├── app ├── Dockerfile ├── src │ ├── test │ │ ├── resources │ │ │ └── application-scratch.properties │ │ └── java │ │ │ └── com │ │ │ └── favorites │ │ │ ├── util │ │ │ ├── TestString.java │ │ │ ├── html │ │ │ │ ├── HTMLParserExample1.java │ │ │ │ └── HTMLParserExample2.java │ │ │ └── redis │ │ │ │ └── TestRedis.java │ │ │ ├── domain │ │ │ ├── UserRepositoryTests.java │ │ │ ├── RepositoryTest.java │ │ │ ├── CollectRepositoryTest.java │ │ │ └── CollectorRepositoryTest.java │ │ │ ├── controller │ │ │ └── HelloWorldControlerTests.java │ │ │ └── FavoritesApplicationTests.java │ └── main │ │ ├── resources │ │ ├── static │ │ │ ├── img │ │ │ │ ├── icon.ico │ │ │ │ ├── icon.png │ │ │ │ ├── logo.jpg │ │ │ │ ├── logo.png │ │ │ │ ├── camera.png │ │ │ │ ├── dummy.png │ │ │ │ ├── favicon.png │ │ │ │ ├── loading.gif │ │ │ │ ├── useTool.gif │ │ │ │ ├── cloud-error.png │ │ │ │ ├── empty_list.png │ │ │ │ ├── logo-block.png │ │ │ │ ├── logo-single.png │ │ │ │ └── profile-bg.jpg │ │ │ ├── index │ │ │ │ ├── img │ │ │ │ │ ├── profile.png │ │ │ │ │ └── portfolio │ │ │ │ │ │ ├── cabin.png │ │ │ │ │ │ ├── cake.png │ │ │ │ │ │ ├── game.png │ │ │ │ │ │ ├── safe.png │ │ │ │ │ │ ├── circus.png │ │ │ │ │ │ └── submarine.png │ │ │ │ ├── vendor │ │ │ │ │ ├── font-awesome │ │ │ │ │ │ ├── fonts │ │ │ │ │ │ │ ├── FontAwesome.otf │ │ │ │ │ │ │ ├── fontawesome-webfont.eot │ │ │ │ │ │ │ ├── fontawesome-webfont.ttf │ │ │ │ │ │ │ ├── fontawesome-webfont.woff │ │ │ │ │ │ │ └── fontawesome-webfont.woff2 │ │ │ │ │ │ ├── less │ │ │ │ │ │ │ ├── screen-reader.less │ │ │ │ │ │ │ ├── fixed-width.less │ │ │ │ │ │ │ ├── larger.less │ │ │ │ │ │ │ ├── list.less │ │ │ │ │ │ │ ├── core.less │ │ │ │ │ │ │ ├── stacked.less │ │ │ │ │ │ │ ├── font-awesome.less │ │ │ │ │ │ │ ├── bordered-pulled.less │ │ │ │ │ │ │ ├── rotated-flipped.less │ │ │ │ │ │ │ ├── path.less │ │ │ │ │ │ │ ├── animated.less │ │ │ │ │ │ │ └── mixins.less │ │ │ │ │ │ └── scss │ │ │ │ │ │ │ ├── _fixed-width.scss │ │ │ │ │ │ │ ├── _screen-reader.scss │ │ │ │ │ │ │ ├── _larger.scss │ │ │ │ │ │ │ ├── _list.scss │ │ │ │ │ │ │ ├── _core.scss │ │ │ │ │ │ │ ├── font-awesome.scss │ │ │ │ │ │ │ ├── _stacked.scss │ │ │ │ │ │ │ ├── _bordered-pulled.scss │ │ │ │ │ │ │ ├── _rotated-flipped.scss │ │ │ │ │ │ │ ├── _path.scss │ │ │ │ │ │ │ ├── _animated.scss │ │ │ │ │ │ │ └── _mixins.scss │ │ │ │ │ └── bootstrap │ │ │ │ │ │ └── fonts │ │ │ │ │ │ ├── glyphicons-halflings-regular.eot │ │ │ │ │ │ ├── glyphicons-halflings-regular.ttf │ │ │ │ │ │ ├── glyphicons-halflings-regular.woff │ │ │ │ │ │ └── glyphicons-halflings-regular.woff2 │ │ │ │ └── js │ │ │ │ │ ├── freelancer.min.js │ │ │ │ │ ├── freelancer.js │ │ │ │ │ └── contact_me.js │ │ │ ├── vendor │ │ │ │ ├── fontawesome │ │ │ │ │ └── fonts │ │ │ │ │ │ ├── FontAwesome.otf │ │ │ │ │ │ ├── fontawesome-webfont.eot │ │ │ │ │ │ ├── fontawesome-webfont.ttf │ │ │ │ │ │ ├── fontawesome-webfont.woff │ │ │ │ │ │ └── fontawesome-webfont.woff2 │ │ │ │ ├── simple-line-icons │ │ │ │ │ └── fonts │ │ │ │ │ │ ├── Simple-Line-Icons.eot │ │ │ │ │ │ ├── Simple-Line-Icons.ttf │ │ │ │ │ │ ├── Simple-Line-Icons.woff │ │ │ │ │ │ └── Simple-Line-Icons.woff2 │ │ │ │ └── scrollable │ │ │ │ │ ├── scrollable.min.css │ │ │ │ │ └── scrollable.css │ │ │ └── css │ │ │ │ └── index.css │ │ ├── templates │ │ │ ├── home.html │ │ │ ├── mobile.html │ │ │ ├── fragments │ │ │ │ ├── footer.html │ │ │ │ └── sidebar.html │ │ │ ├── tool.html │ │ │ ├── error.html │ │ │ ├── favorites │ │ │ │ ├── newfavorites.html │ │ │ │ ├── export.html │ │ │ │ └── import.html │ │ │ ├── lookAround.html │ │ │ └── layout.html │ │ ├── application.properties │ │ ├── application-dev.properties │ │ └── application-docker.properties │ │ └── java │ │ └── com │ │ └── favorites │ │ ├── domain │ │ ├── enums │ │ │ ├── IsDelete.java │ │ │ ├── CollectType.java │ │ │ ├── FollowStatus.java │ │ │ └── LetterType.java │ │ ├── Entitys.java │ │ ├── view │ │ │ ├── CommentView.java │ │ │ ├── LetterView.java │ │ │ ├── CollectView.java │ │ │ ├── CollectorView.java │ │ │ ├── IndexCollectorView.java │ │ │ └── LetterSummary.java │ │ ├── result │ │ │ ├── Response.java │ │ │ ├── ResponseData.java │ │ │ └── ExceptionMsg.java │ │ ├── Praise.java │ │ ├── UrlLibrary.java │ │ ├── UserIsFollow.java │ │ ├── LookRecord.java │ │ ├── Notice.java │ │ ├── Follow.java │ │ ├── Favorites.java │ │ ├── Feedback.java │ │ ├── Letter.java │ │ ├── Comment.java │ │ ├── Config.java │ │ └── User.java │ │ ├── service │ │ ├── FeedbackService.java │ │ ├── ConfigService.java │ │ ├── CollectorService.java │ │ ├── FavoritesService.java │ │ ├── NoticeService.java │ │ ├── LetterService.java │ │ ├── UserService.java │ │ ├── RedisService.java │ │ ├── LookRecordService.java │ │ ├── LookAroundService.java │ │ ├── impl │ │ │ ├── FeedbackServiceImpl.java │ │ │ ├── RedisServiceImpl.java │ │ │ ├── ConfigServiceImpl.java │ │ │ ├── FavoritesServiceImpl.java │ │ │ ├── CollectorServiceImpl.java │ │ │ └── LetterServiceImpl.java │ │ └── CollectService.java │ │ ├── repository │ │ ├── FeedbackRepository.java │ │ ├── CollectorRepository.java │ │ ├── PraiseRepository.java │ │ ├── UrlLibraryRepository.java │ │ ├── CommentRepository.java │ │ ├── LetterRepository.java │ │ ├── ConfigRepository.java │ │ ├── FavoritesRepository.java │ │ ├── NoticeRepository.java │ │ ├── BaseNativeSqlRepository.java │ │ ├── FollowRepository.java │ │ ├── LookRecordRepository.java │ │ └── UserRepository.java │ │ ├── utils │ │ ├── MessageUtil.java │ │ ├── MD5Util.java │ │ ├── StringUtil.java │ │ ├── FileUtil.java │ │ ├── URLUtil.java │ │ └── DateUtils.java │ │ ├── comm │ │ ├── config │ │ │ ├── SessionConfig.java │ │ │ └── RedisConfig.java │ │ ├── aop │ │ │ ├── LoggerManage.java │ │ │ └── LoggerAdvice.java │ │ ├── Const.java │ │ └── exception │ │ │ └── GlobalExceptionHandler.java │ │ ├── FavoritesApplication.java │ │ ├── WebConfiguration.java │ │ ├── web │ │ ├── FeedbackController.java │ │ ├── WebJarController.java │ │ ├── LookRecordController.java │ │ ├── FollowController.java │ │ ├── LetterController.java │ │ ├── BaseController.java │ │ └── NoticeController.java │ │ ├── cache │ │ └── CacheService.java │ │ └── schedule │ │ └── ScheduledTasks.java ├── build.gradle └── pom.xml ├── mysql ├── Dockerfile └── my.cnf ├── .gitignore ├── nginx └── conf.d │ └── app.conf ├── docker-compose.yml └── README.md /app/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM maven:3.5-jdk-8 -------------------------------------------------------------------------------- /mysql/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM mysql/mysql-server:5.7 2 | COPY my.cnf /etc/my.cnf 3 | -------------------------------------------------------------------------------- /app/src/test/resources/application-scratch.properties: -------------------------------------------------------------------------------- 1 | spring.datasource.name=scratchdb 2 | spring.jmx.default-domain=jpa.sample -------------------------------------------------------------------------------- /app/src/main/resources/static/img/icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloudfavorites/favorites-web/HEAD/app/src/main/resources/static/img/icon.ico -------------------------------------------------------------------------------- /app/src/main/resources/static/img/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloudfavorites/favorites-web/HEAD/app/src/main/resources/static/img/icon.png -------------------------------------------------------------------------------- /app/src/main/resources/static/img/logo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloudfavorites/favorites-web/HEAD/app/src/main/resources/static/img/logo.jpg -------------------------------------------------------------------------------- /app/src/main/resources/static/img/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloudfavorites/favorites-web/HEAD/app/src/main/resources/static/img/logo.png -------------------------------------------------------------------------------- /app/src/main/resources/static/img/camera.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloudfavorites/favorites-web/HEAD/app/src/main/resources/static/img/camera.png -------------------------------------------------------------------------------- /app/src/main/resources/static/img/dummy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloudfavorites/favorites-web/HEAD/app/src/main/resources/static/img/dummy.png -------------------------------------------------------------------------------- /app/src/main/java/com/favorites/domain/enums/IsDelete.java: -------------------------------------------------------------------------------- 1 | package com.favorites.domain.enums; 2 | 3 | public enum IsDelete { 4 | 5 | YES, NO 6 | } 7 | -------------------------------------------------------------------------------- /app/src/main/resources/static/img/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloudfavorites/favorites-web/HEAD/app/src/main/resources/static/img/favicon.png -------------------------------------------------------------------------------- /app/src/main/resources/static/img/loading.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloudfavorites/favorites-web/HEAD/app/src/main/resources/static/img/loading.gif -------------------------------------------------------------------------------- /app/src/main/resources/static/img/useTool.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloudfavorites/favorites-web/HEAD/app/src/main/resources/static/img/useTool.gif -------------------------------------------------------------------------------- /app/src/main/resources/static/img/cloud-error.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloudfavorites/favorites-web/HEAD/app/src/main/resources/static/img/cloud-error.png -------------------------------------------------------------------------------- /app/src/main/resources/static/img/empty_list.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloudfavorites/favorites-web/HEAD/app/src/main/resources/static/img/empty_list.png -------------------------------------------------------------------------------- /app/src/main/resources/static/img/logo-block.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloudfavorites/favorites-web/HEAD/app/src/main/resources/static/img/logo-block.png -------------------------------------------------------------------------------- /app/src/main/resources/static/img/logo-single.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloudfavorites/favorites-web/HEAD/app/src/main/resources/static/img/logo-single.png -------------------------------------------------------------------------------- /app/src/main/resources/static/img/profile-bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloudfavorites/favorites-web/HEAD/app/src/main/resources/static/img/profile-bg.jpg -------------------------------------------------------------------------------- /app/src/main/java/com/favorites/domain/enums/CollectType.java: -------------------------------------------------------------------------------- 1 | package com.favorites.domain.enums; 2 | 3 | public enum CollectType { 4 | 5 | PUBLIC, PRIVATE 6 | } 7 | -------------------------------------------------------------------------------- /app/src/main/resources/static/index/img/profile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloudfavorites/favorites-web/HEAD/app/src/main/resources/static/index/img/profile.png -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | /bin 3 | /build 4 | /.settings 5 | /.classpath 6 | /.project 7 | /.gradle 8 | *.log 9 | *.iml 10 | *.class 11 | .checkstyle 12 | /.idea 13 | -------------------------------------------------------------------------------- /app/src/main/java/com/favorites/domain/enums/FollowStatus.java: -------------------------------------------------------------------------------- 1 | package com.favorites.domain.enums; 2 | 3 | public enum FollowStatus { 4 | 5 | FOLLOW, UNFOLLOW 6 | } 7 | -------------------------------------------------------------------------------- /app/src/main/resources/static/index/img/portfolio/cabin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloudfavorites/favorites-web/HEAD/app/src/main/resources/static/index/img/portfolio/cabin.png -------------------------------------------------------------------------------- /app/src/main/resources/static/index/img/portfolio/cake.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloudfavorites/favorites-web/HEAD/app/src/main/resources/static/index/img/portfolio/cake.png -------------------------------------------------------------------------------- /app/src/main/resources/static/index/img/portfolio/game.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloudfavorites/favorites-web/HEAD/app/src/main/resources/static/index/img/portfolio/game.png -------------------------------------------------------------------------------- /app/src/main/resources/static/index/img/portfolio/safe.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloudfavorites/favorites-web/HEAD/app/src/main/resources/static/index/img/portfolio/safe.png -------------------------------------------------------------------------------- /app/src/main/resources/static/index/img/portfolio/circus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloudfavorites/favorites-web/HEAD/app/src/main/resources/static/index/img/portfolio/circus.png -------------------------------------------------------------------------------- /app/src/main/resources/static/index/img/portfolio/submarine.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloudfavorites/favorites-web/HEAD/app/src/main/resources/static/index/img/portfolio/submarine.png -------------------------------------------------------------------------------- /app/src/main/resources/static/vendor/fontawesome/fonts/FontAwesome.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloudfavorites/favorites-web/HEAD/app/src/main/resources/static/vendor/fontawesome/fonts/FontAwesome.otf -------------------------------------------------------------------------------- /app/src/main/resources/static/index/vendor/font-awesome/fonts/FontAwesome.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloudfavorites/favorites-web/HEAD/app/src/main/resources/static/index/vendor/font-awesome/fonts/FontAwesome.otf -------------------------------------------------------------------------------- /app/src/main/resources/static/index/vendor/font-awesome/less/screen-reader.less: -------------------------------------------------------------------------------- 1 | // Screen Readers 2 | // ------------------------- 3 | 4 | .sr-only { .sr-only(); } 5 | .sr-only-focusable { .sr-only-focusable(); } 6 | -------------------------------------------------------------------------------- /app/src/main/resources/static/index/vendor/font-awesome/less/fixed-width.less: -------------------------------------------------------------------------------- 1 | // Fixed Width Icons 2 | // ------------------------- 3 | .@{fa-css-prefix}-fw { 4 | width: (18em / 14); 5 | text-align: center; 6 | } 7 | -------------------------------------------------------------------------------- /app/src/main/resources/static/index/vendor/font-awesome/scss/_fixed-width.scss: -------------------------------------------------------------------------------- 1 | // Fixed Width Icons 2 | // ------------------------- 3 | .#{$fa-css-prefix}-fw { 4 | width: (18em / 14); 5 | text-align: center; 6 | } 7 | -------------------------------------------------------------------------------- /app/src/main/resources/static/vendor/fontawesome/fonts/fontawesome-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloudfavorites/favorites-web/HEAD/app/src/main/resources/static/vendor/fontawesome/fonts/fontawesome-webfont.eot -------------------------------------------------------------------------------- /app/src/main/resources/static/vendor/fontawesome/fonts/fontawesome-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloudfavorites/favorites-web/HEAD/app/src/main/resources/static/vendor/fontawesome/fonts/fontawesome-webfont.ttf -------------------------------------------------------------------------------- /app/src/main/resources/static/vendor/fontawesome/fonts/fontawesome-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloudfavorites/favorites-web/HEAD/app/src/main/resources/static/vendor/fontawesome/fonts/fontawesome-webfont.woff -------------------------------------------------------------------------------- /app/src/main/resources/static/vendor/fontawesome/fonts/fontawesome-webfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloudfavorites/favorites-web/HEAD/app/src/main/resources/static/vendor/fontawesome/fonts/fontawesome-webfont.woff2 -------------------------------------------------------------------------------- /app/src/main/resources/static/vendor/simple-line-icons/fonts/Simple-Line-Icons.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloudfavorites/favorites-web/HEAD/app/src/main/resources/static/vendor/simple-line-icons/fonts/Simple-Line-Icons.eot -------------------------------------------------------------------------------- /app/src/main/resources/static/vendor/simple-line-icons/fonts/Simple-Line-Icons.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloudfavorites/favorites-web/HEAD/app/src/main/resources/static/vendor/simple-line-icons/fonts/Simple-Line-Icons.ttf -------------------------------------------------------------------------------- /app/src/main/resources/static/vendor/simple-line-icons/fonts/Simple-Line-Icons.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloudfavorites/favorites-web/HEAD/app/src/main/resources/static/vendor/simple-line-icons/fonts/Simple-Line-Icons.woff -------------------------------------------------------------------------------- /app/src/main/resources/static/vendor/simple-line-icons/fonts/Simple-Line-Icons.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloudfavorites/favorites-web/HEAD/app/src/main/resources/static/vendor/simple-line-icons/fonts/Simple-Line-Icons.woff2 -------------------------------------------------------------------------------- /app/src/main/java/com/favorites/domain/enums/LetterType.java: -------------------------------------------------------------------------------- 1 | package com.favorites.domain.enums; 2 | 3 | /** 4 | * Created by DingYS on 2017/3/7. 5 | */ 6 | public enum LetterType { 7 | 8 | ORIGINAL,REPLY 9 | 10 | } 11 | -------------------------------------------------------------------------------- /app/src/main/resources/static/index/vendor/font-awesome/fonts/fontawesome-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloudfavorites/favorites-web/HEAD/app/src/main/resources/static/index/vendor/font-awesome/fonts/fontawesome-webfont.eot -------------------------------------------------------------------------------- /app/src/main/resources/static/index/vendor/font-awesome/fonts/fontawesome-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloudfavorites/favorites-web/HEAD/app/src/main/resources/static/index/vendor/font-awesome/fonts/fontawesome-webfont.ttf -------------------------------------------------------------------------------- /app/src/main/resources/static/index/vendor/font-awesome/fonts/fontawesome-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloudfavorites/favorites-web/HEAD/app/src/main/resources/static/index/vendor/font-awesome/fonts/fontawesome-webfont.woff -------------------------------------------------------------------------------- /app/src/main/resources/static/index/vendor/font-awesome/fonts/fontawesome-webfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloudfavorites/favorites-web/HEAD/app/src/main/resources/static/index/vendor/font-awesome/fonts/fontawesome-webfont.woff2 -------------------------------------------------------------------------------- /app/src/main/resources/static/index/vendor/font-awesome/scss/_screen-reader.scss: -------------------------------------------------------------------------------- 1 | // Screen Readers 2 | // ------------------------- 3 | 4 | .sr-only { @include sr-only(); } 5 | .sr-only-focusable { @include sr-only-focusable(); } 6 | -------------------------------------------------------------------------------- /app/src/main/resources/static/index/vendor/bootstrap/fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloudfavorites/favorites-web/HEAD/app/src/main/resources/static/index/vendor/bootstrap/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /app/src/main/resources/static/index/vendor/bootstrap/fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloudfavorites/favorites-web/HEAD/app/src/main/resources/static/index/vendor/bootstrap/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /app/src/main/resources/static/index/vendor/bootstrap/fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloudfavorites/favorites-web/HEAD/app/src/main/resources/static/index/vendor/bootstrap/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /app/src/main/resources/static/index/vendor/bootstrap/fonts/glyphicons-halflings-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloudfavorites/favorites-web/HEAD/app/src/main/resources/static/index/vendor/bootstrap/fonts/glyphicons-halflings-regular.woff2 -------------------------------------------------------------------------------- /app/src/main/java/com/favorites/service/FeedbackService.java: -------------------------------------------------------------------------------- 1 | package com.favorites.service; 2 | 3 | import com.favorites.domain.Feedback; 4 | 5 | /** 6 | * Created by chenzhimin on 2017/2/23. 7 | */ 8 | public interface FeedbackService { 9 | 10 | public void saveFeeddback(Feedback feedback,Long userId); 11 | } 12 | -------------------------------------------------------------------------------- /app/src/main/java/com/favorites/service/ConfigService.java: -------------------------------------------------------------------------------- 1 | package com.favorites.service; 2 | 3 | import com.favorites.domain.Config; 4 | 5 | public interface ConfigService { 6 | 7 | public Config saveConfig(Long userId,String favoritesId); 8 | 9 | public void updateConfig(long id ,String type,String defaultFavorites); 10 | } 11 | -------------------------------------------------------------------------------- /app/src/main/resources/templates/home.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
5 |
6 | 7 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/java/com/favorites/repository/FeedbackRepository.java: -------------------------------------------------------------------------------- 1 | package com.favorites.repository; 2 | 3 | import com.favorites.domain.Feedback; 4 | import org.springframework.data.jpa.repository.JpaRepository; 5 | 6 | /** 7 | * Created by chenzhimin on 2017/2/23. 8 | */ 9 | public interface FeedbackRepository extends JpaRepository { 10 | } 11 | -------------------------------------------------------------------------------- /app/src/main/java/com/favorites/utils/MessageUtil.java: -------------------------------------------------------------------------------- 1 | package com.favorites.utils; 2 | 3 | public class MessageUtil { 4 | 5 | public static String getMessage(String template, String... keys) { 6 | int count = 0; 7 | for (String key : keys) { 8 | template = template.replace("{" + count++ + "}", key); 9 | } 10 | return template; 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /app/src/main/java/com/favorites/service/CollectorService.java: -------------------------------------------------------------------------------- 1 | package com.favorites.service; 2 | 3 | import com.favorites.domain.view.IndexCollectorView; 4 | 5 | /** 6 | * @Description: 获取收藏家 7 | * @Auth: yuyang 8 | * @Date: 2017/1/19 14:14 9 | * @Version: 1.0 10 | **/ 11 | public interface CollectorService { 12 | 13 | IndexCollectorView getCollectors(); 14 | 15 | } 16 | -------------------------------------------------------------------------------- /app/src/main/java/com/favorites/service/FavoritesService.java: -------------------------------------------------------------------------------- 1 | package com.favorites.service; 2 | 3 | import com.favorites.domain.Collect; 4 | import com.favorites.domain.Favorites; 5 | 6 | public interface FavoritesService { 7 | public Favorites saveFavorites(Long userId,String name); 8 | public Favorites saveFavorites(Collect collect); 9 | public void countFavorites(long id); 10 | 11 | } 12 | -------------------------------------------------------------------------------- /app/src/main/resources/templates/mobile.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
5 |
6 |

移动客户端

7 |
8 |
9 | 10 | 12 | 13 | -------------------------------------------------------------------------------- /app/src/main/java/com/favorites/domain/Entitys.java: -------------------------------------------------------------------------------- 1 | package com.favorites.domain; 2 | 3 | import java.io.Serializable; 4 | 5 | import org.apache.commons.lang3.builder.ToStringBuilder; 6 | 7 | public class Entitys implements Serializable{ 8 | private static final long serialVersionUID = 1L; 9 | 10 | @Override 11 | public String toString() { 12 | return ToStringBuilder.reflectionToString(this); 13 | } 14 | 15 | } 16 | 17 | -------------------------------------------------------------------------------- /app/src/main/java/com/favorites/domain/view/CommentView.java: -------------------------------------------------------------------------------- 1 | package com.favorites.domain.view; 2 | /** 3 | *@InterfaceName: CommentView 4 | *@Description: 5 | *@author YY 6 | *@date 2016年9月1日 下午4:03:20 7 | *@version 1.0 8 | */ 9 | public interface CommentView { 10 | Long getUserId(); 11 | String getUserName(); 12 | String getProfilePicture(); 13 | String getContent(); 14 | Long getCreateTime(); 15 | Long getReplyUserId(); 16 | } 17 | -------------------------------------------------------------------------------- /app/src/main/java/com/favorites/comm/config/SessionConfig.java: -------------------------------------------------------------------------------- 1 | /* 2 | package com.favorites.comm.config; 3 | 4 | import org.springframework.context.annotation.Configuration; 5 | import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession; 6 | 7 | @Configuration 8 | @EnableRedisHttpSession(maxInactiveIntervalInSeconds = 86400*30) 9 | //@EnableRedisHttpSession(maxInactiveIntervalInSeconds = 1800) 10 | public class SessionConfig { 11 | 12 | }*/ 13 | -------------------------------------------------------------------------------- /app/src/main/java/com/favorites/domain/view/LetterView.java: -------------------------------------------------------------------------------- 1 | package com.favorites.domain.view; 2 | 3 | import com.favorites.domain.enums.LetterType; 4 | 5 | /** 6 | * Created by DingYS on 2017/3/8. 7 | */ 8 | public interface LetterView { 9 | Long getId(); 10 | Long getSendUserId(); 11 | String getSendUserName(); 12 | String getProfilePicture(); 13 | String getContent(); 14 | Long getCreateTime(); 15 | Long getPid(); 16 | String getType(); 17 | } 18 | -------------------------------------------------------------------------------- /app/src/main/java/com/favorites/service/NoticeService.java: -------------------------------------------------------------------------------- 1 | package com.favorites.service; 2 | 3 | import java.util.List; 4 | 5 | import org.springframework.data.domain.Pageable; 6 | 7 | import com.favorites.domain.view.CollectSummary; 8 | 9 | public interface NoticeService { 10 | 11 | public void saveNotice(String collectId,String type,Long userId,String operId); 12 | 13 | public List getNoticeCollects(String type, Long userId, Pageable pageable); 14 | 15 | } 16 | -------------------------------------------------------------------------------- /app/src/main/resources/static/index/vendor/font-awesome/less/larger.less: -------------------------------------------------------------------------------- 1 | // Icon Sizes 2 | // ------------------------- 3 | 4 | /* makes the font 33% larger relative to the icon container */ 5 | .@{fa-css-prefix}-lg { 6 | font-size: (4em / 3); 7 | line-height: (3em / 4); 8 | vertical-align: -15%; 9 | } 10 | .@{fa-css-prefix}-2x { font-size: 2em; } 11 | .@{fa-css-prefix}-3x { font-size: 3em; } 12 | .@{fa-css-prefix}-4x { font-size: 4em; } 13 | .@{fa-css-prefix}-5x { font-size: 5em; } 14 | -------------------------------------------------------------------------------- /app/src/main/resources/static/index/vendor/font-awesome/scss/_larger.scss: -------------------------------------------------------------------------------- 1 | // Icon Sizes 2 | // ------------------------- 3 | 4 | /* makes the font 33% larger relative to the icon container */ 5 | .#{$fa-css-prefix}-lg { 6 | font-size: (4em / 3); 7 | line-height: (3em / 4); 8 | vertical-align: -15%; 9 | } 10 | .#{$fa-css-prefix}-2x { font-size: 2em; } 11 | .#{$fa-css-prefix}-3x { font-size: 3em; } 12 | .#{$fa-css-prefix}-4x { font-size: 4em; } 13 | .#{$fa-css-prefix}-5x { font-size: 5em; } 14 | -------------------------------------------------------------------------------- /app/src/main/java/com/favorites/service/LetterService.java: -------------------------------------------------------------------------------- 1 | package com.favorites.service; 2 | 3 | import com.favorites.domain.Letter; 4 | import com.favorites.domain.view.LetterSummary; 5 | import org.springframework.data.domain.Pageable; 6 | 7 | import java.util.List; 8 | 9 | /** 10 | * Created by DingYS on 2017/3/8. 11 | */ 12 | public interface LetterService { 13 | 14 | public void sendLetter(Letter letter); 15 | 16 | public List findLetter(Long userId, Pageable pageable); 17 | } 18 | -------------------------------------------------------------------------------- /app/src/main/resources/static/index/vendor/font-awesome/less/list.less: -------------------------------------------------------------------------------- 1 | // List Icons 2 | // ------------------------- 3 | 4 | .@{fa-css-prefix}-ul { 5 | padding-left: 0; 6 | margin-left: @fa-li-width; 7 | list-style-type: none; 8 | > li { position: relative; } 9 | } 10 | .@{fa-css-prefix}-li { 11 | position: absolute; 12 | left: -@fa-li-width; 13 | width: @fa-li-width; 14 | top: (2em / 14); 15 | text-align: center; 16 | &.@{fa-css-prefix}-lg { 17 | left: (-@fa-li-width + (4em / 14)); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /app/src/main/resources/static/index/vendor/font-awesome/scss/_list.scss: -------------------------------------------------------------------------------- 1 | // List Icons 2 | // ------------------------- 3 | 4 | .#{$fa-css-prefix}-ul { 5 | padding-left: 0; 6 | margin-left: $fa-li-width; 7 | list-style-type: none; 8 | > li { position: relative; } 9 | } 10 | .#{$fa-css-prefix}-li { 11 | position: absolute; 12 | left: -$fa-li-width; 13 | width: $fa-li-width; 14 | top: (2em / 14); 15 | text-align: center; 16 | &.#{$fa-css-prefix}-lg { 17 | left: -$fa-li-width + (4em / 14); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /app/src/main/java/com/favorites/domain/view/CollectView.java: -------------------------------------------------------------------------------- 1 | package com.favorites.domain.view; 2 | 3 | public interface CollectView{ 4 | Long getId(); 5 | Long getUserId(); 6 | String getProfilePicture(); 7 | String getTitle(); 8 | String getType(); 9 | String getUrl(); 10 | String getLogoUrl(); 11 | String getRemark(); 12 | String getDescription(); 13 | Long getLastModifyTime(); 14 | Long getCreateTime(); 15 | String getUserName(); 16 | Long getFavoritesId(); 17 | String getFavoriteName(); 18 | String getOperId(); 19 | } -------------------------------------------------------------------------------- /app/src/main/java/com/favorites/service/UserService.java: -------------------------------------------------------------------------------- 1 | package com.favorites.service; 2 | public interface UserService { 3 | 4 | /** 5 | * 新增一个用户 6 | * @param name 7 | * @param age 8 | */ 9 | void create(String name, Integer age); 10 | 11 | /** 12 | * 根据name删除一个用户高 13 | * @param name 14 | */ 15 | void deleteByName(String name); 16 | 17 | /** 18 | * 获取用户总量 19 | */ 20 | Integer getAllUsers(); 21 | 22 | /** 23 | * 删除所有用户 24 | */ 25 | void deleteAllUsers(); 26 | 27 | } -------------------------------------------------------------------------------- /app/src/main/resources/static/index/vendor/font-awesome/less/core.less: -------------------------------------------------------------------------------- 1 | // Base Class Definition 2 | // ------------------------- 3 | 4 | .@{fa-css-prefix} { 5 | display: inline-block; 6 | font: normal normal normal @fa-font-size-base/@fa-line-height-base FontAwesome; // shortening font declaration 7 | font-size: inherit; // can't have font-size inherit on line above, so need to override 8 | text-rendering: auto; // optimizelegibility throws things off #1094 9 | -webkit-font-smoothing: antialiased; 10 | -moz-osx-font-smoothing: grayscale; 11 | 12 | } 13 | -------------------------------------------------------------------------------- /nginx/conf.d/app.conf: -------------------------------------------------------------------------------- 1 | server { 2 | listen 80; 3 | charset utf-8; 4 | access_log off; 5 | 6 | location / { 7 | proxy_pass http://app:8080; 8 | proxy_set_header Host $host:$server_port; 9 | proxy_set_header X-Forwarded-Host $server_name; 10 | proxy_set_header X-Real-IP $remote_addr; 11 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 12 | } 13 | 14 | location /static { 15 | access_log off; 16 | expires 30d; 17 | 18 | alias /app/static; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /app/src/main/resources/static/index/vendor/font-awesome/scss/_core.scss: -------------------------------------------------------------------------------- 1 | // Base Class Definition 2 | // ------------------------- 3 | 4 | .#{$fa-css-prefix} { 5 | display: inline-block; 6 | font: normal normal normal #{$fa-font-size-base}/#{$fa-line-height-base} FontAwesome; // shortening font declaration 7 | font-size: inherit; // can't have font-size inherit on line above, so need to override 8 | text-rendering: auto; // optimizelegibility throws things off #1094 9 | -webkit-font-smoothing: antialiased; 10 | -moz-osx-font-smoothing: grayscale; 11 | 12 | } 13 | -------------------------------------------------------------------------------- /app/src/main/java/com/favorites/service/RedisService.java: -------------------------------------------------------------------------------- 1 | package com.favorites.service; 2 | 3 | /** 4 | * @Description: 5 | * @Auth: yuyang 6 | * @Date: 2017/2/24 16:10 7 | * @Version: 1.0 8 | **/ 9 | public interface RedisService { 10 | 11 | public void set(String key,String value); 12 | 13 | public String get(String key); 14 | 15 | public void setObject(String key,Object value); 16 | 17 | public Object getObject(String key); 18 | 19 | public boolean expire(String key, long timeout); 20 | 21 | public void delete(String key); 22 | 23 | } 24 | -------------------------------------------------------------------------------- /app/src/main/resources/static/index/vendor/font-awesome/scss/font-awesome.scss: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome 4.6.3 by @davegandy - http://fontawesome.io - @fontawesome 3 | * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) 4 | */ 5 | 6 | @import "variables"; 7 | @import "mixins"; 8 | @import "path"; 9 | @import "core"; 10 | @import "larger"; 11 | @import "fixed-width"; 12 | @import "list"; 13 | @import "bordered-pulled"; 14 | @import "animated"; 15 | @import "rotated-flipped"; 16 | @import "stacked"; 17 | @import "icons"; 18 | @import "screen-reader"; 19 | -------------------------------------------------------------------------------- /app/src/main/java/com/favorites/repository/CollectorRepository.java: -------------------------------------------------------------------------------- 1 | package com.favorites.repository; 2 | 3 | /** 4 | * @Description: 获取收藏家 5 | * @Auth: yuyang 6 | * @Date: 2017/1/18 19:34 7 | * @Version: 1.0 8 | **/ 9 | public interface CollectorRepository { 10 | 11 | Long getMostCollectUser(); 12 | 13 | Long getMostFollowedUser(Long notUserId); 14 | 15 | Long getMostPraisedUser(String notUserIds); 16 | 17 | Long getMostCommentedUser(String notUserIds); 18 | 19 | Long getMostPopularUser(String notUserIds); 20 | 21 | Long getMostActiveUser(String notUserIds); 22 | 23 | } 24 | -------------------------------------------------------------------------------- /app/src/main/java/com/favorites/comm/aop/LoggerManage.java: -------------------------------------------------------------------------------- 1 | package com.favorites.comm.aop; 2 | 3 | import java.lang.annotation.Documented; 4 | import java.lang.annotation.ElementType; 5 | import java.lang.annotation.Retention; 6 | import java.lang.annotation.RetentionPolicy; 7 | import java.lang.annotation.Target; 8 | 9 | /** 10 | * @Description: 日志注解 11 | * @author Leo Wu 12 | * @date 2016年7月7日 上午11:34:57 13 | * @version 1.0 14 | */ 15 | @Target(ElementType.METHOD) 16 | @Retention(RetentionPolicy.RUNTIME) 17 | @Documented 18 | public @interface LoggerManage { 19 | 20 | public String description(); 21 | } 22 | -------------------------------------------------------------------------------- /app/src/main/resources/static/index/vendor/font-awesome/less/stacked.less: -------------------------------------------------------------------------------- 1 | // Stacked Icons 2 | // ------------------------- 3 | 4 | .@{fa-css-prefix}-stack { 5 | position: relative; 6 | display: inline-block; 7 | width: 2em; 8 | height: 2em; 9 | line-height: 2em; 10 | vertical-align: middle; 11 | } 12 | .@{fa-css-prefix}-stack-1x, .@{fa-css-prefix}-stack-2x { 13 | position: absolute; 14 | left: 0; 15 | width: 100%; 16 | text-align: center; 17 | } 18 | .@{fa-css-prefix}-stack-1x { line-height: inherit; } 19 | .@{fa-css-prefix}-stack-2x { font-size: 2em; } 20 | .@{fa-css-prefix}-inverse { color: @fa-inverse; } 21 | -------------------------------------------------------------------------------- /app/src/main/resources/static/index/vendor/font-awesome/scss/_stacked.scss: -------------------------------------------------------------------------------- 1 | // Stacked Icons 2 | // ------------------------- 3 | 4 | .#{$fa-css-prefix}-stack { 5 | position: relative; 6 | display: inline-block; 7 | width: 2em; 8 | height: 2em; 9 | line-height: 2em; 10 | vertical-align: middle; 11 | } 12 | .#{$fa-css-prefix}-stack-1x, .#{$fa-css-prefix}-stack-2x { 13 | position: absolute; 14 | left: 0; 15 | width: 100%; 16 | text-align: center; 17 | } 18 | .#{$fa-css-prefix}-stack-1x { line-height: inherit; } 19 | .#{$fa-css-prefix}-stack-2x { font-size: 2em; } 20 | .#{$fa-css-prefix}-inverse { color: $fa-inverse; } 21 | -------------------------------------------------------------------------------- /app/src/test/java/com/favorites/util/TestString.java: -------------------------------------------------------------------------------- 1 | package com.favorites.util; 2 | 3 | import com.favorites.domain.Praise; 4 | import org.junit.Test; 5 | 6 | public class TestString { 7 | 8 | @Test 9 | public void testRealUrl() throws Exception { 10 | //collect.setUrl(collect.getUrl().substring(0,collect.getUrl().indexOf("?"))); 11 | String url="http://jartto.wang/2018/03/29/audition-of-f2e/?hmsr=toutiao.io&utm_medium=toutiao.io&utm_source=toutiao.io"; 12 | if(url.contains("?")){ 13 | url=url.substring(0,url.indexOf("?")); 14 | } 15 | System.out.println(url); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /app/src/main/resources/static/index/vendor/font-awesome/less/font-awesome.less: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome 4.6.3 by @davegandy - http://fontawesome.io - @fontawesome 3 | * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) 4 | */ 5 | 6 | @import "variables.less"; 7 | @import "mixins.less"; 8 | @import "path.less"; 9 | @import "core.less"; 10 | @import "larger.less"; 11 | @import "fixed-width.less"; 12 | @import "list.less"; 13 | @import "bordered-pulled.less"; 14 | @import "animated.less"; 15 | @import "rotated-flipped.less"; 16 | @import "stacked.less"; 17 | @import "icons.less"; 18 | @import "screen-reader.less"; 19 | -------------------------------------------------------------------------------- /app/src/main/java/com/favorites/service/LookRecordService.java: -------------------------------------------------------------------------------- 1 | package com.favorites.service; 2 | 3 | import com.favorites.domain.view.CollectSummary; 4 | import org.springframework.data.domain.Pageable; 5 | 6 | import java.util.List; 7 | 8 | /** 9 | * 浏览记录service接口 10 | * Created by chenzhimin on 2017/1/12. 11 | */ 12 | public interface LookRecordService { 13 | 14 | public void saveLookRecord(Long userId, Long collectId); 15 | 16 | public void deleteLookRecord(Long userId, Long collectId); 17 | 18 | public void deleteLookRecordByUserID(Long userId); 19 | 20 | public List getLookRecords(Long userId, Pageable pageable); 21 | 22 | } 23 | -------------------------------------------------------------------------------- /app/src/main/java/com/favorites/utils/MD5Util.java: -------------------------------------------------------------------------------- 1 | package com.favorites.utils; 2 | 3 | import java.security.MessageDigest; 4 | 5 | 6 | public class MD5Util { 7 | 8 | public static String encrypt(String dataStr) { 9 | try { 10 | MessageDigest m = MessageDigest.getInstance("MD5"); 11 | m.update(dataStr.getBytes("UTF8")); 12 | byte s[] = m.digest(); 13 | String result = ""; 14 | for (int i = 0; i < s.length; i++) { 15 | result += Integer.toHexString((0x000000FF & s[i]) | 0xFFFFFF00) 16 | .substring(6); 17 | } 18 | return result; 19 | } catch (Exception e) { 20 | e.printStackTrace(); 21 | } 22 | 23 | return ""; 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /app/src/main/java/com/favorites/utils/StringUtil.java: -------------------------------------------------------------------------------- 1 | package com.favorites.utils; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | import java.util.regex.Matcher; 6 | import java.util.regex.Pattern; 7 | 8 | import org.apache.commons.lang3.StringUtils; 9 | 10 | public class StringUtil { 11 | 12 | public static List getAtUser(String str){ 13 | Pattern p = Pattern.compile("(?<=@).*?(?= )"); 14 | Matcher m = p.matcher(str); 15 | List result=new ArrayList(); 16 | while(m.find()){ 17 | if(StringUtils.isNoneBlank(m.group().trim())){ 18 | result.add(m.group().trim()); 19 | } 20 | } 21 | return result; 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /app/src/main/resources/templates/fragments/footer.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
5 | © 2016 - 2022 6 | 7 | 云收藏 | 让收藏更简单 8 | 9 |
10 |
11 | 12 |
13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /app/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | ###### data config start ###### 2 | spring.jpa.properties.hibernate.hbm2ddl.auto=update 3 | spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect 4 | spring.jpa.show-sql= false 5 | spring.datasource.hikari.connectionInitSql=SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci; 6 | 7 | ###### data config end ###### 8 | 9 | static.url = /usr/local/static 10 | file.profilepictures.url = file/profilepictures/ 11 | file.backgroundpictures.url = file/backgroundpictures/ 12 | 13 | spring.profiles.active=dev 14 | 15 | spring.servlet.multipart.enabled=true 16 | spring.servlet.multipart.max-file-size: 1000000 17 | spring.servlet.multipart.max-request-size: 1000000 18 | 19 | -------------------------------------------------------------------------------- /app/src/main/resources/static/index/vendor/font-awesome/less/bordered-pulled.less: -------------------------------------------------------------------------------- 1 | // Bordered & Pulled 2 | // ------------------------- 3 | 4 | .@{fa-css-prefix}-border { 5 | padding: .2em .25em .15em; 6 | border: solid .08em @fa-border-color; 7 | border-radius: .1em; 8 | } 9 | 10 | .@{fa-css-prefix}-pull-left { float: left; } 11 | .@{fa-css-prefix}-pull-right { float: right; } 12 | 13 | .@{fa-css-prefix} { 14 | &.@{fa-css-prefix}-pull-left { margin-right: .3em; } 15 | &.@{fa-css-prefix}-pull-right { margin-left: .3em; } 16 | } 17 | 18 | /* Deprecated as of 4.4.0 */ 19 | .pull-right { float: right; } 20 | .pull-left { float: left; } 21 | 22 | .@{fa-css-prefix} { 23 | &.pull-left { margin-right: .3em; } 24 | &.pull-right { margin-left: .3em; } 25 | } 26 | -------------------------------------------------------------------------------- /app/src/main/resources/static/index/vendor/font-awesome/scss/_bordered-pulled.scss: -------------------------------------------------------------------------------- 1 | // Bordered & Pulled 2 | // ------------------------- 3 | 4 | .#{$fa-css-prefix}-border { 5 | padding: .2em .25em .15em; 6 | border: solid .08em $fa-border-color; 7 | border-radius: .1em; 8 | } 9 | 10 | .#{$fa-css-prefix}-pull-left { float: left; } 11 | .#{$fa-css-prefix}-pull-right { float: right; } 12 | 13 | .#{$fa-css-prefix} { 14 | &.#{$fa-css-prefix}-pull-left { margin-right: .3em; } 15 | &.#{$fa-css-prefix}-pull-right { margin-left: .3em; } 16 | } 17 | 18 | /* Deprecated as of 4.4.0 */ 19 | .pull-right { float: right; } 20 | .pull-left { float: left; } 21 | 22 | .#{$fa-css-prefix} { 23 | &.pull-left { margin-right: .3em; } 24 | &.pull-right { margin-left: .3em; } 25 | } 26 | -------------------------------------------------------------------------------- /app/src/main/resources/static/index/vendor/font-awesome/less/rotated-flipped.less: -------------------------------------------------------------------------------- 1 | // Rotated & Flipped Icons 2 | // ------------------------- 3 | 4 | .@{fa-css-prefix}-rotate-90 { .fa-icon-rotate(90deg, 1); } 5 | .@{fa-css-prefix}-rotate-180 { .fa-icon-rotate(180deg, 2); } 6 | .@{fa-css-prefix}-rotate-270 { .fa-icon-rotate(270deg, 3); } 7 | 8 | .@{fa-css-prefix}-flip-horizontal { .fa-icon-flip(-1, 1, 0); } 9 | .@{fa-css-prefix}-flip-vertical { .fa-icon-flip(1, -1, 2); } 10 | 11 | // Hook for IE8-9 12 | // ------------------------- 13 | 14 | :root .@{fa-css-prefix}-rotate-90, 15 | :root .@{fa-css-prefix}-rotate-180, 16 | :root .@{fa-css-prefix}-rotate-270, 17 | :root .@{fa-css-prefix}-flip-horizontal, 18 | :root .@{fa-css-prefix}-flip-vertical { 19 | filter: none; 20 | } 21 | -------------------------------------------------------------------------------- /app/src/main/java/com/favorites/FavoritesApplication.java: -------------------------------------------------------------------------------- 1 | package com.favorites; 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.web.servlet.support.SpringBootServletInitializer; 7 | 8 | @SpringBootApplication 9 | public class FavoritesApplication extends SpringBootServletInitializer { 10 | 11 | @Override 12 | protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { 13 | return application.sources(FavoritesApplication.class); 14 | } 15 | 16 | public static void main(String[] args) { 17 | SpringApplication.run(FavoritesApplication.class, args); 18 | } 19 | 20 | } -------------------------------------------------------------------------------- /app/src/main/resources/static/index/vendor/font-awesome/scss/_rotated-flipped.scss: -------------------------------------------------------------------------------- 1 | // Rotated & Flipped Icons 2 | // ------------------------- 3 | 4 | .#{$fa-css-prefix}-rotate-90 { @include fa-icon-rotate(90deg, 1); } 5 | .#{$fa-css-prefix}-rotate-180 { @include fa-icon-rotate(180deg, 2); } 6 | .#{$fa-css-prefix}-rotate-270 { @include fa-icon-rotate(270deg, 3); } 7 | 8 | .#{$fa-css-prefix}-flip-horizontal { @include fa-icon-flip(-1, 1, 0); } 9 | .#{$fa-css-prefix}-flip-vertical { @include fa-icon-flip(1, -1, 2); } 10 | 11 | // Hook for IE8-9 12 | // ------------------------- 13 | 14 | :root .#{$fa-css-prefix}-rotate-90, 15 | :root .#{$fa-css-prefix}-rotate-180, 16 | :root .#{$fa-css-prefix}-rotate-270, 17 | :root .#{$fa-css-prefix}-flip-horizontal, 18 | :root .#{$fa-css-prefix}-flip-vertical { 19 | filter: none; 20 | } 21 | -------------------------------------------------------------------------------- /app/src/main/resources/static/index/vendor/font-awesome/less/path.less: -------------------------------------------------------------------------------- 1 | /* FONT PATH 2 | * -------------------------- */ 3 | 4 | @font-face { 5 | font-family: 'FontAwesome'; 6 | src: url('@{fa-font-path}/fontawesome-webfont.eot?v=@{fa-version}'); 7 | src: url('@{fa-font-path}/fontawesome-webfont.eot?#iefix&v=@{fa-version}') format('embedded-opentype'), 8 | url('@{fa-font-path}/fontawesome-webfont.woff2?v=@{fa-version}') format('woff2'), 9 | url('@{fa-font-path}/fontawesome-webfont.woff?v=@{fa-version}') format('woff'), 10 | url('@{fa-font-path}/fontawesome-webfont.ttf?v=@{fa-version}') format('truetype'), 11 | url('@{fa-font-path}/fontawesome-webfont.svg?v=@{fa-version}#fontawesomeregular') format('svg'); 12 | // src: url('@{fa-font-path}/FontAwesome.otf') format('opentype'); // used when developing fonts 13 | font-weight: normal; 14 | font-style: normal; 15 | } 16 | -------------------------------------------------------------------------------- /app/src/main/java/com/favorites/WebConfiguration.java: -------------------------------------------------------------------------------- 1 | package com.favorites; 2 | 3 | import org.springframework.boot.web.servlet.FilterRegistrationBean; 4 | import org.springframework.context.annotation.Bean; 5 | import org.springframework.context.annotation.Configuration; 6 | 7 | import com.favorites.comm.filter.SecurityFilter; 8 | 9 | @Configuration 10 | public class WebConfiguration { 11 | 12 | @Bean 13 | public FilterRegistrationBean filterRegistration() { 14 | 15 | FilterRegistrationBean registration = new FilterRegistrationBean(); 16 | registration.setFilter(new SecurityFilter()); 17 | registration.addUrlPatterns("/*"); 18 | registration.addInitParameter("paramName", "paramValue"); 19 | registration.setName("MyFilter"); 20 | registration.setOrder(1); 21 | return registration; 22 | } 23 | 24 | } 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /app/src/main/resources/static/index/vendor/font-awesome/scss/_path.scss: -------------------------------------------------------------------------------- 1 | /* FONT PATH 2 | * -------------------------- */ 3 | 4 | @font-face { 5 | font-family: 'FontAwesome'; 6 | src: url('#{$fa-font-path}/fontawesome-webfont.eot?v=#{$fa-version}'); 7 | src: url('#{$fa-font-path}/fontawesome-webfont.eot?#iefix&v=#{$fa-version}') format('embedded-opentype'), 8 | url('#{$fa-font-path}/fontawesome-webfont.woff2?v=#{$fa-version}') format('woff2'), 9 | url('#{$fa-font-path}/fontawesome-webfont.woff?v=#{$fa-version}') format('woff'), 10 | url('#{$fa-font-path}/fontawesome-webfont.ttf?v=#{$fa-version}') format('truetype'), 11 | url('#{$fa-font-path}/fontawesome-webfont.svg?v=#{$fa-version}#fontawesomeregular') format('svg'); 12 | // src: url('#{$fa-font-path}/FontAwesome.otf') format('opentype'); // used when developing fonts 13 | font-weight: normal; 14 | font-style: normal; 15 | } 16 | -------------------------------------------------------------------------------- /app/src/main/java/com/favorites/service/LookAroundService.java: -------------------------------------------------------------------------------- 1 | package com.favorites.service; 2 | 3 | import com.favorites.domain.UserIsFollow; 4 | import com.favorites.domain.view.CollectSummary; 5 | import org.springframework.data.domain.Pageable; 6 | 7 | import java.util.List; 8 | 9 | /** 10 | * 随便看看Service 11 | * Created by chenzhimin on 2017/1/4. 12 | */ 13 | public interface LookAroundService { 14 | /** 15 | * 随便看看中滚动条随机显示5条收藏 16 | * @return 17 | */ 18 | public List scrollFiveCollect(); 19 | 20 | /** 21 | * 按照用户收藏量倒序查询5个用户 22 | * @param userId 23 | * @return 24 | */ 25 | public List queryFiveUser(Long userId); 26 | 27 | /** 28 | * 随便看看查询收藏列表中(同发现中列表,另加类别过滤) 29 | * @return 30 | */ 31 | public List queryCollectExplore(Pageable pageable,Long userId,String category); 32 | 33 | 34 | } 35 | -------------------------------------------------------------------------------- /app/src/main/resources/static/index/vendor/font-awesome/less/animated.less: -------------------------------------------------------------------------------- 1 | // Animated Icons 2 | // -------------------------- 3 | 4 | .@{fa-css-prefix}-spin { 5 | -webkit-animation: fa-spin 2s infinite linear; 6 | animation: fa-spin 2s infinite linear; 7 | } 8 | 9 | .@{fa-css-prefix}-pulse { 10 | -webkit-animation: fa-spin 1s infinite steps(8); 11 | animation: fa-spin 1s infinite steps(8); 12 | } 13 | 14 | @-webkit-keyframes fa-spin { 15 | 0% { 16 | -webkit-transform: rotate(0deg); 17 | transform: rotate(0deg); 18 | } 19 | 100% { 20 | -webkit-transform: rotate(359deg); 21 | transform: rotate(359deg); 22 | } 23 | } 24 | 25 | @keyframes fa-spin { 26 | 0% { 27 | -webkit-transform: rotate(0deg); 28 | transform: rotate(0deg); 29 | } 30 | 100% { 31 | -webkit-transform: rotate(359deg); 32 | transform: rotate(359deg); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /app/src/main/java/com/favorites/repository/PraiseRepository.java: -------------------------------------------------------------------------------- 1 | package com.favorites.repository; 2 | import org.springframework.data.jpa.repository.JpaRepository; 3 | import org.springframework.data.jpa.repository.Query; 4 | 5 | import com.favorites.domain.Praise; 6 | import com.favorites.domain.view.CommentView; 7 | 8 | import javax.transaction.Transactional; 9 | 10 | public interface PraiseRepository extends JpaRepository { 11 | 12 | 13 | Long countByCollectId(Long collectId); 14 | 15 | Praise findByUserIdAndCollectId(Long userId,Long collectId); 16 | 17 | public String findPraiseUserSql="select u.id as userId,u.userName as userName,u.profilePicture as profilePicture,p.createTime as createTime " 18 | + "from Praise p,User u WHERE p.userId=u.id"; 19 | 20 | @Query(findPraiseUserSql+ " and p.id=?1") 21 | CommentView findPraiseUser(Long id); 22 | 23 | @Transactional 24 | void deleteById(Long id); 25 | } -------------------------------------------------------------------------------- /app/src/main/resources/static/index/vendor/font-awesome/scss/_animated.scss: -------------------------------------------------------------------------------- 1 | // Spinning Icons 2 | // -------------------------- 3 | 4 | .#{$fa-css-prefix}-spin { 5 | -webkit-animation: fa-spin 2s infinite linear; 6 | animation: fa-spin 2s infinite linear; 7 | } 8 | 9 | .#{$fa-css-prefix}-pulse { 10 | -webkit-animation: fa-spin 1s infinite steps(8); 11 | animation: fa-spin 1s infinite steps(8); 12 | } 13 | 14 | @-webkit-keyframes fa-spin { 15 | 0% { 16 | -webkit-transform: rotate(0deg); 17 | transform: rotate(0deg); 18 | } 19 | 100% { 20 | -webkit-transform: rotate(359deg); 21 | transform: rotate(359deg); 22 | } 23 | } 24 | 25 | @keyframes fa-spin { 26 | 0% { 27 | -webkit-transform: rotate(0deg); 28 | transform: rotate(0deg); 29 | } 30 | 100% { 31 | -webkit-transform: rotate(359deg); 32 | transform: rotate(359deg); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | services: 3 | nginx: 4 | container_name: favorites-nginx 5 | image: nginx:1.13 6 | restart: always 7 | ports: 8 | - 80:80 9 | - 443:443 10 | volumes: 11 | - ./nginx/conf.d:/etc/nginx/conf.d 12 | - /tmp/logs:/var/log/nginx 13 | 14 | 15 | mysql: 16 | build: ./mysql 17 | environment: 18 | MYSQL_DATABASE: favorites 19 | MYSQL_ROOT_PASSWORD: root 20 | MYSQL_ROOT_HOST: '%' 21 | TZ: Asia/Shanghai 22 | ports: 23 | - "3306:3306" 24 | volumes: 25 | - ./mysql_data:/var/lib/mysql 26 | restart: always 27 | 28 | app: 29 | restart: always 30 | build: ./app 31 | working_dir: /app 32 | volumes: 33 | - ./app:/app 34 | - ~/.m2:/root/.m2 35 | - /tmp/logs:/usr/local/logs 36 | expose: 37 | - "8080" 38 | command: mvn clean spring-boot:run -Drun.profiles=docker 39 | depends_on: 40 | - nginx 41 | - mysql -------------------------------------------------------------------------------- /app/src/main/java/com/favorites/repository/UrlLibraryRepository.java: -------------------------------------------------------------------------------- 1 | package com.favorites.repository; 2 | 3 | import com.favorites.domain.UrlLibrary; 4 | import org.springframework.data.jpa.repository.JpaRepository; 5 | import org.springframework.data.jpa.repository.Modifying; 6 | import org.springframework.data.jpa.repository.Query; 7 | import org.springframework.data.repository.query.Param; 8 | 9 | import javax.transaction.Transactional; 10 | import java.util.List; 11 | 12 | public interface UrlLibraryRepository extends JpaRepository { 13 | 14 | List findByCountLessThanAndLogoUrl(int count,String str); 15 | 16 | @Transactional 17 | @Modifying 18 | @Query("update UrlLibrary u set u.count=u.count+1 where u.id =:id ") 19 | int increaseCountById(@Param("id") Long id); 20 | 21 | @Transactional 22 | @Modifying 23 | @Query("update UrlLibrary u set u.logoUrl = ?2 where u.id = ?1") 24 | int updateLogoUrlById(Long id,String logoUrl); 25 | 26 | } -------------------------------------------------------------------------------- /app/src/test/java/com/favorites/util/html/HTMLParserExample1.java: -------------------------------------------------------------------------------- 1 | package com.favorites.util.html; 2 | 3 | import java.io.IOException; 4 | 5 | import org.jsoup.Jsoup; 6 | import org.jsoup.nodes.Document; 7 | import org.jsoup.nodes.Element; 8 | import org.jsoup.select.Elements; 9 | 10 | public class HTMLParserExample1 { 11 | 12 | public static void main(String[] args) { 13 | 14 | Document doc; 15 | try { 16 | 17 | // need http protocol 18 | doc = Jsoup.connect("http://www.imzhongxin.com").get(); 19 | 20 | // get page title 21 | String title = doc.title(); 22 | System.out.println("title : " + title); 23 | 24 | // get all links 25 | Elements links = doc.select("a[href]"); 26 | for (Element link : links) { 27 | 28 | // get the value from href attribute 29 | System.out.println("\nlink : " + link.attr("href")); 30 | System.out.println("text : " + link.text()); 31 | 32 | } 33 | 34 | } catch (IOException e) { 35 | e.printStackTrace(); 36 | } 37 | 38 | } 39 | 40 | } -------------------------------------------------------------------------------- /app/src/main/java/com/favorites/service/impl/FeedbackServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.favorites.service.impl; 2 | 3 | import com.favorites.domain.Feedback; 4 | import com.favorites.repository.FeedbackRepository; 5 | import com.favorites.service.FeedbackService; 6 | import com.favorites.utils.DateUtils; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.stereotype.Service; 9 | 10 | /** 11 | * Created by chenzhimin on 2017/2/23. 12 | */ 13 | @Service("feedbackService") 14 | public class FeedbackServiceImpl implements FeedbackService { 15 | 16 | @Autowired 17 | private FeedbackRepository feedbackRepository; 18 | 19 | @Override 20 | public void saveFeeddback(Feedback feedback,Long userId) { 21 | feedback.setUserId(userId == null || userId == 0L ? null : userId); 22 | feedback.setCreateTime(DateUtils.getCurrentTime()); 23 | feedback.setLastModifyTime(DateUtils.getCurrentTime()); 24 | feedbackRepository.save(feedback); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/src/main/resources/templates/tool.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
5 |
6 |

网页收集工具

7 |
8 |
1、使用浏览器扩展收藏网页
9 | 支持:Chrome/360极速/QQ/UC/百度浏览器 10 | 下载 11 |
12 |
13 |
2、网页收集小工具
14 | 云收藏 15 | (将该按钮拖动至浏览器书签栏,如下图) 16 |
17 |
18 |
19 | 20 |
21 |
22 | 23 | 24 | -------------------------------------------------------------------------------- /app/src/main/java/com/favorites/repository/CommentRepository.java: -------------------------------------------------------------------------------- 1 | package com.favorites.repository; 2 | import java.util.List; 3 | 4 | import javax.transaction.Transactional; 5 | 6 | import org.springframework.data.jpa.repository.JpaRepository; 7 | import org.springframework.data.jpa.repository.Query; 8 | 9 | import com.favorites.domain.Comment; 10 | import com.favorites.domain.view.CommentView; 11 | 12 | public interface CommentRepository extends JpaRepository { 13 | 14 | public String findReplyUserSql="select u.id as userId, u.userName as userName,u.profilePicture as profilePicture,c.content as content," + 15 | " c.createTime as createTime,c.replyUserId as replyUserId " 16 | + "from Comment c,User u WHERE c.userId=u.id"; 17 | 18 | Long countByCollectId(Long collectId); 19 | 20 | List findByCollectIdOrderByIdDesc(Long collectId); 21 | 22 | @Transactional 23 | void deleteById(Long id); 24 | 25 | 26 | @Query(findReplyUserSql+ " and c.id=?1") 27 | CommentView findReplyUser(Long id); 28 | 29 | } -------------------------------------------------------------------------------- /app/src/main/java/com/favorites/comm/Const.java: -------------------------------------------------------------------------------- 1 | package com.favorites.comm; 2 | 3 | import org.springframework.beans.factory.annotation.Autowired; 4 | import org.springframework.beans.factory.annotation.Value; 5 | import org.springframework.stereotype.Component; 6 | 7 | @Component 8 | public class Const { 9 | 10 | public static String BASE_PATH; 11 | 12 | public static String LOGIN_SESSION_KEY = "Favorites_user"; 13 | 14 | public static String PASSWORD_KEY = "@#$%^&*()OPG#$%^&*(HG"; 15 | 16 | public static String DES3_KEY = "9964DYByKL967c3308imytCB"; 17 | 18 | public static String default_logo="img/logo.jpg"; 19 | 20 | public static String userAgent="Mozilla"; 21 | 22 | public static String default_Profile=BASE_PATH+"/img/logo.jpg"; 23 | 24 | public static String LAST_REFERER = "LAST_REFERER"; 25 | 26 | public static int COOKIE_TIMEOUT= 30*24*60*60; 27 | 28 | 29 | @Autowired(required = true) 30 | public void setBasePath(@Value("${favorites.base.path}")String basePath) { 31 | Const.BASE_PATH = basePath; 32 | } 33 | 34 | 35 | } 36 | -------------------------------------------------------------------------------- /app/src/test/java/com/favorites/util/html/HTMLParserExample2.java: -------------------------------------------------------------------------------- 1 | package com.favorites.util.html; 2 | import java.io.IOException; 3 | 4 | import org.jsoup.Jsoup; 5 | import org.jsoup.nodes.Document; 6 | import org.jsoup.nodes.Element; 7 | import org.jsoup.select.Elements; 8 | 9 | public class HTMLParserExample2 { 10 | 11 | public static void main(String[] args) { 12 | 13 | Document doc; 14 | try { 15 | 16 | //get all images 17 | doc = Jsoup.connect("http://ghelei312.iteye.com/blog/2257579").get(); 18 | Elements images = doc.select("img[src~=(?i)\\.(png|jpe?g|gif)]"); 19 | 20 | String xxx=images.first().attr("src"); 21 | System.out.println("XXXXXX*="+xxx); 22 | for (Element image : images) { 23 | 24 | System.out.println("\nsrc : " + image.attr("src")); 25 | System.out.println("height : " + image.attr("height")); 26 | System.out.println("width : " + image.attr("width")); 27 | System.out.println("alt : " + image.attr("alt")); 28 | 29 | } 30 | 31 | } catch (IOException e) { 32 | e.printStackTrace(); 33 | } 34 | 35 | } 36 | 37 | } -------------------------------------------------------------------------------- /app/src/main/resources/static/index/js/freelancer.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Start Bootstrap - Freelancer v3.3.7+1 (http://startbootstrap.com/template-overviews/freelancer) 3 | * Copyright 2013-2016 Start Bootstrap 4 | * Licensed under MIT (https://github.com/BlackrockDigital/startbootstrap/blob/gh-pages/LICENSE) 5 | */ 6 | !function(o){"use strict";o(".page-scroll a").bind("click",function(t){var l=o(this);o("html, body").stop().animate({scrollTop:o(l.attr("href")).offset().top-50},1250,"easeInOutExpo"),t.preventDefault()}),o("body").scrollspy({target:".navbar-fixed-top",offset:51}),o(".navbar-collapse ul li a").click(function(){o(".navbar-toggle:visible").click()}),o("#mainNav").affix({offset:{top:100}}),o(function(){o("body").on("input propertychange",".floating-label-form-group",function(t){o(this).toggleClass("floating-label-form-group-with-value",!!o(t.target).val())}).on("focus",".floating-label-form-group",function(){o(this).addClass("floating-label-form-group-with-focus")}).on("blur",".floating-label-form-group",function(){o(this).removeClass("floating-label-form-group-with-focus")})})}(jQuery); -------------------------------------------------------------------------------- /app/src/main/java/com/favorites/comm/exception/GlobalExceptionHandler.java: -------------------------------------------------------------------------------- 1 | package com.favorites.comm.exception; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | import org.springframework.web.bind.annotation.ControllerAdvice; 6 | import org.springframework.web.bind.annotation.ExceptionHandler; 7 | import org.springframework.web.servlet.ModelAndView; 8 | 9 | import javax.servlet.http.HttpServletRequest; 10 | 11 | /** 12 | * Created by DingYS on 2017/2/20. 13 | */ 14 | @ControllerAdvice 15 | public class GlobalExceptionHandler { 16 | 17 | protected Logger logger = LoggerFactory.getLogger(this.getClass()); 18 | 19 | public static final String DEFAULT_ERROR_VIEW = "error"; 20 | 21 | @ExceptionHandler(value = Exception.class) 22 | public ModelAndView defaultErrorHandler(Exception e, HttpServletRequest request) throws Exception { 23 | logger.info("请求地址:" + request.getRequestURL()); 24 | ModelAndView mav = new ModelAndView(); 25 | logger.error("异常信息:",e); 26 | mav.setViewName(DEFAULT_ERROR_VIEW); 27 | return mav; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /app/src/main/java/com/favorites/domain/result/Response.java: -------------------------------------------------------------------------------- 1 | package com.favorites.domain.result; 2 | 3 | public class Response { 4 | /** 返回信息码*/ 5 | private String rspCode="000000"; 6 | /** 返回信息内容*/ 7 | private String rspMsg="操作成功"; 8 | 9 | public Response() { 10 | } 11 | 12 | public Response(ExceptionMsg msg){ 13 | this.rspCode=msg.getCode(); 14 | this.rspMsg=msg.getMsg(); 15 | } 16 | 17 | public Response(String rspCode) { 18 | this.rspCode = rspCode; 19 | this.rspMsg = ""; 20 | } 21 | 22 | public Response(String rspCode, String rspMsg) { 23 | this.rspCode = rspCode; 24 | this.rspMsg = rspMsg; 25 | } 26 | public String getRspCode() { 27 | return rspCode; 28 | } 29 | public void setRspCode(String rspCode) { 30 | this.rspCode = rspCode; 31 | } 32 | public String getRspMsg() { 33 | return rspMsg; 34 | } 35 | public void setRspMsg(String rspMsg) { 36 | this.rspMsg = rspMsg; 37 | } 38 | 39 | @Override 40 | public String toString() { 41 | return "Response{" + 42 | "rspCode='" + rspCode + '\'' + 43 | ", rspMsg='" + rspMsg + '\'' + 44 | '}'; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /app/src/main/java/com/favorites/service/CollectService.java: -------------------------------------------------------------------------------- 1 | package com.favorites.service; 2 | 3 | import com.favorites.domain.Collect; 4 | import com.favorites.domain.view.CollectSummary; 5 | 6 | import org.springframework.data.domain.Pageable; 7 | 8 | import java.util.List; 9 | import java.util.Map; 10 | 11 | public interface CollectService { 12 | 13 | public List getCollects(String type, Long userId, Pageable pageable,Long favoritesId,Long specUserId); 14 | 15 | public void saveCollect(Collect collect); 16 | 17 | public void updateCollect(Collect newCollect); 18 | 19 | public boolean checkCollect(Collect collect); 20 | 21 | public void importHtml(Map map,Long favoritesId,Long userId,String type); 22 | 23 | public StringBuilder exportToHtml(long favoritesId); 24 | 25 | public List searchMy(Long userId,String key,Pageable pageable); 26 | 27 | public List searchOther(Long userId,String key,Pageable pageable); 28 | 29 | public void otherCollect(Collect collect); 30 | 31 | public void like(Long userId,long id); 32 | 33 | } 34 | -------------------------------------------------------------------------------- /app/src/main/java/com/favorites/domain/result/ResponseData.java: -------------------------------------------------------------------------------- 1 | package com.favorites.domain.result; 2 | 3 | public class ResponseData extends Response{ 4 | private Object data; 5 | 6 | public ResponseData(Object data) { 7 | this.data = data; 8 | } 9 | 10 | public ResponseData(ExceptionMsg msg) { 11 | super(msg); 12 | } 13 | 14 | public ResponseData(String rspCode, String rspMsg) { 15 | super(rspCode, rspMsg); 16 | } 17 | 18 | public ResponseData(String rspCode, String rspMsg, Object data) { 19 | super(rspCode, rspMsg); 20 | this.data = data; 21 | } 22 | 23 | public ResponseData(ExceptionMsg msg, Object data) { 24 | super(msg); 25 | this.data = data; 26 | } 27 | 28 | public Object getData() { 29 | return data; 30 | } 31 | 32 | public void setData(Object data) { 33 | this.data = data; 34 | } 35 | 36 | @Override 37 | public String toString() { 38 | return "ResponseData{" + 39 | "data=" + data + 40 | "} " + super.toString(); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /app/src/main/java/com/favorites/domain/view/CollectorView.java: -------------------------------------------------------------------------------- 1 | package com.favorites.domain.view; 2 | 3 | import javax.persistence.Column; 4 | import javax.persistence.Entity; 5 | import javax.persistence.GeneratedValue; 6 | import javax.persistence.Id; 7 | 8 | /** 9 | * @Description: 10 | * @Auth: yuyang 11 | * @Date: 2017/1/17 12:25 12 | * @Version: 1.0 13 | **/ 14 | @Entity 15 | public class CollectorView { 16 | 17 | @Id 18 | @GeneratedValue 19 | private Long id; 20 | @Column(name="userId",length=20) 21 | private Long userId; 22 | @Column(name="counts",length=20) 23 | private Long counts; 24 | 25 | public Long getId() { 26 | return id; 27 | } 28 | 29 | public void setId(Long id) { 30 | this.id = id; 31 | } 32 | 33 | public Long getUserId() { 34 | return userId; 35 | } 36 | 37 | public void setUserId(Long userId) { 38 | this.userId = userId; 39 | } 40 | 41 | public Long getCounts() { 42 | return counts; 43 | } 44 | 45 | public void setCounts(Long counts) { 46 | this.counts = counts; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /app/src/main/java/com/favorites/repository/LetterRepository.java: -------------------------------------------------------------------------------- 1 | package com.favorites.repository; 2 | 3 | import com.favorites.domain.Letter; 4 | import com.favorites.domain.view.LetterView; 5 | import org.springframework.data.domain.Pageable; 6 | import org.springframework.data.jpa.repository.JpaRepository; 7 | import org.springframework.data.jpa.repository.Modifying; 8 | import org.springframework.data.jpa.repository.Query; 9 | 10 | import javax.transaction.Transactional; 11 | import java.util.List; 12 | 13 | /** 14 | * Created by DingYS on 2017/3/7. 15 | */ 16 | public interface LetterRepository extends JpaRepository { 17 | 18 | public String findSql = "select l.id as id,l.sendUserId as sendUserId,u.userName as sendUserName,u.profilePicture as profilePicture,l.content as content,l.createTime as createTime,l.pid as pid,l.type as type from Letter l,User u where l.sendUserId = u.id"; 19 | 20 | @Transactional 21 | @Modifying 22 | @Query("update Letter l set l.pid = ?2 where l.id = ?1") 23 | int updatePidById(Long id,Long pid); 24 | 25 | @Query(findSql+" and l.receiveUserId = ?1") 26 | List findLetterByReceiveUserId(Long userId,Pageable pageable); 27 | 28 | } 29 | -------------------------------------------------------------------------------- /app/src/main/java/com/favorites/repository/ConfigRepository.java: -------------------------------------------------------------------------------- 1 | package com.favorites.repository; 2 | 3 | import javax.transaction.Transactional; 4 | 5 | import org.springframework.data.jpa.repository.JpaRepository; 6 | import org.springframework.data.jpa.repository.Modifying; 7 | import org.springframework.data.jpa.repository.Query; 8 | 9 | import com.favorites.domain.Config; 10 | 11 | public interface ConfigRepository extends JpaRepository { 12 | 13 | Config findByUserId(Long userId); 14 | 15 | Config findById(long id); 16 | 17 | Config findByUserIdAndDefaultFavorties(Long userId,String defaultFavorites); 18 | 19 | @Transactional 20 | @Modifying 21 | @Query("update Config set defaultCollectType=?2,lastModifyTime =?3 where id = ?1") 22 | int updateCollectTypeById(Long id,String value,Long lastModifyTime); 23 | 24 | @Transactional 25 | @Modifying 26 | @Query("update Config set defaultModel=?2,lastModifyTime =?3 where id = ?1") 27 | int updateModelTypeById(Long id,String value,Long lastModifyTime); 28 | 29 | @Transactional 30 | @Modifying 31 | @Query("update Config set defaultFavorties=?2,lastModifyTime =?3 where id = ?1") 32 | int updateFavoritesById(Long id,String value,Long lastModifyTime); 33 | 34 | } -------------------------------------------------------------------------------- /mysql/my.cnf: -------------------------------------------------------------------------------- 1 | [mysqld] 2 | # 3 | # Remove leading # and set to the amount of RAM for the most important data 4 | # cache in MySQL. Start at 70% of total RAM for dedicated server, else 10%. 5 | # innodb_buffer_pool_size = 128M 6 | # 7 | # Remove leading # to turn on a very important data integrity option: logging 8 | # changes to the binary log between backups. 9 | # log_bin 10 | # 11 | # Remove leading # to set options mainly useful for reporting servers. 12 | # The server defaults are faster for transactions and fast SELECTs. 13 | # Adjust sizes as needed, experiment to find the optimal values. 14 | # join_buffer_size = 128M 15 | # sort_buffer_size = 2M 16 | # read_rnd_buffer_size = 2M 17 | skip-host-cache 18 | skip-name-resolve 19 | datadir=/var/lib/mysql 20 | socket=/var/lib/mysql/mysql.sock 21 | secure-file-priv=/var/lib/mysql-files 22 | user=mysql 23 | 24 | # Disabling symbolic-links is recommended to prevent assorted security risks 25 | symbolic-links=0 26 | 27 | log-error=/var/log/mysqld.log 28 | pid-file=/var/run/mysqld/mysqld.pid 29 | 30 | character_set_server=utf8 31 | character_set_filesystem=utf8 32 | collation-server=utf8_general_ci 33 | init-connect='SET NAMES utf8' 34 | init_connect='SET collation_connection = utf8_general_ci' 35 | skip-character-set-client-handshake -------------------------------------------------------------------------------- /app/src/main/java/com/favorites/domain/Praise.java: -------------------------------------------------------------------------------- 1 | package com.favorites.domain; 2 | 3 | import java.io.Serializable; 4 | 5 | import javax.persistence.*; 6 | 7 | /** 8 | * 点赞 9 | * 10 | * @author DingYS 11 | * 12 | */ 13 | @Entity 14 | public class Praise extends Entitys implements Serializable { 15 | 16 | private static final long serialVersionUID = 1L; 17 | @Id 18 | @GeneratedValue(strategy= GenerationType.IDENTITY) 19 | private Long id; 20 | @Column(nullable = false) 21 | private Long collectId; 22 | @Column(nullable = false) 23 | private Long userId; 24 | @Column(nullable = false) 25 | private Long createTime; 26 | 27 | public Praise() { 28 | super(); 29 | } 30 | 31 | public Long getId() { 32 | return id; 33 | } 34 | 35 | public void setId(Long id) { 36 | this.id = id; 37 | } 38 | 39 | public Long getCollectId() { 40 | return collectId; 41 | } 42 | 43 | public void setCollectId(Long collectId) { 44 | this.collectId = collectId; 45 | } 46 | 47 | public Long getUserId() { 48 | return userId; 49 | } 50 | 51 | public void setUserId(Long userId) { 52 | this.userId = userId; 53 | } 54 | 55 | public Long getCreateTime() { 56 | return createTime; 57 | } 58 | 59 | public void setCreateTime(Long createTime) { 60 | this.createTime = createTime; 61 | } 62 | 63 | } -------------------------------------------------------------------------------- /app/src/main/java/com/favorites/web/FeedbackController.java: -------------------------------------------------------------------------------- 1 | package com.favorites.web; 2 | 3 | import com.favorites.domain.Feedback; 4 | import com.favorites.domain.result.ExceptionMsg; 5 | import com.favorites.domain.result.Response; 6 | import com.favorites.service.FeedbackService; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.web.bind.annotation.RequestMapping; 9 | import org.springframework.web.bind.annotation.RequestMethod; 10 | import org.springframework.web.bind.annotation.RestController; 11 | 12 | /** 13 | * Created by chenzhimin on 2017/2/23. 14 | */ 15 | @RestController 16 | @RequestMapping("/feedback") 17 | public class FeedbackController extends BaseController{ 18 | @Autowired 19 | private FeedbackService feedbackService; 20 | 21 | /** 22 | * @author chenzhimin 23 | * @date 2017年1月23日 24 | * @return 25 | */ 26 | @RequestMapping(value="/save",method = RequestMethod.POST) 27 | public Response save(Feedback feedback) { 28 | try { 29 | feedbackService.saveFeeddback(feedback,getUserId()); 30 | } catch (Exception e) { 31 | logger.error("feedback failed, ", e); 32 | return result(ExceptionMsg.FAILED); 33 | } 34 | return result(); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /app/src/main/java/com/favorites/domain/result/ExceptionMsg.java: -------------------------------------------------------------------------------- 1 | 2 | package com.favorites.domain.result; 3 | 4 | public enum ExceptionMsg { 5 | SUCCESS("000000", "操作成功"), 6 | FAILED("999999","操作失败"), 7 | ParamError("000001", "参数错误!"), 8 | 9 | LoginNameOrPassWordError("000100", "用户名或者密码错误!"), 10 | EmailUsed("000101","该邮箱已被注册"), 11 | UserNameUsed("000102","该登录名称已存在"), 12 | EmailNotRegister("000103","该邮箱地址未注册"), 13 | LinkOutdated("000104","该链接已过期,请重新请求"), 14 | PassWordError("000105","密码输入错误"), 15 | UserNameLengthLimit("000106","用户名长度超限"), 16 | LoginNameNotExists("000107","该用户未注册"), 17 | UserNameSame("000108","新用户名与原用户名一致"), 18 | 19 | FavoritesNameIsNull("000200","收藏夹名称不能为空"), 20 | FavoritesNameUsed("000201","收藏夹名称已被创建"), 21 | 22 | CollectExist("000300","该文章已被收藏"), 23 | 24 | FileEmpty("000400","上传文件为空"), 25 | LimitPictureSize("000401","图片大小必须小于2M"), 26 | LimitPictureType("000402","图片格式必须为'jpg'、'png'、'jpge'、'gif'、'bmp'") 27 | ; 28 | private ExceptionMsg(String code, String msg) { 29 | this.code = code; 30 | this.msg = msg; 31 | } 32 | private String code; 33 | private String msg; 34 | 35 | public String getCode() { 36 | return code; 37 | } 38 | public String getMsg() { 39 | return msg; 40 | } 41 | 42 | 43 | } 44 | 45 | -------------------------------------------------------------------------------- /app/src/main/java/com/favorites/domain/UrlLibrary.java: -------------------------------------------------------------------------------- 1 | package com.favorites.domain; 2 | 3 | import javax.persistence.*; 4 | import java.io.Serializable; 5 | 6 | /** 7 | * Created by DingYS on 2016/12/29. 8 | */ 9 | @Entity 10 | public class UrlLibrary extends Entitys implements Serializable{ 11 | 12 | @Id 13 | @GeneratedValue(strategy= GenerationType.IDENTITY) 14 | private Long id; 15 | @Column(nullable = false, columnDefinition = "varchar(600)") 16 | private String url; 17 | @Column(nullable = true,columnDefinition = "varchar(300)") 18 | private String logoUrl; 19 | @Column(columnDefinition="INT default 0") 20 | private int count; 21 | 22 | public int getCount() { 23 | return count; 24 | } 25 | 26 | public void setCount(int count) { 27 | this.count = count; 28 | } 29 | 30 | public Long getId() { 31 | return id; 32 | } 33 | 34 | public void setId(Long id) { 35 | this.id = id; 36 | } 37 | 38 | public String getUrl() { 39 | return url; 40 | } 41 | 42 | public void setUrl(String url) { 43 | this.url = url; 44 | } 45 | 46 | public String getLogoUrl() { 47 | return logoUrl; 48 | } 49 | 50 | public void setLogoUrl(String logoUrl) { 51 | this.logoUrl = logoUrl; 52 | } 53 | 54 | } 55 | -------------------------------------------------------------------------------- /app/src/main/java/com/favorites/utils/FileUtil.java: -------------------------------------------------------------------------------- 1 | package com.favorites.utils; 2 | 3 | import java.io.File; 4 | import java.io.FileOutputStream; 5 | 6 | /** 7 | *@ClassName: FileUtil 8 | *@Description: 9 | *@author YY 10 | *@date 2016年8月26日 上午10:26:17 11 | *@version 1.0 12 | */ 13 | public class FileUtil { 14 | 15 | /** 16 | * 获取文件类型 17 | * @param fileName 18 | * @return 19 | */ 20 | public static String getFileExtName(String fileName) { 21 | if (fileName!=null ) { 22 | int i = fileName.lastIndexOf('.'); 23 | if (i>-1) { 24 | return fileName.substring(i+1).toLowerCase(); 25 | }else { 26 | return null; 27 | } 28 | }else { 29 | return null; 30 | } 31 | } 32 | 33 | /** 34 | * 上传文件 35 | * @param fileBytes 36 | * @param filePath 37 | * @param fileName 38 | * @throws Exception 39 | */ 40 | public static void uploadFile(byte[] fileBytes, String filePath, String fileName) throws Exception { 41 | File targetFile = new File(filePath); 42 | if(!targetFile.exists()){ 43 | targetFile.mkdirs(); 44 | } 45 | FileOutputStream out = new FileOutputStream(filePath+fileName); 46 | out.write(fileBytes); 47 | out.flush(); 48 | out.close(); 49 | } 50 | 51 | } -------------------------------------------------------------------------------- /app/src/main/java/com/favorites/domain/UserIsFollow.java: -------------------------------------------------------------------------------- 1 | package com.favorites.domain; 2 | 3 | import javax.persistence.Entity; 4 | import javax.persistence.GeneratedValue; 5 | import javax.persistence.GenerationType; 6 | import javax.persistence.Id; 7 | import java.io.Serializable; 8 | 9 | /** 10 | * 随便看看右侧关注使用 11 | * Created by chenzhimin on 2017/1/19. 12 | */ 13 | @Entity 14 | public class UserIsFollow implements Serializable{ 15 | @Id 16 | @GeneratedValue(strategy= GenerationType.IDENTITY) 17 | private Long id; 18 | private String userName; 19 | private String profilePicture; 20 | private String isFollow; 21 | 22 | public Long getId() { 23 | return id; 24 | } 25 | 26 | public void setId(Long id) { 27 | this.id = id; 28 | } 29 | 30 | public String getUserName() { 31 | return userName; 32 | } 33 | 34 | public void setUserName(String userName) { 35 | this.userName = userName; 36 | } 37 | 38 | public String getProfilePicture() { 39 | return profilePicture; 40 | } 41 | 42 | public void setProfilePicture(String profilePicture) { 43 | this.profilePicture = profilePicture; 44 | } 45 | 46 | public String getIsFollow() { 47 | return isFollow; 48 | } 49 | 50 | public void setIsFollow(String isFollow) { 51 | this.isFollow = isFollow; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /app/src/test/java/com/favorites/domain/UserRepositoryTests.java: -------------------------------------------------------------------------------- 1 | package com.favorites.domain; 2 | 3 | import org.junit.Assert; 4 | import org.junit.Test; 5 | import org.junit.runner.RunWith; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.boot.test.context.SpringBootTest; 8 | import org.springframework.test.context.junit4.SpringRunner; 9 | 10 | import com.favorites.repository.UserRepository; 11 | 12 | @RunWith(SpringRunner.class) 13 | @SpringBootTest 14 | public class UserRepositoryTests { 15 | 16 | @Autowired 17 | private UserRepository userRepository; 18 | 19 | @Test 20 | public void test() throws Exception { 21 | 22 | userRepository.save(new User("aa", "aa@126.com", "aa", "aa123456")); 23 | userRepository.save(new User("bb", "bb@126.com", "bb", "bb123456")); 24 | userRepository.save(new User("cc", "cc@126.com", "cc", "cc123456")); 25 | Assert.assertEquals(9, userRepository.findAll().size()); 26 | 27 | Assert.assertEquals("aa", userRepository.findByUserName("aa").getUserName()); 28 | 29 | /*Assert.assertEquals(60, userRepository.findUser("FFF").getAge().longValue()); 30 | 31 | Assert.assertEquals("FFF", userRepository.findByNameAndAge("FFF", 60).getName()); 32 | 33 | userRepository.delete(userRepository.findByName("AAA")); 34 | 35 | Assert.assertEquals(9, userRepository.findAll().size()); 36 | */ 37 | } 38 | 39 | 40 | } -------------------------------------------------------------------------------- /app/src/main/resources/static/vendor/scrollable/scrollable.min.css: -------------------------------------------------------------------------------- 1 | .scrollable .scrollable-bar,.scrollable .scrollable-slider{-webkit-border-radius:2px;-moz-border-radius:2px;border-radius:2px}.scrollable{overflow:hidden;position:relative;width:100%;height:100%}.scrollable-content{box-sizing:border-box;min-height:100%}.fullwindow .scrollable-content{transform:none!important}.scrollable .scrollable-content,.scrollable .scrollable-slider{-webkit-transition:background-color .2s linear,opacity .2s linear,-webkit-transform .2s ease-out;-moz-transition:background-color .2s linear,opacity .2s linear,-moz-transform .2s ease-out;-ms-transition:background-color .2s linear,opacity .2s linear,-ms-transform .2s ease-out;-o-transition:background-color .2s linear,opacity .2s linear,-o-transform .2s ease-out;transition:background-color .2s linear,opacity .2s linear,transform .2s ease-out}.scrollable .scrollable-bar{position:absolute;box-sizing:border-box;opacity:0;background-color:#f0f0f0;background-color:rgba(255,255,255,.8);border:2px solid transparent}.scrollable:hover .scrollable-bar{opacity:.6}.scrollable .scrollable-bar:hover,.scrollable.active .scrollable-bar{opacity:1}.scrollable .scrollable-slider{background-color:#ccc;background-image:linear-gradient(to right,#ccc,#ddd);border:1px solid #333;border:1px solid rgba(0,0,0,.5)}.scrollable .scrollable-bar-x .scrollable-slider{height:8px}.scrollable .scrollable-bar-y .scrollable-slider{width:8px} -------------------------------------------------------------------------------- /app/src/main/java/com/favorites/web/WebJarController.java: -------------------------------------------------------------------------------- 1 | package com.favorites.web; 2 | 3 | import org.springframework.core.io.ClassPathResource; 4 | import org.springframework.http.HttpStatus; 5 | import org.springframework.http.ResponseEntity; 6 | import org.springframework.stereotype.Controller; 7 | import org.springframework.web.bind.annotation.PathVariable; 8 | import org.springframework.web.bind.annotation.RequestMapping; 9 | import org.springframework.web.bind.annotation.ResponseBody; 10 | import org.springframework.web.servlet.HandlerMapping; 11 | import org.webjars.WebJarAssetLocator; 12 | 13 | import javax.servlet.http.HttpServletRequest; 14 | 15 | @Controller 16 | public class WebJarController { 17 | private final WebJarAssetLocator assetLocator = new WebJarAssetLocator(); 18 | 19 | @ResponseBody 20 | @RequestMapping("/webjarslocator/{webjar}/**") 21 | public ResponseEntity locateWebjarAsset(@PathVariable String webjar, HttpServletRequest request) { 22 | try { 23 | 24 | String mvcPrefix = "/webjarslocator/" + webjar + "/"; 25 | String mvcPath = (String) request.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE); 26 | String fullPath = assetLocator.getFullPath(webjar, mvcPath.substring(mvcPrefix.length())); 27 | return new ResponseEntity(new ClassPathResource(fullPath), HttpStatus.OK); 28 | } catch (Exception e) { 29 | return new ResponseEntity(HttpStatus.NOT_FOUND); 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /app/src/test/java/com/favorites/controller/HelloWorldControlerTests.java: -------------------------------------------------------------------------------- 1 | package com.favorites.controller; 2 | 3 | import org.junit.Before; 4 | import org.junit.Test; 5 | import org.junit.runner.RunWith; 6 | import org.springframework.boot.test.context.SpringBootTest; 7 | import org.springframework.http.MediaType; 8 | import org.springframework.test.context.junit4.SpringRunner; 9 | import org.springframework.test.context.web.WebAppConfiguration; 10 | import org.springframework.test.web.servlet.MockMvc; 11 | import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; 12 | import org.springframework.test.web.servlet.result.MockMvcResultHandlers; 13 | import org.springframework.test.web.servlet.result.MockMvcResultMatchers; 14 | import org.springframework.test.web.servlet.setup.MockMvcBuilders; 15 | 16 | import com.favorites.web.IndexController; 17 | 18 | @RunWith(SpringRunner.class) 19 | @SpringBootTest 20 | @WebAppConfiguration 21 | public class HelloWorldControlerTests { 22 | 23 | private MockMvc mvc; 24 | 25 | @Before 26 | public void setUp() throws Exception { 27 | mvc = MockMvcBuilders.standaloneSetup(new IndexController()).build(); 28 | } 29 | 30 | @Test 31 | public void getHello() throws Exception { 32 | mvc.perform(MockMvcRequestBuilders.get("/hello").accept(MediaType.APPLICATION_JSON)) 33 | .andExpect(MockMvcResultMatchers.status().isOk()) 34 | .andDo(MockMvcResultHandlers.print()) 35 | .andReturn(); 36 | } 37 | 38 | } -------------------------------------------------------------------------------- /app/src/main/java/com/favorites/repository/FavoritesRepository.java: -------------------------------------------------------------------------------- 1 | package com.favorites.repository; 2 | 3 | 4 | import java.util.List; 5 | 6 | import javax.transaction.Transactional; 7 | 8 | import com.favorites.domain.Collect; 9 | import org.springframework.data.jpa.repository.JpaRepository; 10 | import org.springframework.data.jpa.repository.Modifying; 11 | import org.springframework.data.jpa.repository.Query; 12 | import org.springframework.data.repository.query.Param; 13 | 14 | import com.favorites.domain.Favorites; 15 | 16 | public interface FavoritesRepository extends JpaRepository { 17 | 18 | Favorites findById(long id); 19 | 20 | List findByUserId(Long userId); 21 | 22 | List findByUserIdOrderByLastModifyTimeDesc(Long userId); 23 | 24 | List findByUserIdOrderByLastModifyTimeAsc(Long userId); 25 | 26 | Favorites findByUserIdAndName(Long userId,String name); 27 | 28 | @Modifying(clearAutomatically=true) 29 | @Transactional 30 | @Query("update Favorites f set f.count=(f.count-1),f.lastModifyTime =:lastModifyTime where f.id =:id") 31 | void reduceCountById(@Param("id") Long id,@Param("lastModifyTime") Long lastModifyTime); 32 | 33 | @Modifying(clearAutomatically=true) 34 | @Transactional 35 | @Query("update Favorites set name=:name ,lastModifyTime=:lastModifyTime where id=:id") 36 | void updateNameById(@Param("id") Long id,@Param("lastModifyTime") Long lastModifyTime,@Param("name") String name); 37 | @Query("select id from Favorites where name=?1") 38 | List findIdByName(String name); 39 | } -------------------------------------------------------------------------------- /app/src/test/java/com/favorites/domain/RepositoryTest.java: -------------------------------------------------------------------------------- 1 | package com.favorites.domain; 2 | 3 | import java.util.List; 4 | 5 | import org.junit.Test; 6 | import org.junit.runner.RunWith; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.boot.test.context.SpringBootTest; 9 | import org.springframework.test.context.junit4.SpringRunner; 10 | 11 | import com.favorites.repository.CommentRepository; 12 | import com.favorites.repository.FollowRepository; 13 | import com.favorites.repository.PraiseRepository; 14 | 15 | 16 | @RunWith(SpringRunner.class) 17 | @SpringBootTest 18 | public class RepositoryTest { 19 | 20 | @Autowired 21 | private PraiseRepository praiseRepository; 22 | 23 | @Autowired 24 | private CommentRepository commentRepository; 25 | 26 | @Autowired 27 | private FollowRepository followRepository; 28 | 29 | @Test 30 | public void testPraise() throws Exception { 31 | long count=praiseRepository.countByCollectId(1l); 32 | System.out.println("count===="+count); 33 | Praise praise=praiseRepository.findByUserIdAndCollectId(1l, 1l); 34 | System.out.println("exists===="+praise); 35 | 36 | } 37 | 38 | 39 | @Test 40 | public void testComment() throws Exception { 41 | long count=commentRepository.countByCollectId(1l); 42 | System.out.println("count===="+count); 43 | 44 | } 45 | 46 | 47 | @Test 48 | public void testFollow() throws Exception { 49 | List userIds=followRepository.findMyFollowIdByUserId(1l); 50 | for(Long userId:userIds){ 51 | System.out.println("userId===="+userId); 52 | } 53 | 54 | } 55 | 56 | 57 | } -------------------------------------------------------------------------------- /app/src/main/resources/static/index/js/freelancer.js: -------------------------------------------------------------------------------- 1 | // Freelancer Theme JavaScript 2 | 3 | (function($) { 4 | "use strict"; // Start of use strict 5 | 6 | // jQuery for page scrolling feature - requires jQuery Easing plugin 7 | $('.page-scroll a').bind('click', function(event) { 8 | var $anchor = $(this); 9 | $('html, body').stop().animate({ 10 | scrollTop: ($($anchor.attr('href')).offset().top - 50) 11 | }, 1250, 'easeInOutExpo'); 12 | event.preventDefault(); 13 | }); 14 | 15 | // Highlight the top nav as scrolling occurs 16 | $('body').scrollspy({ 17 | target: '.navbar-fixed-top', 18 | offset: 51 19 | }); 20 | 21 | // Closes the Responsive Menu on Menu Item Click 22 | $('.navbar-collapse ul li a').click(function(){ 23 | $('.navbar-toggle:visible').click(); 24 | }); 25 | 26 | // Offset for Main Navigation 27 | $('#mainNav').affix({ 28 | offset: { 29 | top: 100 30 | } 31 | }) 32 | 33 | // Floating label headings for the contact form 34 | $(function() { 35 | $("body").on("input propertychange", ".floating-label-form-group", function(e) { 36 | $(this).toggleClass("floating-label-form-group-with-value", !!$(e.target).val()); 37 | }).on("focus", ".floating-label-form-group", function() { 38 | $(this).addClass("floating-label-form-group-with-focus"); 39 | }).on("blur", ".floating-label-form-group", function() { 40 | $(this).removeClass("floating-label-form-group-with-focus"); 41 | }); 42 | }); 43 | 44 | })(jQuery); // End of use strict 45 | -------------------------------------------------------------------------------- /app/src/main/java/com/favorites/service/impl/RedisServiceImpl.java: -------------------------------------------------------------------------------- 1 | /* 2 | package com.favorites.service.impl; 3 | 4 | import com.favorites.service.RedisService; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.data.redis.core.RedisTemplate; 7 | import org.springframework.data.redis.core.StringRedisTemplate; 8 | import org.springframework.stereotype.Service; 9 | 10 | import java.util.concurrent.TimeUnit; 11 | 12 | */ 13 | /** 14 | * @Description: 15 | * @Auth: yuyang 16 | * @Date: 2017/2/24 16:11 17 | * @Version: 1.0 18 | **//* 19 | 20 | @Service 21 | public class RedisServiceImpl implements RedisService{ 22 | 23 | 24 | @Autowired 25 | private RedisTemplate redisTemplate; 26 | @Autowired 27 | private StringRedisTemplate stringRedisTemplate; 28 | 29 | @Override 30 | public void set(String key, String value) { 31 | stringRedisTemplate.opsForValue().set(key, value); 32 | } 33 | 34 | @Override 35 | public String get(String key) { 36 | return stringRedisTemplate.opsForValue().get(key); 37 | } 38 | 39 | @Override 40 | public void setObject(String key, Object value) { 41 | redisTemplate.opsForValue().set(key, value); 42 | } 43 | 44 | @Override 45 | public Object getObject(String key) { 46 | return redisTemplate.opsForValue().get(key); 47 | } 48 | 49 | @Override 50 | public boolean expire(String key, long timeout) { 51 | return redisTemplate.expire(key, timeout, TimeUnit.SECONDS); 52 | } 53 | 54 | @Override 55 | public void delete(String key){ 56 | redisTemplate.delete(key); 57 | } 58 | 59 | } 60 | */ 61 | -------------------------------------------------------------------------------- /app/src/main/java/com/favorites/domain/LookRecord.java: -------------------------------------------------------------------------------- 1 | package com.favorites.domain; 2 | 3 | import javax.persistence.*; 4 | import java.io.Serializable; 5 | 6 | /** 7 | * 浏览记录entity 8 | * Created by chenzhimin on 2017/1/5. 9 | */ 10 | @Entity 11 | public class LookRecord extends Entitys implements Serializable{ 12 | 13 | private static final long serialVersionUID = 1L; 14 | 15 | @Id 16 | @GeneratedValue(strategy= GenerationType.IDENTITY) 17 | private Long id; 18 | @Column(nullable = false) 19 | private Long userId; 20 | @Column(nullable = false) 21 | private Long collectId; 22 | @Column(nullable = false) 23 | private Long createTime; 24 | @Column(nullable = false) 25 | private Long lastModifyTime; 26 | 27 | public Long getId() { 28 | return id; 29 | } 30 | 31 | public void setId(Long id) { 32 | this.id = id; 33 | } 34 | 35 | public Long getUserId() { 36 | return userId; 37 | } 38 | 39 | public void setUserId(Long userId) { 40 | this.userId = userId; 41 | } 42 | 43 | public Long getCollectId() { 44 | return collectId; 45 | } 46 | 47 | public void setCollectId(Long collectId) { 48 | this.collectId = collectId; 49 | } 50 | 51 | public Long getCreateTime() { 52 | return createTime; 53 | } 54 | 55 | public void setCreateTime(Long createTime) { 56 | this.createTime = createTime; 57 | } 58 | 59 | public Long getLastModifyTime() { 60 | return lastModifyTime; 61 | } 62 | 63 | public void setLastModifyTime(Long lastModifyTime) { 64 | this.lastModifyTime = lastModifyTime; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /app/src/main/resources/templates/error.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Favorites error Page 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 22 |
23 |
24 |
25 |

26 |

27 |

您访问的内容有错!请联系我们 cloudfavorites@126.com

28 |

29 | 返回首页 30 |

31 |
32 |
33 |
34 | 35 | -------------------------------------------------------------------------------- /app/src/main/java/com/favorites/repository/NoticeRepository.java: -------------------------------------------------------------------------------- 1 | package com.favorites.repository; 2 | 3 | import javax.transaction.Transactional; 4 | 5 | import org.springframework.data.domain.Page; 6 | import org.springframework.data.domain.Pageable; 7 | import org.springframework.data.jpa.repository.JpaRepository; 8 | import org.springframework.data.jpa.repository.Modifying; 9 | import org.springframework.data.jpa.repository.Query; 10 | 11 | import com.favorites.domain.Notice; 12 | import com.favorites.domain.view.CollectView; 13 | 14 | public interface NoticeRepository extends JpaRepository { 15 | 16 | public String baseSql="select c.id as id,c.title as title, c.type as type,c.url as url," + 17 | "c.favoritesId as favoritesId,c.remark as favoriteName,c.logoUrl as logoUrl,c.userId as userId, " 18 | + "c.remark as remark,c.description as description,c.lastModifyTime as lastModifyTime, " 19 | + "u.userName as userName,u.profilePicture as profilePicture,n.operId as operId " 20 | + "from Notice n,Collect c,User u WHERE n.collectId=c.id and c.userId=u.id"; 21 | 22 | @Query(baseSql+ " and n.userId=?1 and n.type=?2") 23 | Page findViewByUserIdAndType(Long userId,String type,Pageable pageable); 24 | 25 | Long countByUserIdAndTypeAndReaded(Long userId,String type,String readed); 26 | 27 | @Query("select count(1) from Notice n,Praise p where n.operId=p.id and type='praise' and n.userId=?1 and n.readed=?2") 28 | Long countPraiseByUserIdAndReaded(Long userId,String readed); 29 | 30 | @Transactional 31 | @Modifying 32 | @Query("update Notice n set n.readed = ?1 where n.userId = ?2 and n.type = ?3 and n.readed='unread'") 33 | int updateReadedByUserId(String readed, long userId, String type); 34 | 35 | } -------------------------------------------------------------------------------- /app/src/main/java/com/favorites/web/LookRecordController.java: -------------------------------------------------------------------------------- 1 | package com.favorites.web; 2 | 3 | import com.favorites.domain.result.Response; 4 | import com.favorites.service.LookRecordService; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.web.bind.annotation.PathVariable; 7 | import org.springframework.web.bind.annotation.RequestMapping; 8 | import org.springframework.web.bind.annotation.RestController; 9 | 10 | /** 11 | * Created by chenzhimin on 2017/2/14. 12 | */ 13 | @RestController 14 | @RequestMapping("/lookRecord") 15 | public class LookRecordController extends BaseController{ 16 | 17 | @Autowired 18 | private LookRecordService lookRecordService; 19 | 20 | /** 21 | * @author chenzhimin 22 | * @date 2017年1月23日 23 | * @param collectId 收藏ID 24 | * @return 25 | */ 26 | @RequestMapping(value="/save/{collectId}") 27 | public Response saveLookRecord(@PathVariable("collectId") long collectId) { 28 | lookRecordService.saveLookRecord(this.getUserId(),collectId); 29 | return result(); 30 | } 31 | 32 | /** 33 | * @author chenzhimin 34 | * @date 2017年1月23日 35 | * @param collectId 收藏ID 36 | * @return 37 | */ 38 | @RequestMapping(value="/delete/{collectId}") 39 | public Response deleteLookRecord(@PathVariable("collectId") long collectId) { 40 | lookRecordService.deleteLookRecord(this.getUserId(),collectId); 41 | return result(); 42 | } 43 | 44 | /** 45 | * @author chenzhimin 46 | * @date 2017年1月23日 47 | * @return 48 | */ 49 | @RequestMapping(value="/deleteAll") 50 | public Response deleteAll() { 51 | lookRecordService.deleteLookRecordByUserID(this.getUserId()); 52 | return result(); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | repositories { 3 | maven { url "http://repo2.maven.org/maven2" } 4 | mavenLocal() 5 | } 6 | dependencies { 7 | classpath("org.springframework.boot:spring-boot-gradle-plugin:1.5.8.RELEASE") 8 | } 9 | } 10 | 11 | apply plugin: 'java' 12 | apply plugin: 'org.springframework.boot' 13 | apply plugin: 'war' 14 | apply plugin: 'idea' 15 | 16 | war { 17 | baseName = 'favorites-web' 18 | version = '0.1.0' 19 | } 20 | 21 | sourceCompatibility = 1.8 22 | targetCompatibility = 1.8 23 | 24 | repositories { 25 | mavenCentral() 26 | maven { url "http://repo2.maven.org/maven2" } 27 | } 28 | 29 | dependencies { 30 | compile("org.springframework.boot:spring-boot-starter-web:1.5.8.RELEASE") 31 | compile("org.springframework.boot:spring-boot-starter-thymeleaf:1.5.8.RELEASE") 32 | compile("org.springframework.boot:spring-boot-starter-data-jpa:1.5.8.RELEASE") 33 | compile group: 'mysql', name: 'mysql-connector-java', version: '5.1.6' 34 | compile group: 'org.apache.commons', name: 'commons-lang3', version: '3.4' 35 | compile("org.springframework.boot:spring-boot-devtools:1.5.8.RELEASE") 36 | compile("org.springframework.boot:spring-boot-starter-test:1.5.8.RELEASE") 37 | compile("org.springframework.boot:spring-boot-starter-mail:1.5.8.RELEASE") 38 | compile 'org.webjars.bower:bootstrap:3.3.6' 39 | compile("org.webjars:vue:1.0.24") 40 | compile 'org.webjars.bower:vue-resource:0.7.0' 41 | compile group: 'org.webjars', name: 'webjars-locator', version: '0.14' 42 | compile group: 'org.jsoup', name: 'jsoup', version: '1.14.2' 43 | compile 'org.springframework.boot:spring-boot-starter-tomcat' 44 | } 45 | 46 | bootRun { 47 | addResources = true 48 | } 49 | 50 | springBoot { 51 | mainClass = "com.favorites.Application" 52 | } 53 | -------------------------------------------------------------------------------- /app/src/main/java/com/favorites/web/FollowController.java: -------------------------------------------------------------------------------- 1 | package com.favorites.web; 2 | 3 | import org.springframework.beans.factory.annotation.Autowired; 4 | import org.springframework.web.bind.annotation.RequestMapping; 5 | import org.springframework.web.bind.annotation.RestController; 6 | 7 | import com.favorites.comm.aop.LoggerManage; 8 | import com.favorites.domain.Follow; 9 | import com.favorites.domain.enums.FollowStatus; 10 | import com.favorites.domain.result.ExceptionMsg; 11 | import com.favorites.domain.result.Response; 12 | import com.favorites.repository.FollowRepository; 13 | import com.favorites.utils.DateUtils; 14 | 15 | @RestController 16 | @RequestMapping("/follow") 17 | public class FollowController extends BaseController{ 18 | 19 | @Autowired 20 | private FollowRepository followRepository; 21 | 22 | /** 23 | * 关注&取消关注 24 | * @return 25 | */ 26 | @RequestMapping("/changeFollowStatus") 27 | @LoggerManage(description="关注&取消关注") 28 | public Response changeFollowStatus(String status,Long userId){ 29 | try { 30 | FollowStatus followStatus = FollowStatus.FOLLOW; 31 | if(!"follow".equals(status)){ 32 | followStatus = FollowStatus.UNFOLLOW; 33 | } 34 | Follow follow = followRepository.findByUserIdAndFollowId(getUserId(), userId); 35 | if(null != follow){ 36 | followRepository.updateStatusById(followStatus, DateUtils.getCurrentTime(), follow.getId()); 37 | }else{ 38 | follow = new Follow(); 39 | follow.setFollowId(userId); 40 | follow.setUserId(getUserId()); 41 | follow.setStatus(followStatus); 42 | follow.setCreateTime(DateUtils.getCurrentTime()); 43 | follow.setLastModifyTime(DateUtils.getCurrentTime()); 44 | followRepository.save(follow); 45 | } 46 | } catch (Exception e) { 47 | logger.error("关注&取消关注异常:",e); 48 | return result(ExceptionMsg.FAILED); 49 | } 50 | return result(); 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /app/src/main/resources/static/index/vendor/font-awesome/less/mixins.less: -------------------------------------------------------------------------------- 1 | // Mixins 2 | // -------------------------- 3 | 4 | .fa-icon() { 5 | display: inline-block; 6 | font: normal normal normal @fa-font-size-base/@fa-line-height-base FontAwesome; // shortening font declaration 7 | font-size: inherit; // can't have font-size inherit on line above, so need to override 8 | text-rendering: auto; // optimizelegibility throws things off #1094 9 | -webkit-font-smoothing: antialiased; 10 | -moz-osx-font-smoothing: grayscale; 11 | 12 | } 13 | 14 | .fa-icon-rotate(@degrees, @rotation) { 15 | -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=@{rotation})"; 16 | -webkit-transform: rotate(@degrees); 17 | -ms-transform: rotate(@degrees); 18 | transform: rotate(@degrees); 19 | } 20 | 21 | .fa-icon-flip(@horiz, @vert, @rotation) { 22 | -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=@{rotation}, mirror=1)"; 23 | -webkit-transform: scale(@horiz, @vert); 24 | -ms-transform: scale(@horiz, @vert); 25 | transform: scale(@horiz, @vert); 26 | } 27 | 28 | 29 | // Only display content to screen readers. A la Bootstrap 4. 30 | // 31 | // See: http://a11yproject.com/posts/how-to-hide-content/ 32 | 33 | .sr-only() { 34 | position: absolute; 35 | width: 1px; 36 | height: 1px; 37 | padding: 0; 38 | margin: -1px; 39 | overflow: hidden; 40 | clip: rect(0,0,0,0); 41 | border: 0; 42 | } 43 | 44 | // Use in conjunction with .sr-only to only display content when it's focused. 45 | // 46 | // Useful for "Skip to main content" links; see http://www.w3.org/TR/2013/NOTE-WCAG20-TECHS-20130905/G1 47 | // 48 | // Credit: HTML5 Boilerplate 49 | 50 | .sr-only-focusable() { 51 | &:active, 52 | &:focus { 53 | position: static; 54 | width: auto; 55 | height: auto; 56 | margin: 0; 57 | overflow: visible; 58 | clip: auto; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /app/src/main/java/com/favorites/domain/Notice.java: -------------------------------------------------------------------------------- 1 | package com.favorites.domain; 2 | 3 | import javax.persistence.*; 4 | import java.io.Serializable; 5 | 6 | /** 7 | * 消息 8 | * 9 | * @author DingYS 10 | * 11 | */ 12 | @Entity 13 | public class Notice extends Entitys implements Serializable { 14 | 15 | private static final long serialVersionUID = 1L; 16 | @Id 17 | @GeneratedValue(strategy= GenerationType.IDENTITY) 18 | private Long id; 19 | @Column(nullable = false) 20 | private Long userId; 21 | @Column(nullable = true) 22 | private String collectId; 23 | @Column(nullable = false) 24 | private String type; 25 | @Column(nullable = true) 26 | private String operId; 27 | @Column(nullable = false) 28 | private String readed; 29 | @Column(nullable = false) 30 | private Long createTime; 31 | 32 | public Notice() { 33 | super(); 34 | } 35 | 36 | public Long getId() { 37 | return id; 38 | } 39 | 40 | public void setId(Long id) { 41 | this.id = id; 42 | } 43 | 44 | public Long getUserId() { 45 | return userId; 46 | } 47 | 48 | public void setUserId(Long userId) { 49 | this.userId = userId; 50 | } 51 | 52 | public String getCollectId() { 53 | return collectId; 54 | } 55 | 56 | public void setCollectId(String collectId) { 57 | this.collectId = collectId; 58 | } 59 | 60 | public String getType() { 61 | return type; 62 | } 63 | 64 | public void setType(String type) { 65 | this.type = type; 66 | } 67 | 68 | public String getOperId() { 69 | return operId; 70 | } 71 | 72 | public void setOperId(String operId) { 73 | this.operId = operId; 74 | } 75 | 76 | public String getReaded() { 77 | return readed; 78 | } 79 | 80 | public void setReaded(String readed) { 81 | this.readed = readed; 82 | } 83 | 84 | public Long getCreateTime() { 85 | return createTime; 86 | } 87 | 88 | public void setCreateTime(Long createTime) { 89 | this.createTime = createTime; 90 | } 91 | 92 | } -------------------------------------------------------------------------------- /app/src/main/resources/static/index/vendor/font-awesome/scss/_mixins.scss: -------------------------------------------------------------------------------- 1 | // Mixins 2 | // -------------------------- 3 | 4 | @mixin fa-icon() { 5 | display: inline-block; 6 | font: normal normal normal #{$fa-font-size-base}/#{$fa-line-height-base} FontAwesome; // shortening font declaration 7 | font-size: inherit; // can't have font-size inherit on line above, so need to override 8 | text-rendering: auto; // optimizelegibility throws things off #1094 9 | -webkit-font-smoothing: antialiased; 10 | -moz-osx-font-smoothing: grayscale; 11 | 12 | } 13 | 14 | @mixin fa-icon-rotate($degrees, $rotation) { 15 | -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=#{$rotation})"; 16 | -webkit-transform: rotate($degrees); 17 | -ms-transform: rotate($degrees); 18 | transform: rotate($degrees); 19 | } 20 | 21 | @mixin fa-icon-flip($horiz, $vert, $rotation) { 22 | -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=#{$rotation}, mirror=1)"; 23 | -webkit-transform: scale($horiz, $vert); 24 | -ms-transform: scale($horiz, $vert); 25 | transform: scale($horiz, $vert); 26 | } 27 | 28 | 29 | // Only display content to screen readers. A la Bootstrap 4. 30 | // 31 | // See: http://a11yproject.com/posts/how-to-hide-content/ 32 | 33 | @mixin sr-only { 34 | position: absolute; 35 | width: 1px; 36 | height: 1px; 37 | padding: 0; 38 | margin: -1px; 39 | overflow: hidden; 40 | clip: rect(0,0,0,0); 41 | border: 0; 42 | } 43 | 44 | // Use in conjunction with .sr-only to only display content when it's focused. 45 | // 46 | // Useful for "Skip to main content" links; see http://www.w3.org/TR/2013/NOTE-WCAG20-TECHS-20130905/G1 47 | // 48 | // Credit: HTML5 Boilerplate 49 | 50 | @mixin sr-only-focusable { 51 | &:active, 52 | &:focus { 53 | position: static; 54 | width: auto; 55 | height: auto; 56 | margin: 0; 57 | overflow: visible; 58 | clip: auto; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /app/src/main/java/com/favorites/repository/BaseNativeSqlRepository.java: -------------------------------------------------------------------------------- 1 | package com.favorites.repository; 2 | 3 | import org.springframework.stereotype.Service; 4 | 5 | import javax.persistence.EntityManager; 6 | import javax.persistence.EntityManagerFactory; 7 | import javax.persistence.PersistenceUnit; 8 | import javax.persistence.Query; 9 | import java.util.List; 10 | 11 | /** 12 | * @Description: JPA使用原生SQL基类 13 | * @Auth: yuyang 14 | * @Date: 2017/1/18 19:30 15 | * @Version: 1.0 16 | **/ 17 | @Service 18 | public class BaseNativeSqlRepository { 19 | 20 | @PersistenceUnit 21 | private EntityManagerFactory emf; 22 | 23 | /** 24 | * 查询多个属性 25 | * 返回List数组形式的List,数组中内容按照查询字段先后 26 | * @param sql 原生SQL语句 27 | * @return 28 | */ 29 | public List sqlArrayList(String sql){ 30 | EntityManager em=emf.createEntityManager(); 31 | Query query=em.createNativeQuery(sql); 32 | List list = query.getResultList(); 33 | em.close(); 34 | return list; 35 | } 36 | 37 | /** 38 | * 查询多个属性 39 | * 返回List对象形式的List,Object为Class格式对象 40 | * @param sql 原生SQL语句 41 | * @param obj Class格式对象 42 | * @return 43 | */ 44 | public List sqlObjectList(String sql, Object obj){ 45 | EntityManager em=emf.createEntityManager(); 46 | Query query=em.createNativeQuery(sql,obj.getClass()); 47 | List list = query.getResultList(); 48 | em.close(); 49 | return list; 50 | } 51 | 52 | /** 53 | * 查询单个属性 54 | * 返回List对象形式的List,Object为对象数据类型 55 | * @param sql 原生SQL语句 56 | * @return 57 | */ 58 | public List sqlSingleList(String sql){ 59 | EntityManager em=emf.createEntityManager(); 60 | Query query=em.createNativeQuery(sql); 61 | List list = query.getResultList(); 62 | em.close(); 63 | return list; 64 | } 65 | 66 | } 67 | -------------------------------------------------------------------------------- /app/src/main/resources/templates/favorites/newfavorites.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
5 |
6 |

新建收藏夹

7 |
8 |
9 |
10 |
11 | 12 |
13 | 14 |
15 |
16 |
17 |
18 |
19 | 20 | 54 | -------------------------------------------------------------------------------- /app/src/main/java/com/favorites/utils/URLUtil.java: -------------------------------------------------------------------------------- 1 | package com.favorites.utils; 2 | 3 | import java.net.HttpURLConnection; 4 | import java.net.URL; 5 | 6 | import org.slf4j.Logger; 7 | import org.slf4j.LoggerFactory; 8 | 9 | public class URLUtil { 10 | 11 | public static Logger logger = LoggerFactory.getLogger(HtmlUtil.class); 12 | 13 | public static synchronized boolean isConnect(String urlStr) { 14 | int counts = 0; 15 | if (urlStr == null || urlStr.length() <= 0) { 16 | return false; 17 | } 18 | while (counts < 3) { 19 | try { 20 | URL url = new URL(urlStr); 21 | HttpURLConnection con = (HttpURLConnection) url.openConnection(); 22 | int state = con.getResponseCode(); 23 | if (state == 200) { 24 | return true; 25 | } 26 | break; 27 | }catch (Exception ex) { 28 | counts++; 29 | continue; 30 | } 31 | } 32 | return false; 33 | } 34 | 35 | public static String getDomainUrl(String urlStr){ 36 | String domainUrl=urlStr; 37 | try { 38 | URL url = new URL(urlStr); 39 | domainUrl=url.getProtocol()+"://"+url.getAuthority(); 40 | } catch (Exception e) { 41 | // TODO: handle exception 42 | logger.error("getDomainUrl is erro,url :"+urlStr, e); 43 | } 44 | return domainUrl; 45 | } 46 | 47 | 48 | public static String getHost(String urlStr){ 49 | String host=urlStr; 50 | try { 51 | URL url = new URL(urlStr); 52 | host=url.getHost(); 53 | } catch (Exception e) { 54 | // TODO: handle exception 55 | logger.error("getHost is erro,url :"+urlStr, e); 56 | } 57 | return host; 58 | } 59 | 60 | 61 | public static void main(String[] args) { 62 | System.out.println(getDomainUrl("http://common.cnblogs.com/favicon.ico")); 63 | } 64 | 65 | } 66 | -------------------------------------------------------------------------------- /app/src/main/java/com/favorites/domain/view/IndexCollectorView.java: -------------------------------------------------------------------------------- 1 | package com.favorites.domain.view; 2 | 3 | import com.favorites.domain.User; 4 | 5 | /** 6 | * @Description: 7 | * @Auth: yuyang 8 | * @Date: 2017/1/19 14:18 9 | * @Version: 1.0 10 | **/ 11 | public class IndexCollectorView { 12 | //收藏文章最多的用户 13 | private User mostCollectUser; 14 | //被关注最多的用户 15 | private User mostFollowedUser; 16 | //文章被赞最多的用户 17 | private User mostPraisedUser; 18 | //文章被评论最多的用户 19 | private User mostCommentedUser; 20 | //最受欢迎的用户 21 | private User mostPopularUser; 22 | //近一个月最活跃用户 23 | private User mostActiveUser; 24 | 25 | public User getMostCollectUser() { 26 | return mostCollectUser; 27 | } 28 | 29 | public void setMostCollectUser(User mostCollectUser) { 30 | this.mostCollectUser = mostCollectUser; 31 | } 32 | 33 | public User getMostFollowedUser() { 34 | return mostFollowedUser; 35 | } 36 | 37 | public void setMostFollowedUser(User mostFollowedUser) { 38 | this.mostFollowedUser = mostFollowedUser; 39 | } 40 | 41 | public User getMostPraisedUser() { 42 | return mostPraisedUser; 43 | } 44 | 45 | public void setMostPraisedUser(User mostPraisedUser) { 46 | this.mostPraisedUser = mostPraisedUser; 47 | } 48 | 49 | public User getMostCommentedUser() { 50 | return mostCommentedUser; 51 | } 52 | 53 | public void setMostCommentedUser(User mostCommentedUser) { 54 | this.mostCommentedUser = mostCommentedUser; 55 | } 56 | 57 | public User getMostPopularUser() { 58 | return mostPopularUser; 59 | } 60 | 61 | public void setMostPopularUser(User mostPopularUser) { 62 | this.mostPopularUser = mostPopularUser; 63 | } 64 | 65 | public User getMostActiveUser() { 66 | return mostActiveUser; 67 | } 68 | 69 | public void setMostActiveUser(User mostActiveUser) { 70 | this.mostActiveUser = mostActiveUser; 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /app/src/main/java/com/favorites/repository/FollowRepository.java: -------------------------------------------------------------------------------- 1 | package com.favorites.repository; 2 | 3 | import java.util.List; 4 | 5 | import javax.transaction.Transactional; 6 | 7 | import org.springframework.data.jpa.repository.JpaRepository; 8 | import org.springframework.data.jpa.repository.Modifying; 9 | import org.springframework.data.jpa.repository.Query; 10 | import org.springframework.data.repository.query.Param; 11 | 12 | import com.favorites.domain.Follow; 13 | import com.favorites.domain.enums.FollowStatus; 14 | 15 | public interface FollowRepository extends JpaRepository { 16 | 17 | @Query("select u.userName from Follow f ,User u where f.userId=:userId and f.followId = u.id and f.status = 'FOLLOW'") 18 | List findByUserId(@Param("userId") Long userId); 19 | 20 | @Query("select f.followId from User u,Follow f where u.id=f.userId and f.status='FOLLOW' and u.id=:userId") 21 | List findMyFollowIdByUserId(@Param("userId") Long userId); 22 | 23 | Integer countByUserIdAndStatus(Long userId,FollowStatus status); 24 | 25 | Integer countByFollowIdAndStatus(Long followId,FollowStatus status); 26 | 27 | @Query("select u.userName , u.introduction ,u.profilePicture ,u.id from Follow f ,User u where f.userId=:userId and f.followId = u.id and f.status = 'FOLLOW'") 28 | List findFollowUserByUserId(@Param("userId") Long userId); 29 | 30 | @Query("select u.userName , u.introduction ,u.profilePicture ,u.id from Follow f,User u where f.followId=:followId and f.userId = u.id and f.status='FOLLOW'") 31 | List findFollowedUserByFollowId(@Param("followId") Long followId); 32 | 33 | Integer countByUserIdAndFollowIdAndStatus(Long userId,Long followId,FollowStatus status); 34 | 35 | Follow findByUserIdAndFollowId(Long userId,Long followId); 36 | 37 | @Modifying(clearAutomatically=true) 38 | @Transactional 39 | @Query("update Follow set status=?1,lastModifyTime=?2 where id=?3") 40 | Integer updateStatusById(FollowStatus status,Long lastModifyTime,Long id); 41 | 42 | } -------------------------------------------------------------------------------- /app/src/main/java/com/favorites/comm/aop/LoggerAdvice.java: -------------------------------------------------------------------------------- 1 | package com.favorites.comm.aop; 2 | 3 | 4 | import org.apache.commons.lang3.builder.ToStringBuilder; 5 | import org.aspectj.lang.JoinPoint; 6 | import org.aspectj.lang.annotation.AfterReturning; 7 | import org.aspectj.lang.annotation.AfterThrowing; 8 | import org.aspectj.lang.annotation.Aspect; 9 | import org.aspectj.lang.annotation.Before; 10 | import org.slf4j.Logger; 11 | import org.slf4j.LoggerFactory; 12 | import org.springframework.stereotype.Service; 13 | 14 | /** 15 | * @Description: 日志管理 16 | * @author Leo Wu 17 | * @date 2016年7月6日 下午5:36:38 18 | * @version 1.0 19 | */ 20 | @Aspect 21 | @Service 22 | public class LoggerAdvice { 23 | 24 | protected Logger logger = LoggerFactory.getLogger(this.getClass()); 25 | 26 | @Before("within(com.favorites..*) && @annotation(loggerManage)") 27 | public void addBeforeLogger(JoinPoint joinPoint, LoggerManage loggerManage) { 28 | logger.info("执行 " + loggerManage.description() + " 开始"); 29 | logger.info(joinPoint.getSignature().toString()); 30 | logger.info(parseParames(joinPoint.getArgs())); 31 | } 32 | 33 | @AfterReturning("within(com.favorites..*) && @annotation(loggerManage)") 34 | public void addAfterReturningLogger(JoinPoint joinPoint, LoggerManage loggerManage) { 35 | logger.info("执行 " + loggerManage.description() + " 结束"); 36 | } 37 | 38 | @AfterThrowing(pointcut = "within(com.favorites..*) && @annotation(loggerManage)", throwing = "ex") 39 | public void addAfterThrowingLogger(JoinPoint joinPoint, LoggerManage loggerManage, Exception ex) { 40 | logger.error("执行 " + loggerManage.description() + " 异常", ex); 41 | } 42 | 43 | private String parseParames(Object[] parames) { 44 | if (null == parames || parames.length <= 0 || parames.length >1024) { 45 | return ""; 46 | } 47 | StringBuffer param = new StringBuffer("传入参数[{}] "); 48 | for (Object obj : parames) { 49 | param.append(ToStringBuilder.reflectionToString(obj)).append(" "); 50 | } 51 | return param.toString(); 52 | } 53 | 54 | } 55 | -------------------------------------------------------------------------------- /app/src/main/java/com/favorites/service/impl/ConfigServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.favorites.service.impl; 2 | 3 | import com.favorites.domain.Config; 4 | import com.favorites.repository.ConfigRepository; 5 | import com.favorites.service.ConfigService; 6 | import com.favorites.utils.DateUtils; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.stereotype.Service; 9 | 10 | @Service("configService") 11 | public class ConfigServiceImpl implements ConfigService{ 12 | 13 | @Autowired 14 | private ConfigRepository configRepository; 15 | 16 | /** 17 | * 保存属性设置 18 | * @param userId 19 | * @param favoritesId 20 | * @return 21 | */ 22 | public Config saveConfig(Long userId,String favoritesId){ 23 | Config config = new Config(); 24 | config.setUserId(userId); 25 | config.setDefaultModel("simple"); 26 | config.setDefaultFavorties(favoritesId); 27 | config.setDefaultCollectType("public"); 28 | config.setCreateTime(DateUtils.getCurrentTime()); 29 | config.setLastModifyTime(DateUtils.getCurrentTime()); 30 | configRepository.save(config); 31 | return config; 32 | } 33 | 34 | /** 35 | * 属性修改 36 | * @param id 37 | * @param type 38 | */ 39 | public void updateConfig(long id ,String type,String defaultFavorites){ 40 | Config config = configRepository.findById(id); 41 | String value=""; 42 | if("defaultCollectType".equals(type)){ 43 | if("public".equals(config.getDefaultCollectType())){ 44 | value = "private"; 45 | }else{ 46 | value = "public"; 47 | } 48 | configRepository.updateCollectTypeById(id, value, DateUtils.getCurrentTime()); 49 | }else if("defaultModel".equals(type)){ 50 | if("simple".equals(config.getDefaultModel())){ 51 | value = "major"; 52 | }else{ 53 | value="simple"; 54 | } 55 | configRepository.updateModelTypeById(id, value, DateUtils.getCurrentTime()); 56 | }else if("defaultFavorites".equals(type)){ 57 | configRepository.updateFavoritesById(id, defaultFavorites, DateUtils.getCurrentTime()); 58 | } 59 | 60 | } 61 | 62 | } 63 | -------------------------------------------------------------------------------- /app/src/main/resources/application-dev.properties: -------------------------------------------------------------------------------- 1 | ###### db config start ###### 2 | spring.datasource.url=jdbc:mysql://127.0.0.1/favorites?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&useSSL=true 3 | spring.datasource.username=root 4 | spring.datasource.password=root 5 | spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver 6 | ###### db config end ###### 7 | 8 | ###### session config start ###### 9 | server.session-timeout=2592000 10 | ###### session config end ###### 11 | 12 | ###### logging config start ###### 13 | logging.file=/usr/local/logs/favorites-web.log 14 | logging.level.com.favorites=INFO 15 | logging.level.org.springframework.web=INFO 16 | logging.level.org.hibernate=INFO 17 | ###### logging config end ###### 18 | 19 | favorites.base.path=http://127.0.0.1:8080/ 20 | forgotpassword.url=http://127.0.0.1:8080/newPassword 21 | 22 | ###### file path begin ###### 23 | static.url=E:\\temp\\ 24 | file.profilepictures.url=profilepictures/ 25 | file.backgroundpictures.url=backgroundpictures/ 26 | ###### file path end ###### 27 | 28 | 29 | ##### mail setting begin ##### 30 | #\u90AE\u4EF6\u914D\u7F6E 31 | spring.mail.host=smtp.126.com 32 | spring.mail.username=cloudfavorites@126.com 33 | spring.mail.password=ritesxxx123 34 | spring.mail.port=465 35 | 36 | #\u767B\u5F55\u670D\u52A1\u5668\u662F\u5426\u9700\u8981\u8BA4\u8BC1 37 | spring.mail.properties.mail.smtp.auth=true 38 | #SSL\u8BC1\u4E66Socket\u5DE5\u5382 39 | spring.mail.properties.mail.smtp.socketFactory.class=javax.net.ssl.SSLSocketFactory 40 | #\u4F7F\u7528SMTPS\u534F\u8BAE465\u7AEF\u53E3 41 | spring.mail.properties.mail.smtp.socketFactory.port=465 42 | 43 | #\u663E\u793A\u5728\u6536\u4EF6\u4EBA\u90AE\u7BB1\u91CC\u9762\u7684\u53D1\u4EF6\u4EBA\u540D\u79F0 44 | spring.mail.self.username=\u4E91\u6536\u85CF 45 | 46 | mail.subject.forgotpassword=\u5BC6\u7801\u91CD\u7F6E\u90AE\u4EF6 47 | mail.content.forgotpassword=\u8BF7\u70B9\u51FB\u4EE5\u4E0B\u5730\u5740:
\u91CD\u7F6E\u5BC6\u7801 48 | ##### mail setting end ##### 49 | 50 | spring.thymeleaf.cache=false -------------------------------------------------------------------------------- /app/src/main/java/com/favorites/domain/Follow.java: -------------------------------------------------------------------------------- 1 | package com.favorites.domain; 2 | 3 | import java.io.Serializable; 4 | 5 | import javax.persistence.*; 6 | 7 | import com.favorites.domain.enums.FollowStatus; 8 | 9 | 10 | /** 11 | * 关注 12 | * 13 | * @author DingYS 14 | * 15 | */ 16 | @Entity 17 | public class Follow extends Entitys implements Serializable { 18 | 19 | private static final long serialVersionUID = 1L; 20 | @Id 21 | @GeneratedValue(strategy= GenerationType.IDENTITY) 22 | private Long id; 23 | @Column(nullable = false) 24 | private Long userId; 25 | @Column(nullable = false) 26 | private Long followId; 27 | @Column(nullable = false) 28 | @Enumerated(EnumType.STRING) 29 | private FollowStatus status; 30 | @Column(nullable = false) 31 | private Long createTime; 32 | @Column(nullable = false) 33 | private Long lastModifyTime; 34 | @Transient 35 | private String name; 36 | 37 | public Follow() { 38 | super(); 39 | } 40 | 41 | public Long getId() { 42 | return id; 43 | } 44 | 45 | public void setId(Long id) { 46 | this.id = id; 47 | } 48 | 49 | public Long getUserId() { 50 | return userId; 51 | } 52 | 53 | public void setUserId(Long userId) { 54 | this.userId = userId; 55 | } 56 | 57 | public Long getFollowId() { 58 | return followId; 59 | } 60 | 61 | public void setFollowId(Long followId) { 62 | this.followId = followId; 63 | } 64 | 65 | public Long getCreateTime() { 66 | return createTime; 67 | } 68 | 69 | public void setCreateTime(Long createTime) { 70 | this.createTime = createTime; 71 | } 72 | 73 | public FollowStatus getStatus() { 74 | return status; 75 | } 76 | 77 | public void setStatus(FollowStatus status) { 78 | this.status = status; 79 | } 80 | 81 | public Long getLastModifyTime() { 82 | return lastModifyTime; 83 | } 84 | 85 | public void setLastModifyTime(Long lastModifyTime) { 86 | this.lastModifyTime = lastModifyTime; 87 | } 88 | 89 | public String getName() { 90 | return name; 91 | } 92 | 93 | public void setName(String name) { 94 | this.name = name; 95 | } 96 | 97 | 98 | } -------------------------------------------------------------------------------- /app/src/main/resources/application-docker.properties: -------------------------------------------------------------------------------- 1 | ###### db config start ###### 2 | spring.datasource.url=jdbc:mysql://mysql:3306/favorites?useUnicode=true&characterEncoding=utf-8 3 | spring.datasource.username=root 4 | spring.datasource.password=root 5 | spring.datasource.driver-class-name=com.mysql.jdbc.Driver 6 | spring.datasource.hikari.connectionInitSql=SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci; 7 | spring.datasource.max-active=20 8 | spring.datasource.max-idle=30 9 | spring.datasource.min-idle=6 10 | spring.datasource.initial-size=10 11 | ###### db config end ###### 12 | 13 | ###### logging config start ###### 14 | logging.file=/usr/local/logs/favorites-web.log 15 | logging.level.com.favorites=INFO 16 | logging.level.org.springframework.web=INFO 17 | logging.level.org.hibernate=in 18 | ###### logging config end ###### 19 | 20 | favorites.base.path=http://192.168.0.54/ 21 | 22 | ###### file path begin ###### 23 | static.url=/usr/share/nginx/html/ 24 | file.profilepictures.url=profilepictures/ 25 | file.backgroundpictures.url=backgroundpictures/ 26 | ###### file path end ###### 27 | 28 | 29 | ##### mail setting begin ##### 30 | #\u90AE\u4EF6\u914D\u7F6E 31 | spring.mail.host=smtp.126.com 32 | spring.mail.username=cloudfavorites@126.com 33 | spring.mail.password= 34 | spring.mail.port=465 35 | 36 | #\u767B\u5F55\u670D\u52A1\u5668\u662F\u5426\u9700\u8981\u8BA4\u8BC1 37 | spring.mail.properties.mail.smtp.auth=true 38 | #SSL\u8BC1\u4E66Socket\u5DE5\u5382 39 | spring.mail.properties.mail.smtp.socketFactory.class=javax.net.ssl.SSLSocketFactory 40 | #\u4F7F\u7528SMTPS\u534F\u8BAE465\u7AEF\u53E3 41 | spring.mail.properties.mail.smtp.socketFactory.port=465 42 | 43 | #\u663E\u793A\u5728\u6536\u4EF6\u4EBA\u90AE\u7BB1\u91CC\u9762\u7684\u53D1\u4EF6\u4EBA\u540D\u79F0 44 | spring.mail.self.username=\u4E91\u6536\u85CF 45 | 46 | mail.subject.forgotpassword=\u5BC6\u7801\u91CD\u7F6E\u90AE\u4EF6 47 | mail.content.forgotpassword=\u8BF7\u70B9\u51FB\u4EE5\u4E0B\u5730\u5740:
\u91CD\u7F6E\u5BC6\u7801 48 | ##### mail setting end ##### 49 | 50 | spring.thymeleaf.cache=true -------------------------------------------------------------------------------- /app/src/main/java/com/favorites/cache/CacheService.java: -------------------------------------------------------------------------------- 1 | package com.favorites.cache; 2 | 3 | import com.favorites.domain.UrlLibrary; 4 | import com.favorites.repository.UrlLibraryRepository; 5 | import com.favorites.utils.HtmlUtil; 6 | import org.apache.commons.lang3.StringUtils; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.stereotype.Component; 9 | 10 | import java.util.HashMap; 11 | import java.util.List; 12 | import java.util.Map; 13 | import java.util.concurrent.ConcurrentHashMap; 14 | 15 | /** 16 | * Created by DingYS on 2016/12/29. 17 | */ 18 | @Component 19 | public class CacheService { 20 | 21 | private Map maps = new ConcurrentHashMap<>(); 22 | @Autowired 23 | private UrlLibraryRepository urlLibraryRepository; 24 | 25 | public String getMap(String key){ 26 | if(maps.isEmpty()){ 27 | List collectLibrarieList = urlLibraryRepository.findAll(); 28 | for(UrlLibrary urlLibrary : collectLibrarieList){ 29 | maps.put(urlLibrary.getUrl(), urlLibrary.getLogoUrl()); 30 | } 31 | } 32 | if(null == maps.get(key)){ 33 | this.addMaps(key); 34 | } 35 | return maps.get(key); 36 | } 37 | 38 | 39 | public void addMaps(String key){ 40 | if(key.contains("?")){ 41 | key=key.substring(0,key.indexOf("?")); 42 | } 43 | String logoUrl = HtmlUtil.getImge(key); 44 | maps.put(key,logoUrl); 45 | UrlLibrary urlLibrary = new UrlLibrary(); 46 | urlLibrary.setUrl(key); 47 | urlLibrary.setLogoUrl(logoUrl); 48 | urlLibraryRepository.save(urlLibrary); 49 | } 50 | 51 | public boolean refreshOne(String key,String newValue){ 52 | if(StringUtils.isNotBlank(key)){ 53 | String value = getMap(key); 54 | if(StringUtils.isNotBlank(newValue) && !newValue.equals(value)){ 55 | maps.put(key,newValue); 56 | return true; 57 | } 58 | } 59 | return false; 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /app/src/main/java/com/favorites/repository/LookRecordRepository.java: -------------------------------------------------------------------------------- 1 | package com.favorites.repository; 2 | 3 | import com.favorites.domain.LookRecord; 4 | import com.favorites.domain.view.CollectView; 5 | import org.springframework.data.domain.Page; 6 | import org.springframework.data.domain.Pageable; 7 | import org.springframework.data.jpa.repository.JpaRepository; 8 | import org.springframework.data.jpa.repository.Modifying; 9 | import org.springframework.data.jpa.repository.Query; 10 | import org.springframework.data.repository.query.Param; 11 | 12 | import javax.transaction.Transactional; 13 | 14 | /** 15 | * 浏览记录Repository 16 | * Created by chenzhimin on 2017/1/5. 17 | */ 18 | public interface LookRecordRepository extends JpaRepository { 19 | 20 | /** 21 | * 查询用户浏览历史记录 22 | */ 23 | public String userLookRecordSql = "select c.id as id,c.title as title, c.type as type,c.url as url,c.logoUrl as logoUrl,c.userId as userId, " 24 | + "c.remark as remark,c.description as description,c.lastModifyTime as lastModifyTime,r.lastModifyTime as createTime, " 25 | + "u.userName as userName,u.profilePicture as profilePicture,f.id as favoritesId,f.name as favoriteName " 26 | + "from LookRecord r,Collect c,User u,Favorites f " 27 | + "WHERE c.userId = u.id and r.collectId = c.id and c.favoritesId=f.id and c.isDelete='NO'"; 28 | 29 | @Query(userLookRecordSql+ " and r.userId=?1") 30 | Page findViewByUserId(Long userId, Pageable pageable); 31 | 32 | Integer countByUserIdAndCollectId(Long userId, Long collectId); 33 | 34 | @Modifying(clearAutomatically=true) 35 | @Transactional 36 | @Query("update LookRecord set lastModifyTime=:lastModifyTime where userId=:userId and collectId=:collectId") 37 | void updatelastModifyTime(@Param("userId") Long userId, @Param("collectId") Long collectId, @Param("lastModifyTime") Long lastModifyTime); 38 | 39 | @Transactional 40 | Long deleteByUserIdAndCollectId(Long userId,Long collectId); 41 | 42 | @Transactional 43 | Long deleteByUserId(Long userId); 44 | } 45 | -------------------------------------------------------------------------------- /app/src/test/java/com/favorites/FavoritesApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.favorites; 2 | 3 | import static org.assertj.core.api.Assertions.assertThat; 4 | import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; 5 | import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; 6 | import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; 7 | 8 | import java.lang.management.ManagementFactory; 9 | 10 | import javax.management.ObjectName; 11 | 12 | import org.junit.Before; 13 | import org.junit.Test; 14 | import org.junit.runner.RunWith; 15 | import org.springframework.beans.factory.annotation.Autowired; 16 | import org.springframework.boot.test.context.SpringBootTest; 17 | import org.springframework.test.context.ActiveProfiles; 18 | import org.springframework.test.context.TestPropertySource; 19 | import org.springframework.test.context.junit4.SpringRunner; 20 | import org.springframework.test.web.servlet.MockMvc; 21 | import org.springframework.test.web.servlet.setup.MockMvcBuilders; 22 | import org.springframework.web.context.WebApplicationContext; 23 | 24 | @RunWith(SpringRunner.class) 25 | @SpringBootTest 26 | // Enable JMX so we can test the MBeans (you can't do this in a properties file) 27 | @TestPropertySource(properties = { "spring.jmx.enabled:true", 28 | "spring.datasource.jmx-enabled:true" }) 29 | @ActiveProfiles("scratch") 30 | public class FavoritesApplicationTests { 31 | 32 | @Autowired 33 | private WebApplicationContext context; 34 | 35 | private MockMvc mvc; 36 | 37 | @Before 38 | public void setUp() { 39 | this.mvc = MockMvcBuilders.webAppContextSetup(this.context).build(); 40 | } 41 | 42 | @Test 43 | public void testHome() throws Exception { 44 | 45 | this.mvc.perform(get("/")).andExpect(status().isOk()) 46 | .andExpect(content().string("Bath")); 47 | } 48 | 49 | @Test 50 | public void testJmx() throws Exception { 51 | assertThat(ManagementFactory.getPlatformMBeanServer() 52 | .queryMBeans(new ObjectName("jpa.sample:type=ConnectionPool,*"), null)) 53 | .hasSize(1); 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /app/src/main/resources/static/vendor/scrollable/scrollable.css: -------------------------------------------------------------------------------- 1 | .scrollable { 2 | position: relative; 3 | z-index: 1; 4 | margin: 0; 5 | padding: 0; 6 | } 7 | 8 | .scrollable .scrollbar, 9 | .scrollable .scrollbar .handle-container, 10 | .scrollable .scrollbar .handle-container .handle { 11 | position: absolute; 12 | display: block; 13 | } 14 | 15 | .scrollable .scrollable-container .scrollable-area { 16 | position: relative; 17 | padding: 0; 18 | margin: 0; 19 | width: auto; 20 | height: auto; 21 | } 22 | 23 | .scrollable .scrollbar { 24 | background-color: rgba(0,0,0,0.2); 25 | z-index: 5; 26 | } 27 | 28 | .scrollable .scrollbar .handle { 29 | background-color: #333; 30 | border-radius: 5px; 31 | cursor: default; 32 | z-index: 6; 33 | } 34 | 35 | .scrollable .scrollbar .handle-container { 36 | top: 0; 37 | bottom: 0; 38 | left: 0; 39 | right: 0; 40 | } 41 | 42 | .scrollable .scrollbar.scrollbar-x { 43 | bottom: 0; 44 | left: 0; 45 | right: 0; 46 | height: 14px; 47 | } 48 | 49 | .scrollable .scrollbar.scrollbar-y { 50 | top: 0; 51 | bottom: 0; 52 | right: 0; 53 | width: 14px; 54 | } 55 | 56 | .scrollable .scrollbar.scrollbar-x .handle-container { 57 | left: 2px; 58 | right: 2px; 59 | } 60 | 61 | .scrollable .scrollbar.scrollbar-y .handle-container { 62 | top: 2px; 63 | bottom: 2px; 64 | } 65 | 66 | .scrollable .scrollbar.scrollbar-x .handle-container .handle { 67 | height: 10px; 68 | margin: 2px 0; 69 | } 70 | 71 | .scrollable .scrollbar.scrollbar-y .handle-container .handle { 72 | width: 10px; 73 | margin: 0 2px; 74 | } 75 | 76 | .scrollable .scrollbar.scrollbar-x.corner .handle-container { 77 | right: 16px; 78 | } 79 | 80 | .scrollable .scrollbar.scrollbar-y.corner .handle-container { 81 | bottom: 16px; 82 | } 83 | 84 | .scrollable.autohide > .scrollbar { 85 | filter : alpha(opacity=0); 86 | opacity : 0; 87 | } 88 | 89 | .scrollable.scrolling.autohide > .scrollbar, 90 | .scrollable.autohide.hover > .scrollbar { 91 | filter : alpha(opacity=100); 92 | opacity : 1; 93 | } -------------------------------------------------------------------------------- /app/src/main/java/com/favorites/domain/Favorites.java: -------------------------------------------------------------------------------- 1 | package com.favorites.domain; 2 | 3 | import java.io.Serializable; 4 | 5 | import javax.persistence.*; 6 | 7 | /** 8 | * 收藏夹 9 | * @author DingYS 10 | * 11 | */ 12 | @Entity 13 | public class Favorites extends Entitys implements Serializable { 14 | 15 | private static final long serialVersionUID = 1L; 16 | @Id 17 | @GeneratedValue(strategy= GenerationType.IDENTITY) 18 | private Long id; 19 | @Column(nullable = false) 20 | private Long userId; 21 | @Column(nullable = false) 22 | private String name; 23 | @Column(nullable = false) 24 | private Long count; 25 | @Column(nullable = false) 26 | private Long createTime; 27 | @Column(nullable = false) 28 | private Long lastModifyTime; 29 | @Column(nullable = false) 30 | private Long publicCount; 31 | 32 | public Long getPublicCount() { 33 | return publicCount; 34 | } 35 | public void setPublicCount(Long publicCount) { 36 | this.publicCount = publicCount; 37 | } 38 | public Long getId() { 39 | return id; 40 | } 41 | public void setId(Long id) { 42 | this.id = id; 43 | } 44 | public Long getUserId() { 45 | return userId; 46 | } 47 | public void setUserId(Long userId) { 48 | this.userId = userId; 49 | } 50 | public String getName() { 51 | return name; 52 | } 53 | public void setName(String name) { 54 | this.name = name; 55 | } 56 | public Long getCount() { 57 | return count; 58 | } 59 | public void setCount(Long count) { 60 | this.count = count; 61 | } 62 | public Long getCreateTime() { 63 | return createTime; 64 | } 65 | public void setCreateTime(Long createTime) { 66 | this.createTime = createTime; 67 | } 68 | public Long getLastModifyTime() { 69 | return lastModifyTime; 70 | } 71 | public void setLastModifyTime(Long lastModifyTime) { 72 | this.lastModifyTime = lastModifyTime; 73 | } 74 | 75 | @Override 76 | public String toString() { 77 | return "Favorites{" + 78 | "id=" + id + 79 | ", userId=" + userId + 80 | ", name='" + name + '\'' + 81 | ", count=" + count + 82 | ", createTime=" + createTime + 83 | ", lastModifyTime=" + lastModifyTime + 84 | ", publicCount=" + publicCount + 85 | '}'; 86 | } 87 | } -------------------------------------------------------------------------------- /app/src/main/java/com/favorites/domain/Feedback.java: -------------------------------------------------------------------------------- 1 | package com.favorites.domain; 2 | 3 | import javax.persistence.*; 4 | import java.io.Serializable; 5 | 6 | /** 7 | * 用户反馈javaBean类 8 | * Created by chenzhimin on 2017/2/23. 9 | */ 10 | @Entity 11 | public class Feedback extends Entitys implements Serializable { 12 | 13 | private static final long serialVersionUID = 1L; 14 | 15 | @Id 16 | @GeneratedValue(strategy= GenerationType.IDENTITY) 17 | private Long id; 18 | @Column(nullable = true) 19 | private Long userId; 20 | @Column(nullable = false) 21 | private String feedbackAdvice; 22 | @Column(nullable = true) 23 | private String feedbackName; 24 | @Column(nullable = false) 25 | private String phone; 26 | @Column(nullable = false) 27 | private Long createTime; 28 | @Column(nullable = false) 29 | private Long lastModifyTime; 30 | 31 | public Long getId() { 32 | return id; 33 | } 34 | 35 | public void setId(Long id) { 36 | this.id = id; 37 | } 38 | 39 | public String getPhone() { 40 | return phone; 41 | } 42 | 43 | public void setPhone(String phone) { 44 | this.phone = phone; 45 | } 46 | 47 | public Long getCreateTime() { 48 | return createTime; 49 | } 50 | 51 | public void setCreateTime(Long createTime) { 52 | this.createTime = createTime; 53 | } 54 | 55 | public Long getLastModifyTime() { 56 | return lastModifyTime; 57 | } 58 | 59 | public void setLastModifyTime(Long lastModifyTime) { 60 | this.lastModifyTime = lastModifyTime; 61 | } 62 | 63 | public Long getUserId() { 64 | return userId; 65 | } 66 | 67 | public void setUserId(Long userId) { 68 | this.userId = userId; 69 | } 70 | 71 | public String getFeedbackAdvice() { 72 | return feedbackAdvice; 73 | } 74 | 75 | public void setFeedbackAdvice(String feedbackAdvice) { 76 | this.feedbackAdvice = feedbackAdvice; 77 | } 78 | 79 | public String getFeedbackName() { 80 | return feedbackName; 81 | } 82 | 83 | public void setFeedbackName(String feedbackName) { 84 | this.feedbackName = feedbackName; 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /app/src/main/java/com/favorites/web/LetterController.java: -------------------------------------------------------------------------------- 1 | package com.favorites.web; 2 | 3 | import com.favorites.comm.aop.LoggerManage; 4 | import com.favorites.domain.Letter; 5 | import com.favorites.domain.result.ExceptionMsg; 6 | import com.favorites.domain.result.Response; 7 | import com.favorites.domain.view.LetterSummary; 8 | import com.favorites.service.LetterService; 9 | import org.springframework.data.domain.PageRequest; 10 | import org.springframework.data.domain.Pageable; 11 | import org.springframework.data.domain.Sort; 12 | import org.springframework.web.bind.annotation.RequestMapping; 13 | import org.springframework.web.bind.annotation.RequestParam; 14 | import org.springframework.web.bind.annotation.RestController; 15 | 16 | import javax.annotation.Resource; 17 | import java.util.List; 18 | 19 | /** 20 | * Created by DingYS on 2017/3/7. 21 | * 私信Controller 22 | */ 23 | @RestController 24 | @RequestMapping("/letter") 25 | public class LetterController extends BaseController { 26 | 27 | @Resource 28 | private LetterService letterService; 29 | 30 | /** 31 | * 发送私信 32 | * @param letter 33 | * @return 34 | */ 35 | @RequestMapping("/sendLetter") 36 | @LoggerManage(description = "发送私信") 37 | public Response sendLetter(Letter letter){ 38 | try { 39 | letter.setSendUserId(getUserId()); 40 | letterService.sendLetter(letter); 41 | }catch (Exception e){ 42 | logger.error("发送私信异常:",e); 43 | return result(ExceptionMsg.FAILED); 44 | } 45 | return result(); 46 | } 47 | 48 | /** 49 | * 私信列表获取 50 | * @param page 51 | * @param size 52 | * @return 53 | */ 54 | @RequestMapping("/getLetterList") 55 | @LoggerManage(description = "获取私信列表") 56 | public List getLetterList(@RequestParam(value = "page", defaultValue = "0") Integer page, 57 | @RequestParam(value = "size", defaultValue = "15") Integer size){ 58 | Sort sort = new Sort(Sort.Direction.DESC, "id"); 59 | Pageable pageable = PageRequest.of(page, size,sort); 60 | List letterList = letterService.findLetter(getUserId(),pageable); 61 | return letterList; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /app/src/main/java/com/favorites/domain/Letter.java: -------------------------------------------------------------------------------- 1 | package com.favorites.domain; 2 | 3 | import com.favorites.domain.enums.LetterType; 4 | 5 | import javax.persistence.*; 6 | import java.io.Serializable; 7 | 8 | /** 9 | * 私信 10 | * 11 | * @author DingYS 12 | * 13 | */ 14 | @Entity 15 | public class Letter extends Entitys implements Serializable { 16 | 17 | private static final long serialVersionUID = 1L; 18 | @Id 19 | @GeneratedValue(strategy= GenerationType.IDENTITY) 20 | private Long id; 21 | @Column(nullable = false) 22 | private Long sendUserId; 23 | @Column(nullable = false, length = 65535, columnDefinition = "Text") 24 | private String content; 25 | @Column(nullable = false) 26 | private Long receiveUserId; 27 | @Column(nullable = true) 28 | private Long pid; 29 | @Enumerated(EnumType.STRING) 30 | @Column(nullable = true) 31 | private LetterType type; 32 | @Column(nullable = false) 33 | private Long createTime; 34 | @Transient 35 | private String sendType; 36 | 37 | 38 | public Letter() { 39 | super(); 40 | } 41 | 42 | public String getSendType() { 43 | return sendType; 44 | } 45 | 46 | public void setSendType(String sendType) { 47 | this.sendType = sendType; 48 | } 49 | 50 | public Long getId() { 51 | return id; 52 | } 53 | 54 | public void setId(Long id) { 55 | this.id = id; 56 | } 57 | 58 | public Long getSendUserId() { 59 | return sendUserId; 60 | } 61 | 62 | public void setSendUserId(Long sendUserId) { 63 | this.sendUserId = sendUserId; 64 | } 65 | 66 | public String getContent() { 67 | return content; 68 | } 69 | 70 | public void setContent(String content) { 71 | this.content = content; 72 | } 73 | 74 | public Long getReceiveUserId() { 75 | return receiveUserId; 76 | } 77 | 78 | public void setReceiveUserId(Long receiveUserId) { 79 | this.receiveUserId = receiveUserId; 80 | } 81 | 82 | public Long getPid() { 83 | return pid; 84 | } 85 | 86 | public void setPid(Long pid) { 87 | this.pid = pid; 88 | } 89 | 90 | public LetterType getType() { 91 | return type; 92 | } 93 | 94 | public void setType(LetterType type) { 95 | this.type = type; 96 | } 97 | 98 | public Long getCreateTime() { 99 | return createTime; 100 | } 101 | 102 | public void setCreateTime(Long createTime) { 103 | this.createTime = createTime; 104 | } 105 | } -------------------------------------------------------------------------------- /app/src/main/java/com/favorites/domain/view/LetterSummary.java: -------------------------------------------------------------------------------- 1 | package com.favorites.domain.view; 2 | 3 | import com.favorites.utils.DateUtils; 4 | 5 | import java.io.Serializable; 6 | 7 | /** 8 | * Created by DingYS on 2017/3/8. 9 | */ 10 | public class LetterSummary implements Serializable{ 11 | 12 | private static final long serialVersionUID = 1L; 13 | 14 | private Long id; 15 | private Long sendUserId; 16 | private String sendUserName; 17 | private String profilePicture; 18 | private String content; 19 | private String createTime; 20 | private Long pid; 21 | private String type; 22 | 23 | public LetterSummary(LetterView view){ 24 | this.id = view.getId(); 25 | this.sendUserId = view.getSendUserId(); 26 | this.sendUserName = view.getSendUserName(); 27 | this.profilePicture = view.getProfilePicture(); 28 | this.content = view.getContent(); 29 | this.createTime = DateUtils.getTimeFormatText(view.getCreateTime()); 30 | this.pid = view.getPid(); 31 | this.type = view.getType(); 32 | } 33 | 34 | public String getType() { 35 | return type; 36 | } 37 | 38 | public void setType(String type) { 39 | this.type = type; 40 | } 41 | 42 | public Long getId() { 43 | return id; 44 | } 45 | 46 | public void setId(Long id) { 47 | this.id = id; 48 | } 49 | 50 | public Long getSendUserId() { 51 | return sendUserId; 52 | } 53 | 54 | public void setSendUserId(Long sendUserId) { 55 | this.sendUserId = sendUserId; 56 | } 57 | 58 | public String getSendUserName() { 59 | return sendUserName; 60 | } 61 | 62 | public void setSendUserName(String sendUserName) { 63 | this.sendUserName = sendUserName; 64 | } 65 | 66 | public String getProfilePicture() { 67 | return profilePicture; 68 | } 69 | 70 | public void setProfilePicture(String profilePicture) { 71 | this.profilePicture = profilePicture; 72 | } 73 | 74 | public String getContent() { 75 | return content; 76 | } 77 | 78 | public void setContent(String content) { 79 | this.content = content; 80 | } 81 | 82 | public String getCreateTime() { 83 | return createTime; 84 | } 85 | 86 | public void setCreateTime(String createTime) { 87 | this.createTime = createTime; 88 | } 89 | 90 | public Long getPid() { 91 | return pid; 92 | } 93 | 94 | public void setPid(Long pid) { 95 | this.pid = pid; 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /app/src/main/java/com/favorites/service/impl/FavoritesServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.favorites.service.impl; 2 | 3 | import com.favorites.domain.Collect; 4 | import com.favorites.domain.enums.CollectType; 5 | import com.favorites.domain.enums.IsDelete; 6 | import com.favorites.repository.CollectRepository; 7 | import org.slf4j.Logger; 8 | import org.slf4j.LoggerFactory; 9 | import org.springframework.beans.factory.annotation.Autowired; 10 | import org.springframework.stereotype.Service; 11 | 12 | import com.favorites.domain.Favorites; 13 | import com.favorites.repository.FavoritesRepository; 14 | import com.favorites.service.FavoritesService; 15 | import com.favorites.utils.DateUtils; 16 | 17 | @Service("favoritesService") 18 | public class FavoritesServiceImpl implements FavoritesService{ 19 | protected Logger logger = LoggerFactory.getLogger(this.getClass()); 20 | 21 | @Autowired 22 | private FavoritesRepository favoritesRepository; 23 | @Autowired 24 | private CollectRepository collectRepository; 25 | 26 | @Override 27 | public Favorites saveFavorites(Long userId, String name) { 28 | Favorites favorites = new Favorites(); 29 | favorites.setName(name); 30 | favorites.setUserId(userId); 31 | favorites.setCount(0l); 32 | favorites.setPublicCount(10l); 33 | favorites.setCreateTime(DateUtils.getCurrentTime()); 34 | favorites.setLastModifyTime(DateUtils.getCurrentTime()); 35 | favoritesRepository.save(favorites); 36 | return favorites; 37 | } 38 | 39 | /** 40 | * 保存 41 | * @return 42 | */ 43 | public Favorites saveFavorites(Collect collect){ 44 | Favorites favorites = new Favorites(); 45 | favorites.setName(collect.getNewFavorites()); 46 | favorites.setUserId(collect.getUserId()); 47 | favorites.setCount(1l); 48 | if(CollectType.PUBLIC.name().equals(collect.getType())){ 49 | favorites.setPublicCount(1l); 50 | }else { 51 | favorites.setPublicCount(10l); 52 | } 53 | favorites.setCreateTime(DateUtils.getCurrentTime()); 54 | favorites.setLastModifyTime(DateUtils.getCurrentTime()); 55 | favoritesRepository.save(favorites); 56 | return favorites; 57 | } 58 | 59 | 60 | public void countFavorites(long id){ 61 | Favorites favorite=favoritesRepository.findById(id); 62 | Long count=collectRepository.countByFavoritesIdAndIsDelete(id, IsDelete.NO); 63 | favorite.setCount(count); 64 | Long pubCount=collectRepository.countByFavoritesIdAndTypeAndIsDelete(id, CollectType.PUBLIC, IsDelete.NO); 65 | favorite.setPublicCount(pubCount); 66 | favorite.setLastModifyTime(DateUtils.getCurrentTime()); 67 | favoritesRepository.save(favorite); 68 | 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /app/src/main/java/com/favorites/utils/DateUtils.java: -------------------------------------------------------------------------------- 1 | package com.favorites.utils; 2 | 3 | import java.text.SimpleDateFormat; 4 | import java.util.Date; 5 | 6 | public class DateUtils { 7 | 8 | private final static long minute = 60 * 1000;// 1分钟 9 | private final static long hour = 60 * minute;// 1小时 10 | private final static long day = 24 * hour;// 1天 11 | private final static long month = 31 * day;// 月 12 | private final static long year = 12 * month;// 年 13 | 14 | public final static String YYYYMMDDHHMMSS = "yyyyMMddHHmmssSSS"; 15 | 16 | /** 17 | * @return 18 | * @author neo 19 | * @date 2015-5-21 20 | */ 21 | public static String getDateSequence() { 22 | return new SimpleDateFormat(YYYYMMDDHHMMSS).format(new Date()); 23 | } 24 | 25 | 26 | /** 27 | * @author neo 28 | * @date 2016年8月10日 29 | * @return 30 | */ 31 | public static long getCurrentTime() { 32 | return System.currentTimeMillis(); 33 | } 34 | 35 | 36 | public static String getTimeFormatText(Long date) { 37 | if (date == null) { 38 | return null; 39 | } 40 | long diff = new Date().getTime() - date; 41 | long r = 0; 42 | if (diff > year) { 43 | r = (diff / year); 44 | return r + "年前"; 45 | } 46 | if (diff > month) { 47 | r = (diff / month); 48 | return r + "个月前"; 49 | } 50 | if (diff > day) { 51 | r = (diff / day); 52 | return r + "天前"; 53 | } 54 | if (diff > hour) { 55 | r = (diff / hour); 56 | return r + "个小时前"; 57 | } 58 | if (diff > minute) { 59 | r = (diff / minute); 60 | return r + "分钟前"; 61 | } 62 | return "刚刚"; 63 | } 64 | 65 | /** 66 | * 将时间戳转换成当天0点 67 | * @param timestamp 68 | * @return 69 | */ 70 | public static long getDayBegin(long timestamp) { 71 | String format = "yyyy-MM-DD"; 72 | String toDayString = new SimpleDateFormat(format).format(new Date(timestamp)); 73 | Date toDay = null; 74 | try { 75 | toDay = org.apache.commons.lang3.time.DateUtils.parseDate(toDayString, new String[]{format}); 76 | 77 | } catch (Exception e) { 78 | throw new RuntimeException(e); 79 | } 80 | return toDay.getTime(); 81 | } 82 | 83 | /** 84 | * 获取一个月之前的时间戳 85 | * @return 86 | */ 87 | public static long getLastMonthTime() { 88 | return getDayBegin(getCurrentTime())-86400000l*30; 89 | } 90 | 91 | } 92 | -------------------------------------------------------------------------------- /app/src/main/java/com/favorites/repository/UserRepository.java: -------------------------------------------------------------------------------- 1 | package com.favorites.repository; 2 | 3 | import javax.transaction.Transactional; 4 | 5 | import com.favorites.domain.enums.CollectType; 6 | import com.favorites.domain.view.CollectView; 7 | import org.springframework.data.domain.Page; 8 | import org.springframework.data.domain.Pageable; 9 | import org.springframework.data.jpa.repository.JpaRepository; 10 | import org.springframework.data.jpa.repository.Modifying; 11 | import org.springframework.data.jpa.repository.Query; 12 | import org.springframework.data.repository.query.Param; 13 | 14 | import com.favorites.domain.User; 15 | 16 | import java.util.List; 17 | 18 | public interface UserRepository extends JpaRepository { 19 | 20 | User findByUserName(String userName); 21 | 22 | User findByUserNameOrEmail(String username, String email); 23 | 24 | User findByEmail(String email); 25 | 26 | User findById(long id); 27 | 28 | @Modifying(clearAutomatically=true) 29 | @Transactional 30 | @Query("update User set outDate=:outDate, validataCode=:validataCode where email=:email") 31 | int setOutDateAndValidataCode(@Param("outDate") String outDate, @Param("validataCode") String validataCode, @Param("email") String email); 32 | 33 | @Modifying(clearAutomatically=true) 34 | @Transactional 35 | @Query("update User set passWord=:passWord where email=:email") 36 | int setNewPassword(@Param("passWord") String passWord, @Param("email") String email); 37 | 38 | @Modifying(clearAutomatically=true) 39 | @Transactional 40 | @Query("update User set introduction=:introduction where email=:email") 41 | int setIntroduction(@Param("introduction") String introduction, @Param("email") String email); 42 | 43 | @Modifying(clearAutomatically=true) 44 | @Transactional 45 | @Query("update User set userName=:userName where email=:email") 46 | int setUserName(@Param("userName") String userName, @Param("email") String email); 47 | 48 | @Modifying(clearAutomatically=true) 49 | @Transactional 50 | @Query("update User set profilePicture=:profilePicture where id=:id") 51 | int setProfilePicture(@Param("profilePicture") String profilePicture, @Param("id") Long id); 52 | 53 | // @Query("from User u where u.name=:name") 54 | // User findUser(@Param("name") String name); 55 | 56 | @Modifying(clearAutomatically=true) 57 | @Transactional 58 | @Query("update User set backgroundPicture=:backgroundPicture where id=:id") 59 | int setBackgroundPicture(@Param("backgroundPicture") String backgroundPicture, @Param("id") Long id); 60 | } -------------------------------------------------------------------------------- /app/src/main/java/com/favorites/service/impl/CollectorServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.favorites.service.impl; 2 | 3 | import com.favorites.domain.view.IndexCollectorView; 4 | import com.favorites.repository.CollectorRepository; 5 | import com.favorites.repository.UserRepository; 6 | import com.favorites.service.CollectorService; 7 | import org.slf4j.Logger; 8 | import org.slf4j.LoggerFactory; 9 | import org.springframework.beans.factory.annotation.Autowired; 10 | import org.springframework.stereotype.Service; 11 | 12 | /** 13 | * @Description: 获取收藏家 14 | * @Auth: yuyang 15 | * @Date: 2017/1/19 14:14 16 | * @Version: 1.0 17 | **/ 18 | @Service 19 | public class CollectorServiceImpl implements CollectorService { 20 | protected Logger logger = LoggerFactory.getLogger(this.getClass()); 21 | 22 | @Autowired 23 | private CollectorRepository collectorRepository; 24 | @Autowired 25 | private UserRepository userRepository; 26 | 27 | /** 28 | * 获取收藏家 29 | * @return 30 | */ 31 | @Override 32 | public IndexCollectorView getCollectors() { 33 | IndexCollectorView indexCollectorView = new IndexCollectorView(); 34 | try { 35 | long mostCollectUser = collectorRepository.getMostCollectUser(); 36 | indexCollectorView.setMostCollectUser(userRepository.findById(mostCollectUser)); 37 | long mostFollowedUser = collectorRepository.getMostFollowedUser(mostCollectUser); 38 | indexCollectorView.setMostFollowedUser(userRepository.findById(mostFollowedUser)); 39 | String notUserIds = mostCollectUser+","+mostFollowedUser; 40 | long mostPraisedUser = collectorRepository.getMostPraisedUser(notUserIds); 41 | indexCollectorView.setMostPraisedUser(userRepository.findById(mostPraisedUser)); 42 | notUserIds += ","+mostPraisedUser; 43 | long mostCommentedUser = collectorRepository.getMostCommentedUser(notUserIds); 44 | indexCollectorView.setMostCommentedUser(userRepository.findById(mostCommentedUser)); 45 | notUserIds += ","+ mostCommentedUser; 46 | long mostPopularUser = collectorRepository.getMostPopularUser(notUserIds); 47 | indexCollectorView.setMostPopularUser(userRepository.findById(mostPopularUser)); 48 | notUserIds += ","+ mostPopularUser; 49 | long mostActiveUser = collectorRepository.getMostActiveUser(notUserIds); 50 | indexCollectorView.setMostActiveUser(userRepository.findById(mostActiveUser)); 51 | }catch (Exception e){ 52 | logger.info("错误",e); 53 | } 54 | return indexCollectorView; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /app/src/main/resources/templates/fragments/sidebar.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 66 | 67 | -------------------------------------------------------------------------------- /app/src/test/java/com/favorites/util/redis/TestRedis.java: -------------------------------------------------------------------------------- 1 | /* 2 | package com.favorites.util.redis; 3 | 4 | import com.favorites.domain.User; 5 | import com.favorites.service.RedisService; 6 | import org.junit.Assert; 7 | import org.junit.Test; 8 | import org.junit.runner.RunWith; 9 | import org.springframework.beans.factory.annotation.Autowired; 10 | import org.springframework.boot.test.context.SpringBootTest; 11 | import org.springframework.data.redis.core.BoundValueOperations; 12 | import org.springframework.data.redis.core.RedisTemplate; 13 | import org.springframework.data.redis.core.StringRedisTemplate; 14 | import org.springframework.test.context.junit4.SpringRunner; 15 | 16 | @RunWith(SpringRunner.class) 17 | @SpringBootTest 18 | public class TestRedis { 19 | 20 | @Autowired 21 | private StringRedisTemplate stringRedisTemplate; 22 | 23 | @Autowired 24 | private RedisTemplate redisTemplate; 25 | 26 | @Autowired 27 | private RedisService redisService; 28 | 29 | @Test 30 | public void test() throws Exception { 31 | // 保存字符串 32 | stringRedisTemplate.opsForValue().set("aaa", "111"); 33 | Assert.assertEquals("111", stringRedisTemplate.opsForValue().get("aaa")); 34 | } 35 | 36 | 37 | @Test 38 | public void testObj() throws Exception { 39 | BoundValueOperations ops = redisTemplate.boundValueOps("favorites"); 40 | ops.set(new User("aa", "aa@126.com", "aa", "aa123456"),1000); 41 | 42 | System.out.println("redis ====="+ops.get().getUserName()); 43 | System.out.println("Expire ====="+ops.getExpire()); 44 | 45 | 46 | redisTemplate.opsForValue().set("test", new User("aa", "aa@126.com", "aa", "aa123456"),1000); 47 | 48 | 49 | System.out.println("test ====="+redisTemplate.opsForValue().get("test")); 50 | 51 | } 52 | 53 | @Test 54 | public void testRedisService(){ 55 | redisService.set("test","123"); 56 | System.out.println("redis test: "+redisService.get("test")); 57 | redisService.setObject("user",new User("aa@126.com", "aa", "aa123456", "aa")); 58 | User user = (User) redisService.getObject("user"); 59 | System.out.println("redis user: "+user.toString()); 60 | boolean f = redisService.expire("user",1); 61 | try { 62 | Thread.sleep(1000); 63 | } catch (InterruptedException e) { 64 | e.printStackTrace(); 65 | } 66 | System.out.println("redis expire: "+f); 67 | System.out.println("redis expire user: "+ redisService.getObject("user")); 68 | redisService.delete("collector"); 69 | System.out.println("redis delete test: "+redisService.get("collector")); 70 | } 71 | 72 | }*/ 73 | -------------------------------------------------------------------------------- /app/src/main/java/com/favorites/comm/config/RedisConfig.java: -------------------------------------------------------------------------------- 1 | /* 2 | package com.favorites.comm.config; 3 | 4 | import java.lang.reflect.Method; 5 | 6 | import org.springframework.cache.CacheManager; 7 | import org.springframework.cache.annotation.CachingConfigurerSupport; 8 | import org.springframework.cache.annotation.EnableCaching; 9 | import org.springframework.cache.interceptor.KeyGenerator; 10 | import org.springframework.context.annotation.Bean; 11 | import org.springframework.context.annotation.Configuration; 12 | import org.springframework.data.redis.cache.RedisCacheManager; 13 | import org.springframework.data.redis.connection.RedisConnectionFactory; 14 | import org.springframework.data.redis.core.RedisTemplate; 15 | import org.springframework.data.redis.core.StringRedisTemplate; 16 | import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer; 17 | 18 | import com.fasterxml.jackson.annotation.JsonAutoDetect; 19 | import com.fasterxml.jackson.annotation.PropertyAccessor; 20 | import com.fasterxml.jackson.databind.ObjectMapper; 21 | 22 | @Configuration 23 | @EnableCaching 24 | public class RedisConfig extends CachingConfigurerSupport{ 25 | 26 | @Bean 27 | public KeyGenerator keyGenerator() { 28 | return new KeyGenerator() { 29 | @Override 30 | public Object generate(Object target, Method method, Object... params) { 31 | StringBuilder sb = new StringBuilder(); 32 | sb.append(target.getClass().getName()); 33 | sb.append(method.getName()); 34 | for (Object obj : params) { 35 | sb.append(obj.toString()); 36 | } 37 | return sb.toString(); 38 | } 39 | }; 40 | } 41 | 42 | @SuppressWarnings("rawtypes") 43 | @Bean 44 | public CacheManager cacheManager(RedisTemplate redisTemplate) { 45 | RedisCacheManager rcm = new RedisCacheManager(redisTemplate); 46 | //设置缓存过期时间 47 | //rcm.setDefaultExpiration(60);//秒 48 | return rcm; 49 | } 50 | 51 | @Bean 52 | public RedisTemplate redisTemplate(RedisConnectionFactory factory) { 53 | StringRedisTemplate template = new StringRedisTemplate(factory); 54 | Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class); 55 | ObjectMapper om = new ObjectMapper(); 56 | om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); 57 | om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); 58 | jackson2JsonRedisSerializer.setObjectMapper(om); 59 | template.setValueSerializer(jackson2JsonRedisSerializer); 60 | template.afterPropertiesSet(); 61 | return template; 62 | } 63 | 64 | }*/ 65 | -------------------------------------------------------------------------------- /app/src/main/java/com/favorites/domain/Comment.java: -------------------------------------------------------------------------------- 1 | package com.favorites.domain; 2 | 3 | import java.io.Serializable; 4 | 5 | import javax.persistence.*; 6 | 7 | /** 8 | * 评论 9 | * 10 | * @author DingYS 11 | * 12 | */ 13 | @Entity 14 | public class Comment extends Entitys implements Serializable { 15 | 16 | private static final long serialVersionUID = 1L; 17 | @Id 18 | @GeneratedValue(strategy= GenerationType.IDENTITY) 19 | private Long id; 20 | @Column(nullable = false) 21 | private Long collectId; 22 | @Column(nullable = false, length = 65535, columnDefinition = "Text") 23 | private String content; 24 | @Column(nullable = false) 25 | private Long userId; 26 | @Column(nullable = true) 27 | private Long replyUserId; 28 | @Column(nullable = false) 29 | private Long createTime; 30 | @Transient 31 | private String commentTime; 32 | @Transient 33 | private String userName; 34 | @Transient 35 | private String replyUserName; 36 | @Transient 37 | private String profilePicture; 38 | 39 | public Long getId() { 40 | return id; 41 | } 42 | 43 | public void setId(Long id) { 44 | this.id = id; 45 | } 46 | 47 | public Long getCollectId() { 48 | return collectId; 49 | } 50 | 51 | public void setCollectId(Long collectId) { 52 | this.collectId = collectId; 53 | } 54 | 55 | public String getContent() { 56 | return content; 57 | } 58 | 59 | public void setContent(String content) { 60 | this.content = content; 61 | } 62 | 63 | public Long getUserId() { 64 | return userId; 65 | } 66 | 67 | public void setUserId(Long userId) { 68 | this.userId = userId; 69 | } 70 | 71 | public Long getReplyUserId() { 72 | return replyUserId; 73 | } 74 | 75 | public void setReplyUserId(Long replyUserId) { 76 | this.replyUserId = replyUserId; 77 | } 78 | 79 | public Long getCreateTime() { 80 | return createTime; 81 | } 82 | 83 | public void setCreateTime(Long createTime) { 84 | this.createTime = createTime; 85 | } 86 | 87 | public String getCommentTime() { 88 | return commentTime; 89 | } 90 | 91 | public void setCommentTime(String commentTime) { 92 | this.commentTime = commentTime; 93 | } 94 | 95 | public String getUserName() { 96 | return userName; 97 | } 98 | 99 | public void setUserName(String userName) { 100 | this.userName = userName; 101 | } 102 | 103 | public String getReplyUserName() { 104 | return replyUserName; 105 | } 106 | 107 | public void setReplyUserName(String replyUserName) { 108 | this.replyUserName = replyUserName; 109 | } 110 | 111 | public String getProfilePicture() { 112 | return profilePicture; 113 | } 114 | 115 | public void setProfilePicture(String profilePicture) { 116 | this.profilePicture = profilePicture; 117 | } 118 | } -------------------------------------------------------------------------------- /app/src/main/java/com/favorites/domain/Config.java: -------------------------------------------------------------------------------- 1 | package com.favorites.domain; 2 | 3 | import javax.persistence.*; 4 | import java.io.Serializable; 5 | 6 | /** 7 | * 属性设置 8 | * 9 | * @author DingYS 10 | * 11 | */ 12 | @Entity 13 | public class Config extends Entitys implements Serializable { 14 | 15 | private static final long serialVersionUID = 1L; 16 | @Id 17 | @GeneratedValue(strategy= GenerationType.IDENTITY) 18 | private Long id; 19 | @Column(nullable = false) 20 | private Long userId; 21 | @Column(nullable = false) 22 | private String defaultFavorties; 23 | @Column(nullable = false) 24 | private String defaultCollectType; 25 | @Column(nullable = false) 26 | private String defaultModel; 27 | @Column(nullable = false) 28 | private Long createTime; 29 | @Column(nullable = false) 30 | private Long lastModifyTime; 31 | @Transient 32 | private String collectTypeName; 33 | @Transient 34 | private String modelName; 35 | 36 | public Config() { 37 | super(); 38 | } 39 | 40 | public Long getId() { 41 | return id; 42 | } 43 | 44 | public void setId(Long id) { 45 | this.id = id; 46 | } 47 | 48 | public Long getUserId() { 49 | return userId; 50 | } 51 | 52 | public void setUserId(Long userId) { 53 | this.userId = userId; 54 | } 55 | 56 | public String getDefaultFavorties() { 57 | return defaultFavorties; 58 | } 59 | 60 | public void setDefaultFavorties(String defaultFavorties) { 61 | this.defaultFavorties = defaultFavorties; 62 | } 63 | 64 | public String getDefaultCollectType() { 65 | return defaultCollectType; 66 | } 67 | 68 | public void setDefaultCollectType(String defaultCollectType) { 69 | this.defaultCollectType = defaultCollectType; 70 | } 71 | 72 | public String getDefaultModel() { 73 | return defaultModel; 74 | } 75 | 76 | public void setDefaultModel(String defaultModel) { 77 | this.defaultModel = defaultModel; 78 | } 79 | 80 | public Long getLastModifyTime() { 81 | return lastModifyTime; 82 | } 83 | 84 | public void setLastModifyTime(Long lastModifyTime) { 85 | this.lastModifyTime = lastModifyTime; 86 | } 87 | 88 | public Long getCreateTime() { 89 | return createTime; 90 | } 91 | 92 | public void setCreateTime(Long createTime) { 93 | this.createTime = createTime; 94 | } 95 | 96 | public String getCollectTypeName() { 97 | return defaultCollectType.equals("private")?"私密":"公开"; 98 | } 99 | 100 | public void setCollectTypeName(String collectTypeName) { 101 | this.collectTypeName = collectTypeName; 102 | } 103 | 104 | public String getModelName() { 105 | return defaultModel.equals("simple")?"简单":"专业"; 106 | } 107 | 108 | public void setModelName(String modelName) { 109 | this.modelName = modelName; 110 | } 111 | 112 | } -------------------------------------------------------------------------------- /app/src/main/resources/templates/lookAround.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 云收藏 | 让收藏更简单 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 29 |
alert
30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /app/src/main/java/com/favorites/web/BaseController.java: -------------------------------------------------------------------------------- 1 | package com.favorites.web; 2 | 3 | import com.favorites.comm.Const; 4 | import com.favorites.domain.User; 5 | import com.favorites.domain.result.ExceptionMsg; 6 | import com.favorites.domain.result.Response; 7 | import com.favorites.utils.Des3EncryptionUtil; 8 | import com.favorites.utils.MD5Util; 9 | import org.apache.commons.lang3.StringUtils; 10 | import org.slf4j.Logger; 11 | import org.slf4j.LoggerFactory; 12 | import org.springframework.stereotype.Controller; 13 | import org.springframework.web.context.request.RequestContextHolder; 14 | import org.springframework.web.context.request.ServletRequestAttributes; 15 | 16 | import javax.servlet.http.HttpServletRequest; 17 | import javax.servlet.http.HttpSession; 18 | 19 | @Controller 20 | public class BaseController { 21 | 22 | protected Logger logger = LoggerFactory.getLogger(this.getClass()); 23 | 24 | protected Response result(ExceptionMsg msg){ 25 | return new Response(msg); 26 | } 27 | protected Response result(){ 28 | return new Response(); 29 | } 30 | 31 | protected HttpServletRequest getRequest() { 32 | return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); 33 | } 34 | 35 | protected HttpSession getSession() { 36 | return getRequest().getSession(); 37 | } 38 | 39 | protected User getUser() { 40 | return (User) getSession().getAttribute(Const.LOGIN_SESSION_KEY); 41 | } 42 | 43 | protected long getUserId() { 44 | Long id=0l; 45 | User user=getUser(); 46 | if(user!=null){ 47 | id=user.getId(); 48 | } 49 | return id; 50 | } 51 | 52 | protected String getUserName() { 53 | String userName="云收藏"; 54 | User user=getUser(); 55 | if(user!=null){ 56 | userName=user.getUserName(); 57 | } 58 | return userName; 59 | } 60 | 61 | protected String getUserIp() { 62 | String value = getRequest().getHeader("X-Real-IP"); 63 | if (StringUtils.isNotBlank(value) && !"unknown".equalsIgnoreCase(value)) { 64 | return value; 65 | } else { 66 | return getRequest().getRemoteAddr(); 67 | } 68 | } 69 | 70 | protected String getPwd(String password){ 71 | try { 72 | String pwd = MD5Util.encrypt(password+Const.PASSWORD_KEY); 73 | return pwd; 74 | } catch (Exception e) { 75 | logger.error("密码加密异常:",e); 76 | } 77 | return null; 78 | } 79 | 80 | protected String cookieSign(String value){ 81 | try{ 82 | value = value + Const.PASSWORD_KEY; 83 | String sign = Des3EncryptionUtil.encode(Const.DES3_KEY,value); 84 | return sign; 85 | }catch (Exception e){ 86 | logger.error("cookie签名异常:",e); 87 | } 88 | return null; 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /app/src/main/resources/templates/layout.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 云收藏 | 让收藏更简单 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 30 |
alert
31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /app/src/main/resources/static/css/index.css: -------------------------------------------------------------------------------- 1 | body 2 | { 3 | padding-top: 50px; 4 | 5 | background-color: #fff; 6 | } 7 | .navbar 8 | { 9 | min-height: 50px; 10 | } 11 | .navbar-default 12 | { 13 | border-bottom: none; 14 | background-color: white; 15 | } 16 | .navbar-default .navbar-nav > li > a 17 | { 18 | padding-top: 14px; 19 | padding-bottom: 14px; 20 | 21 | color: #959595; 22 | } 23 | .navbar-default .navbar-nav > li > a:hover 24 | { 25 | color: #333; 26 | } 27 | .navbar-brand 28 | { 29 | height: 50px; 30 | padding-top: 7px; 31 | padding-bottom: 7px; 32 | } 33 | .navbar-brand > img 34 | { 35 | width: 95px; 36 | height: 36px; 37 | } 38 | footer 39 | { 40 | font-size: 13px; 41 | 42 | color: #666 43 | padding-bottom: 10px; 44 | background: white; 45 | } 46 | footer > a 47 | { 48 | color: black; 49 | } 50 | footer > p 51 | { 52 | margin-bottom: 10px; 53 | } 54 | .img-responsive 55 | { 56 | margin: 0 auto; 57 | } 58 | .banner 59 | { 60 | height: 500px; 61 | 62 | background-image: url(../img/banner.png); 63 | background-repeat: no-repeat; 64 | background-position: center center; 65 | background-size: cover; /* <------ */ 66 | } 67 | .banner > .media 68 | { 69 | width: 758px; 70 | margin-top: 150px; 71 | } 72 | .banner > .media > .media-left > img 73 | { 74 | width: 420px; 75 | height: 233px; 76 | } 77 | .banner .media-body .title 78 | { 79 | font-size: 30px; 80 | } 81 | .banner .media-body .detail 82 | { 83 | font-size: 12px; 84 | line-height: 150%; 85 | 86 | margin-top: 5px; 87 | margin-bottom: 15px; 88 | } 89 | .banner p 90 | { 91 | color: white; 92 | } 93 | .banner h1 94 | { 95 | color: white; 96 | } 97 | .banner a 98 | { 99 | color: white; 100 | border-width: 1px; 101 | border-style: solid; 102 | background-color: transparent; 103 | } 104 | .banner .ms-button 105 | { 106 | padding: 10px 40px; 107 | } 108 | .banner .xs-button 109 | { 110 | padding: 10px 130px; 111 | } 112 | .features 113 | { 114 | margin-top: 40px; 115 | } 116 | .features img 117 | { 118 | width: 60px; 119 | height: 60px; 120 | margin-top: 40px; 121 | } 122 | .features .title 123 | { 124 | font-size: 20px; 125 | 126 | margin-top: 20px; 127 | } 128 | .features .description 129 | { 130 | font-size: 13px; 131 | line-height: 150%; 132 | 133 | margin-top: 20px; 134 | 135 | color: #666; 136 | } 137 | .social 138 | { 139 | margin-top: 80px; 140 | } 141 | .qrcode 142 | { 143 | width: 100px; 144 | height: 100px; 145 | margin-top: 40px; 146 | } 147 | .qrcode-text 148 | { 149 | margin-top: 10px; 150 | } 151 | .qrcode-text img 152 | { 153 | width: 100px; 154 | height: 28px; 155 | } 156 | .target-fix 157 | { 158 | position: relative; 159 | top: -50px; 160 | 161 | display: block; 162 | overflow: hidden; 163 | 164 | height: 0; 165 | } -------------------------------------------------------------------------------- /app/src/main/java/com/favorites/web/NoticeController.java: -------------------------------------------------------------------------------- 1 | package com.favorites.web; 2 | 3 | import com.favorites.comm.aop.LoggerManage; 4 | import com.favorites.domain.Comment; 5 | import com.favorites.domain.Notice; 6 | import com.favorites.domain.result.ExceptionMsg; 7 | import com.favorites.domain.result.Response; 8 | import com.favorites.domain.result.ResponseData; 9 | import com.favorites.repository.CommentRepository; 10 | import com.favorites.repository.NoticeRepository; 11 | import com.favorites.utils.DateUtils; 12 | import org.springframework.beans.factory.annotation.Autowired; 13 | import org.springframework.web.bind.annotation.RequestMapping; 14 | import org.springframework.web.bind.annotation.RequestMethod; 15 | import org.springframework.web.bind.annotation.RestController; 16 | 17 | import java.util.HashMap; 18 | import java.util.Map; 19 | 20 | /** 21 | *@ClassName: NoticeController 22 | *@Description: 23 | *@author YY 24 | *@date 2016年8月31日 上午9:59:47 25 | *@version 1.0 26 | */ 27 | 28 | @RestController 29 | @RequestMapping("/notice") 30 | public class NoticeController extends BaseController{ 31 | 32 | @Autowired 33 | private NoticeRepository noticeRepository; 34 | 35 | @Autowired 36 | private CommentRepository commentRepository; 37 | 38 | /** 39 | * 回复 40 | * @param comment 41 | * @return 42 | */ 43 | @RequestMapping(value = "/reply", method = RequestMethod.POST) 44 | public Response reply(Comment comment) { 45 | logger.info("reply begin"); 46 | try { 47 | comment.setUserId(getUserId()); 48 | comment.setCreateTime(DateUtils.getCurrentTime()); 49 | Comment saveCommon = commentRepository.save(comment); 50 | Notice notice = new Notice(); 51 | notice.setCollectId(comment.getCollectId()+""); 52 | notice.setUserId(comment.getReplyUserId()); 53 | notice.setType("comment"); 54 | notice.setReaded("unread"); 55 | notice.setOperId(saveCommon.getId().toString()); 56 | notice.setCreateTime(DateUtils.getCurrentTime()); 57 | noticeRepository.save(notice); 58 | } catch (Exception e) { 59 | // TODO: handle exception 60 | logger.error("reply failed, ", e); 61 | return result(ExceptionMsg.FAILED); 62 | } 63 | return result(); 64 | } 65 | 66 | @RequestMapping(value="/getNoticeNum") 67 | @LoggerManage(description="获取新消息数量") 68 | public ResponseData getNoticeNum(){ 69 | Map result = new HashMap(); 70 | Long newAtMeCount = noticeRepository.countByUserIdAndTypeAndReaded(getUserId(), "at", "unread"); 71 | Long newCommentMeCount = noticeRepository.countByUserIdAndTypeAndReaded(getUserId(), "comment", "unread"); 72 | Long newPraiseMeCount = noticeRepository.countPraiseByUserIdAndReaded(getUserId(), "unread"); 73 | Long newLetterNotice = noticeRepository.countByUserIdAndTypeAndReaded(getUserId(),"letter","unread"); 74 | result.put("newAtMeCount",newAtMeCount); 75 | result.put("newCommentMeCount",newCommentMeCount); 76 | result.put("newPraiseMeCount",newPraiseMeCount); 77 | result.put("newLetterNotice",newLetterNotice); 78 | return new ResponseData(ExceptionMsg.SUCCESS,result); 79 | } 80 | 81 | } 82 | -------------------------------------------------------------------------------- /app/src/main/resources/templates/favorites/export.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
5 |
6 |

导出收藏夹

7 |
8 |
9 |
10 | 请选择要导出的收藏夹 11 |
12 |
13 |
14 | 19 |
20 |
21 |
22 |
23 | 28 |
29 |
30 |
31 |
32 | 33 |
34 |
35 |
36 |
37 |
38 |
39 | 40 | 72 | -------------------------------------------------------------------------------- /app/src/main/java/com/favorites/domain/User.java: -------------------------------------------------------------------------------- 1 | package com.favorites.domain; 2 | 3 | import javax.persistence.*; 4 | import java.io.Serializable; 5 | /** 6 | * 用户 7 | * @author DingYS 8 | * 9 | */ 10 | @Entity 11 | public class User extends Entitys implements Serializable { 12 | 13 | private static final long serialVersionUID = 1L; 14 | @Id 15 | @GeneratedValue(strategy= GenerationType.IDENTITY) 16 | private Long id; 17 | @Column(nullable = false, unique = true) 18 | private String userName; 19 | @Column(nullable = false) 20 | private String passWord; 21 | @Column(nullable = false, unique = true) 22 | private String email; 23 | @Column(nullable = true) 24 | private String profilePicture; 25 | @Column(nullable = true,length = 65535,columnDefinition="Text") 26 | private String introduction; 27 | @Column(nullable = false) 28 | private Long createTime; 29 | @Column(nullable = false) 30 | private Long lastModifyTime; 31 | @Column(nullable = true) 32 | private String outDate; 33 | @Column(nullable = true) 34 | private String validataCode; 35 | @Column(nullable = true) 36 | private String backgroundPicture; 37 | 38 | public User() { 39 | super(); 40 | } 41 | public User(String email, String nickName, String passWord, String userName) { 42 | super(); 43 | this.email = email; 44 | this.passWord = passWord; 45 | this.userName = userName; 46 | } 47 | public Long getId() { 48 | return id; 49 | } 50 | public void setId(Long id) { 51 | this.id = id; 52 | } 53 | public String getUserName() { 54 | return userName; 55 | } 56 | public void setUserName(String userName) { 57 | this.userName = userName; 58 | } 59 | public String getPassWord() { 60 | return passWord; 61 | } 62 | public void setPassWord(String passWord) { 63 | this.passWord = passWord; 64 | } 65 | public String getEmail() { 66 | return email; 67 | } 68 | public void setEmail(String email) { 69 | this.email = email; 70 | } 71 | public String getIntroduction() { 72 | return introduction; 73 | } 74 | public void setIntroduction(String introduction) { 75 | this.introduction = introduction; 76 | } 77 | public Long getCreateTime() { 78 | return createTime; 79 | } 80 | public void setCreateTime(Long createTime) { 81 | this.createTime = createTime; 82 | } 83 | public Long getLastModifyTime() { 84 | return lastModifyTime; 85 | } 86 | public void setLastModifyTime(Long lastModifyTime) { 87 | this.lastModifyTime = lastModifyTime; 88 | } 89 | public String getProfilePicture() { 90 | return profilePicture; 91 | } 92 | public void setProfilePicture(String profilePicture) { 93 | this.profilePicture = profilePicture; 94 | } 95 | public String getOutDate() { 96 | return outDate; 97 | } 98 | public void setOutDate(String outDate) { 99 | this.outDate = outDate; 100 | } 101 | public String getValidataCode() { 102 | return validataCode; 103 | } 104 | public void setValidataCode(String validataCode) { 105 | this.validataCode = validataCode; 106 | } 107 | public String getBackgroundPicture() { 108 | return backgroundPicture; 109 | } 110 | public void setBackgroundPicture(String backgroundPicture) { 111 | this.backgroundPicture = backgroundPicture; 112 | } 113 | } -------------------------------------------------------------------------------- /app/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | com.favorites 5 | favorites-web 6 | 1.0.0 7 | jar 8 | 9 | 10 | org.springframework.boot 11 | spring-boot-starter-parent 12 | 2.1.2.RELEASE 13 | 14 | 15 | 16 | 17 | org.springframework.boot 18 | spring-boot-starter-web 19 | 20 | 21 | org.springframework.boot 22 | spring-boot-starter-thymeleaf 23 | 24 | 25 | nz.net.ultraq.thymeleaf 26 | thymeleaf-layout-dialect 27 | 28 | 29 | org.springframework.boot 30 | spring-boot-starter-data-jpa 31 | 32 | 33 | org.springframework.boot 34 | spring-boot-devtools 35 | 36 | 37 | org.springframework.boot 38 | spring-boot-starter-test 39 | 40 | 41 | org.springframework.boot 42 | spring-boot-starter-mail 43 | 44 | 45 | org.webjars 46 | webjars-locator 47 | 0.33 48 | 49 | 50 | mysql 51 | mysql-connector-java 52 | 53 | 54 | org.apache.commons 55 | commons-lang3 56 | 3.4 57 | 58 | 59 | org.webjars.bower 60 | bootstrap 61 | 3.3.6 62 | 63 | 64 | org.webjars 65 | vue 66 | 1.0.24 67 | 68 | 69 | org.webjars.bower 70 | vue-resource 71 | 0.7.0 72 | 73 | 74 | org.jsoup 75 | jsoup 76 | 1.14.2 77 | 78 | 79 | org.webjars 80 | jquery 81 | 2.0.0 82 | 83 | 84 | 85 | 86 | 87 | 88 | org.springframework.boot 89 | spring-boot-maven-plugin 90 | 91 | 92 | 93 | 94 | 95 | -------------------------------------------------------------------------------- /app/src/main/resources/static/index/js/contact_me.js: -------------------------------------------------------------------------------- 1 | $(function() { 2 | 3 | $("#contactForm input,#contactForm textarea").jqBootstrapValidation({ 4 | preventSubmit: true, 5 | submitError: function($form, event, errors) { 6 | // additional error messages or events 7 | }, 8 | submitSuccess: function($form, event) { 9 | // Prevent spam click and default submit behaviour 10 | $("#btnSubmit").attr("disabled", true); 11 | event.preventDefault(); 12 | 13 | // get values from FORM 14 | var name = $("input#name").val(); 15 | var email = $("input#email").val(); 16 | var phone = $("input#phone").val(); 17 | var message = $("textarea#message").val(); 18 | var firstName = name; // For Success/Failure Message 19 | // Check for white space in name for Success/Fail message 20 | if (firstName.indexOf(' ') >= 0) { 21 | firstName = name.split(' ').slice(0, -1).join(' '); 22 | } 23 | $.ajax({ 24 | url: "././mail/contact_me.php", 25 | type: "POST", 26 | data: { 27 | name: name, 28 | phone: phone, 29 | email: email, 30 | message: message 31 | }, 32 | cache: false, 33 | success: function() { 34 | // Enable button & show success message 35 | $("#btnSubmit").attr("disabled", false); 36 | $('#success').html("
"); 37 | $('#success > .alert-success').html(""); 39 | $('#success > .alert-success') 40 | .append("Your message has been sent. "); 41 | $('#success > .alert-success') 42 | .append('
'); 43 | 44 | //clear all fields 45 | $('#contactForm').trigger("reset"); 46 | }, 47 | error: function() { 48 | // Fail message 49 | $('#success').html("
"); 50 | $('#success > .alert-danger').html(""); 52 | $('#success > .alert-danger').append("Sorry " + firstName + ", it seems that my mail server is not responding. Please try again later!"); 53 | $('#success > .alert-danger').append('
'); 54 | //clear all fields 55 | $('#contactForm').trigger("reset"); 56 | }, 57 | }); 58 | }, 59 | filter: function() { 60 | return $(this).is(":visible"); 61 | }, 62 | }); 63 | 64 | $("a[data-toggle=\"tab\"]").click(function(e) { 65 | e.preventDefault(); 66 | $(this).tab("show"); 67 | }); 68 | }); 69 | 70 | // When clicking on Full hide fail/success boxes 71 | $('#name').focus(function() { 72 | $('#success').html(''); 73 | }); 74 | -------------------------------------------------------------------------------- /app/src/main/java/com/favorites/service/impl/LetterServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.favorites.service.impl; 2 | 3 | import com.favorites.domain.Letter; 4 | import com.favorites.domain.User; 5 | import com.favorites.domain.enums.LetterType; 6 | import com.favorites.domain.view.LetterSummary; 7 | import com.favorites.domain.view.LetterView; 8 | import com.favorites.repository.LetterRepository; 9 | import com.favorites.repository.UserRepository; 10 | import com.favorites.service.LetterService; 11 | import com.favorites.service.NoticeService; 12 | import com.favorites.utils.DateUtils; 13 | import com.favorites.utils.StringUtil; 14 | import org.apache.commons.lang3.StringUtils; 15 | import org.springframework.beans.factory.annotation.Autowired; 16 | import org.springframework.data.domain.Pageable; 17 | import org.springframework.stereotype.Service; 18 | 19 | import javax.annotation.Resource; 20 | import java.util.ArrayList; 21 | import java.util.List; 22 | 23 | /** 24 | * Created by DingYS on 2017/3/8. 25 | */ 26 | @Service 27 | public class LetterServiceImpl implements LetterService{ 28 | 29 | @Autowired 30 | private LetterRepository letterRepository; 31 | @Resource 32 | private NoticeService noticeService; 33 | @Autowired 34 | private UserRepository userRepository; 35 | 36 | /** 37 | * 发送私信 38 | * @param letter 39 | */ 40 | public void sendLetter(Letter letter){ 41 | if("original".equals(letter.getSendType())){ 42 | letter.setType(LetterType.ORIGINAL); 43 | }else{ 44 | letter.setType(LetterType.REPLY); 45 | List userNameList = StringUtil.getAtUser(letter.getContent()); 46 | if(null != userNameList && userNameList.size() > 0){ 47 | User receiveUser = userRepository.findByUserName(userNameList.get(0)); 48 | if(null != receiveUser){ 49 | letter.setReceiveUserId(receiveUser.getId()); 50 | } 51 | String content = letter.getContent().substring(0,letter.getContent().indexOf("@")); 52 | if(StringUtils.isBlank(content)){ 53 | content = letter.getContent().substring(letter.getContent().indexOf("@")+receiveUser.getUserName().length()+1,letter.getContent().length()); 54 | letter.setContent(content); 55 | } 56 | } 57 | } 58 | letter.setCreateTime(DateUtils.getCurrentTime()); 59 | letterRepository.save(letter); 60 | if(null == letter.getPid()){ 61 | letter.setPid(letter.getId()); 62 | letterRepository.updatePidById(letter.getId(),letter.getId()); 63 | } 64 | // 添加消息通知 65 | noticeService.saveNotice(null,"letter",letter.getReceiveUserId(),String.valueOf(letter.getId())); 66 | } 67 | 68 | /** 69 | * 私信信息查询 70 | * @param userId 71 | * @param pageable 72 | * @return 73 | */ 74 | public List findLetter(Long userId, Pageable pageable){ 75 | List viewList = letterRepository.findLetterByReceiveUserId(userId,pageable); 76 | List summaryList = new ArrayList(); 77 | for(LetterView view : viewList){ 78 | LetterSummary summary = new LetterSummary(view); 79 | summaryList.add(summary); 80 | } 81 | return summaryList; 82 | } 83 | 84 | 85 | } 86 | -------------------------------------------------------------------------------- /app/src/test/java/com/favorites/domain/CollectRepositoryTest.java: -------------------------------------------------------------------------------- 1 | package com.favorites.domain; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | import com.favorites.domain.enums.IsDelete; 7 | import org.junit.Test; 8 | import org.junit.runner.RunWith; 9 | import org.springframework.beans.factory.annotation.Autowired; 10 | import org.springframework.boot.test.context.SpringBootTest; 11 | import org.springframework.data.domain.Page; 12 | import org.springframework.data.domain.PageRequest; 13 | import org.springframework.data.domain.Sort.Direction; 14 | import org.springframework.test.context.junit4.SpringRunner; 15 | 16 | import com.favorites.domain.view.CollectView; 17 | import com.favorites.repository.CollectRepository; 18 | 19 | 20 | @RunWith(SpringRunner.class) 21 | @SpringBootTest 22 | public class CollectRepositoryTest { 23 | 24 | @Autowired 25 | private CollectRepository collectRepository; 26 | 27 | @Test 28 | public void test() throws Exception { 29 | /* List views=collectRepository.findByUserId(1l); 30 | for(CollectView view:views){ 31 | System.out.println("collect title :" +view.getTitle()); 32 | } */ 33 | collectRepository.deleteById(3l); 34 | } 35 | 36 | 37 | @Test 38 | public void testFindView() throws Exception { 39 | /* Page views=collectRepository.findByUserId(1l,new PageRequest(0, 10, Direction.ASC, "title")); 40 | for(CollectView view:views){ 41 | System.out.println("collect title==" +view.getTitle()); 42 | }*/ 43 | } 44 | 45 | 46 | @Test 47 | public void testFindAllView() throws Exception { 48 | Page views=collectRepository.findExploreView(1l, new PageRequest(0, 10, Direction.ASC, "title")); 49 | for(CollectView view:views){ 50 | System.out.print(" collect title==" +view.getTitle()); 51 | System.out.print(" FavoriteName==" +view.getFavoriteName()); 52 | System.out.print(" UserName==" +view.getUserName()); 53 | System.out.println(" Url==" +view.getUrl()); 54 | } 55 | } 56 | 57 | 58 | @Test 59 | public void testFindViewByUserId() throws Exception { 60 | Page views=collectRepository.findViewByUserId(2l,new PageRequest(0, 10, Direction.ASC, "title")); 61 | for(CollectView view:views){ 62 | System.out.print(" collect title==" +view.getTitle()); 63 | System.out.print(" FavoriteName==" +view.getFavoriteName()); 64 | System.out.print(" UserName==" +view.getUserName()); 65 | System.out.println(" Url==" +view.getUrl()); 66 | } 67 | } 68 | 69 | @Test 70 | public void testFindViewByUserIdAndFollows() throws Exception { 71 | List userIds=new ArrayList(); 72 | userIds.add(2l); 73 | userIds.add(3l); 74 | Page views=collectRepository.findViewByUserIdAndFollows(2l,userIds,new PageRequest(0, 10, Direction.ASC, "title")); 75 | for(CollectView view:views){ 76 | System.out.print(" collect title==" +view.getTitle()); 77 | System.out.print(" FavoriteName==" +view.getFavoriteName()); 78 | System.out.print(" UserName==" +view.getUserName()); 79 | System.out.println(" Url==" +view.getUrl()); 80 | } 81 | } 82 | 83 | 84 | @Test 85 | public void Testcount(){ 86 | Long count=collectRepository.countByFavoritesIdAndIsDelete(4L, IsDelete.NO); 87 | System.out.println("+++++++++++++++++++++++++++++++++++++ count:"+count); 88 | } 89 | 90 | } -------------------------------------------------------------------------------- /app/src/test/java/com/favorites/domain/CollectorRepositoryTest.java: -------------------------------------------------------------------------------- 1 | package com.favorites.domain; 2 | 3 | import com.favorites.domain.enums.IsDelete; 4 | import com.favorites.domain.view.IndexCollectorView; 5 | import com.favorites.repository.CollectorRepository; 6 | import com.favorites.service.CollectorService; 7 | import org.junit.Test; 8 | import org.junit.runner.RunWith; 9 | import org.springframework.beans.factory.annotation.Autowired; 10 | import org.springframework.boot.test.context.SpringBootTest; 11 | import org.springframework.test.context.junit4.SpringRunner; 12 | 13 | import javax.persistence.EntityManager; 14 | import javax.persistence.EntityManagerFactory; 15 | import javax.persistence.PersistenceUnit; 16 | import javax.persistence.Query; 17 | import java.util.List; 18 | 19 | /** 20 | * @Description: 获取收藏家测试类 21 | * @Auth: yuyang 22 | * @Date: 2017/1/18 19:56 23 | * @Version: 1.0 24 | **/ 25 | @RunWith(SpringRunner.class) 26 | @SpringBootTest 27 | public class CollectorRepositoryTest { 28 | 29 | @PersistenceUnit 30 | private EntityManagerFactory emf; 31 | @Autowired 32 | private CollectorRepository collectorRepository; 33 | @Autowired 34 | private CollectorService collectorService; 35 | 36 | @Test 37 | public void test(){ 38 | EntityManager em=emf.createEntityManager(); 39 | String querySql = "SELECT follow_id as user_id,COUNT(1) AS counts FROM follow GROUP BY follow_id ORDER BY counts DESC LIMIT 1"; 40 | Query query=em.createNativeQuery(querySql); 41 | List objecArraytList = query.getResultList(); 42 | Object[] obj = (Object[]) objecArraytList.get(0); 43 | System.out.println("+++++++++++++++++++++++++++++++++++++ user_id:"+obj[0]); 44 | System.out.println("+++++++++++++++++++++++++++++++++++++ counts:"+obj[1]); 45 | em.close(); 46 | } 47 | 48 | @Test 49 | public void getMostUser(){ 50 | Long collectUserId = collectorRepository.getMostCollectUser(); 51 | System.out.println("+++++++++++++++++++++++++++++++++++++ collectUserId:"+collectUserId); 52 | Long followedUserid = collectorRepository.getMostFollowedUser(collectUserId); 53 | System.out.println("+++++++++++++++++++++++++++++++++++++ followedUserid:"+followedUserid); 54 | String notUserIds = collectUserId+","+followedUserid; 55 | Long praiseUserid = collectorRepository.getMostPraisedUser(notUserIds); 56 | System.out.println("+++++++++++++++++++++++++++++++++++++ praiseUserid:"+praiseUserid); 57 | notUserIds = notUserIds+","+praiseUserid; 58 | Long commentUserid = collectorRepository.getMostCommentedUser(notUserIds); 59 | System.out.println("+++++++++++++++++++++++++++++++++++++ commentUserid:"+commentUserid); 60 | notUserIds = notUserIds+","+commentUserid; 61 | Long popularUserid = collectorRepository.getMostPopularUser(notUserIds); 62 | System.out.println("+++++++++++++++++++++++++++++++++++++ popularUserid:"+popularUserid); 63 | notUserIds = notUserIds+","+popularUserid; 64 | Long activeUserid = collectorRepository.getMostActiveUser(notUserIds); 65 | System.out.println("+++++++++++++++++++++++++++++++++++++ activeUserid:"+activeUserid); 66 | } 67 | 68 | @Test 69 | public void getCollectors(){ 70 | IndexCollectorView indexCollectorView = collectorService.getCollectors(); 71 | System.out.println("+++++++++++++++++++++++++++++++++++++ collectors:"+indexCollectorView.getMostActiveUser()); 72 | } 73 | 74 | 75 | } 76 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![](http://favorites.ren/img/icon.ico) 2 | ![](http://favorites.ren/index/img/profile.png) 3 | 4 | 云收藏 - 让收藏更简单 5 | ========================= 6 | 7 | ![Spring Boot 2.0](https://img.shields.io/badge/Spring%20Boot-2.0-brightgreen.svg) 8 | ![Thymeleaf 3.0](https://img.shields.io/badge/Thymeleaf-3.0-yellow.svg) 9 | ![Mysql 5.6](https://img.shields.io/badge/Mysql-5.6-blue.svg) 10 | ![JDK 1.8](https://img.shields.io/badge/JDK-1.8-brightgreen.svg) 11 | ![Maven](https://img.shields.io/badge/Maven-3.5.0-yellowgreen.svg) 12 | ![license](https://img.shields.io/badge/license-MPL--2.0-blue.svg) 13 | 14 | 15 | 云收藏是一个使用 Spring Boot 构建的开源网站,可以让用户在线随时随地收藏的一个网站,在网站上分类整理收藏的网站或者文章,可以作为稍后阅读的一个临时存放。作为一个开放开源的软件,可以让用户从浏览器将收藏夹内容导入到云收藏,也支持随时将云收藏收集的文章导出去做备份。 16 | 17 | 网站可以查看别人公开收藏的内容,了解同行业内的大拿都在学习什么,方便学习、整理、检索,根据共同的收藏内容我们可以帮您找到**最熟悉的陌生人** :)。 18 | 19 | 20 | [官方主页](http://favorites.ren) | [github地址](https://github.com/cloudfavorites/favorites-web) | [码云地址](https://gitee.com/ityouknow/favorites-web) | [中文说明](http://www.ityouknow.com/springboot/2016/09/26/spring-boot-opensource-favorites.html) | [文档手册](https://github.com/cloudfavorites/favorites-web/wiki/%E5%A6%82%E4%BD%95%E6%9E%84%E5%BB%BA%E9%A1%B9%E7%9B%AE). 21 | 22 | 核心功能点: 23 | 24 | - 收藏、分类、检索文章 25 | - 导出、导出(包活从浏览器中) 26 | - 可以点赞、分享、讨论 27 | - 注册、登录、个人账户 28 | - 临时收藏、查看别人收藏 29 | - 其它... 30 | 31 | 32 | 项目使用技术 33 | ------------ 34 | 35 | * Vue 36 | * Bootstrap 37 | * jQuery 38 | * Thymeleaf 39 | * Spring Data Jpa 40 | * Spring Boot Mail 41 | * WebJars 42 | * Mysql 43 | * Tomcat 44 | * ~~Redis~~ 45 | 46 | 47 | Screenshots 48 | ------------ 49 | 50 | 主页 51 | ![favorites_chrome](http://favorites.ren/assets/images/2016/favorites_index.png) 52 | 53 | 注册 54 | ![favorites_chrome](http://favorites.ren/assets/images/2016/favorites_register.png) 55 | 56 | 首页 57 | ![favorites_chrome](http://favorites.ren/assets/images/2016/favorites_home.png) 58 | 59 | 收藏 60 | ![favorites_chrome](http://favorites.ren/assets/images/2016/favorites_collect.png) 61 | 62 | 63 | How to use 64 | ------------ 65 | 66 | ![How to use](http://favorites.ren/img/useTool.gif) 67 | 68 | 69 | Docker Deploy 70 | ---------- 71 | 72 | 推荐使用 Docker 部署此项目,需要提前安装 Docker 和 Docker compose 环境,[可以参考这里](http://www.ityouknow.com/docker.html) 73 | 74 | 下载最新发布版本 75 | 76 | ``` sh 77 | wget https://github.com/cloudfavorites/favorites-web/archive/favorites-1.3.0.zip 78 | ``` 79 | 80 | 解压 81 | 82 | ``` sh 83 | unzip favorites-1.1.1.zip 84 | ``` 85 | 86 | 进入目录 87 | 88 | ``` sh 89 | cd favorites-web-favorites-1.1.1/ 90 | ``` 91 | 92 | 修改文件`application-docker.properties` 93 | 94 | ``` sh 95 | vi app/src/main/resources/application-docker.properties 96 | ``` 97 | 98 | 修改内容如下 99 | ``` sh 100 | favorites.base.path=http://xx.xxx.xx.xx/ 101 | ``` 102 | >地址为部署服务器的地址 103 | 104 | 配置完成后,后台启动 105 | 106 | ``` sh 107 | [root@~]# docker-compose up -d 108 | Creating network "favoriteswebfavorites111_default" with the default driver 109 | Creating favorites-nginx ... done 110 | Creating favoriteswebfavorites111_mysql_1 ... done 111 | Creating favoriteswebfavorites111_app_1 ... done 112 | ``` 113 | 114 | 启动完成后,浏览器访问上面配置地址:`http://xx.xxx.xx.xx/`,就可以看到云收藏的首页了。 115 | 116 | 117 | Discussing 118 | ---------- 119 | - [submit issue](https://github.com/cloudfavorites/favorites-web/issues/new) 120 | - email: ityouknow@126.com 121 | 122 | 123 | 勾搭下 124 | -------- 125 | 关注公众号:纯洁的微笑,回复"springboot"进群交流 126 | 127 | ![](http://www.ityouknow.com/assets/images/keeppuresmile_430.jpg) -------------------------------------------------------------------------------- /app/src/main/resources/templates/favorites/import.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
5 |
6 |

导入云收藏

7 |
8 |
9 |
10 |
11 |
12 |
请选择浏览器导出的html格式的书签文件
13 |
14 |
15 | 16 |
17 | 18 | 19 | 22 | 23 |
24 |
25 |
26 |
27 |
28 | 33 |

34 | 39 |
40 | 提交 41 |
42 | 43 |
44 |
45 |
46 |
47 |
48 | 49 | 80 | 81 | -------------------------------------------------------------------------------- /app/src/main/java/com/favorites/schedule/ScheduledTasks.java: -------------------------------------------------------------------------------- 1 | package com.favorites.schedule; 2 | 3 | 4 | import com.favorites.cache.CacheService; 5 | import com.favorites.comm.Const; 6 | import com.favorites.comm.aop.LoggerManage; 7 | import com.favorites.domain.Collect; 8 | import com.favorites.domain.UrlLibrary; 9 | import com.favorites.domain.enums.IsDelete; 10 | import com.favorites.repository.CollectRepository; 11 | import com.favorites.repository.FavoritesRepository; 12 | import com.favorites.repository.UrlLibraryRepository; 13 | import com.favorites.utils.DateUtils; 14 | import com.favorites.utils.HtmlUtil; 15 | import org.slf4j.Logger; 16 | import org.slf4j.LoggerFactory; 17 | import org.springframework.beans.factory.annotation.Autowired; 18 | import org.springframework.scheduling.annotation.Scheduled; 19 | import org.springframework.stereotype.Component; 20 | 21 | import java.util.Calendar; 22 | import java.util.Date; 23 | import java.util.List; 24 | 25 | @Component 26 | public class ScheduledTasks { 27 | 28 | protected Logger logger = LoggerFactory.getLogger(this.getClass()); 29 | 30 | @Autowired 31 | private CollectRepository collectRespository; 32 | @Autowired 33 | private FavoritesRepository favoritesRespository; 34 | @Autowired 35 | private UrlLibraryRepository urlLibraryRepository; 36 | @Autowired 37 | private CacheService cacheService; 38 | 39 | @Autowired 40 | // private RedisService redisService; 41 | 42 | /** 43 | * 回收站定时 44 | */ 45 | @Scheduled(cron="22 2 2 * * ?") 46 | @LoggerManage(description="回收站定时") 47 | public void autoRecovery() { 48 | Calendar ca = Calendar.getInstance(); 49 | ca.setTime(new Date()); 50 | ca.add(Calendar.DAY_OF_YEAR,-30); 51 | Long date = ca.getTime().getTime(); 52 | List favoritesId = favoritesRespository.findIdByName("未读列表"); 53 | List collectList = collectRespository.findByCreateTimeLessThanAndIsDeleteAndFavoritesIdIn(date, IsDelete.NO,favoritesId); 54 | for(Collect collect : collectList){ 55 | try { 56 | logger.info("文章id:" + collect.getId()); 57 | collectRespository.modifyIsDeleteById(IsDelete.YES, DateUtils.getCurrentTime(), collect.getId()); 58 | favoritesRespository.reduceCountById(collect.getFavoritesId(), DateUtils.getCurrentTime()); 59 | } catch (Exception e) { 60 | logger.error("回收站定时任务异常:",e); 61 | } 62 | } 63 | } 64 | 65 | @Scheduled(cron="11 1 1 * * ?") 66 | @LoggerManage(description="获取图片logoUrl定时") 67 | public void getImageLogoUrl(){ 68 | List urlLibraryList = urlLibraryRepository.findByCountLessThanAndLogoUrl(10, Const.BASE_PATH+"img/logo.jpg"); 69 | logger.info("集合长度:" + urlLibraryList.size()); 70 | for(UrlLibrary urlLibrary : urlLibraryList){ 71 | try { 72 | String logoUrl = HtmlUtil.getImge(urlLibrary.getUrl()); 73 | // 刷新缓存 74 | boolean result = cacheService.refreshOne(urlLibrary.getUrl(),logoUrl); 75 | if(result){ 76 | collectRespository.updateLogoUrlByUrl(logoUrl,DateUtils.getCurrentTime(),urlLibrary.getUrl()); 77 | urlLibraryRepository.updateLogoUrlById(urlLibrary.getId(),logoUrl); 78 | }else{ 79 | urlLibraryRepository.increaseCountById(urlLibrary.getId()); 80 | } 81 | }catch (Exception e){ 82 | logger.error("获取图片异常:",e); 83 | } 84 | } 85 | } 86 | 87 | /* @Scheduled(cron="11 11 0 * * ?") 88 | @LoggerManage(description="查询收藏夹放到缓存定时") 89 | public void putRedisCollector() { 90 | try { 91 | IndexCollectorView indexCollectorView = collectorService.getCollectors(); 92 | redisService.setObject("collector", indexCollectorView); 93 | }catch (Exception e){ 94 | logger.error("查询收藏夹放到缓存定时任务异常:",e); 95 | } 96 | }*/ 97 | 98 | } 99 | --------------------------------------------------------------------------------