├── .gitignore ├── .travis.yml ├── README.md ├── dbmigrate ├── 201601301807-intialize-database.sql ├── 201602041443-alter-article_info.sql ├── 201602122214-alter-article_info.sql ├── 201603241501-create-slug_info.sql ├── 201603271539-alter-article_info.sql ├── 201604061516-create-website_traffic.sql ├── 201604182004-alter-article_read_log.sql ├── 201605011706-alter-article_article_info.sql ├── 201605060954-create-book_table.sql ├── 201605111534-alter-record_info.sql ├── 201605111536-delete-record_log_info.sql └── 201605131224-create-pic_info.sql ├── deploy.sh ├── gulpfile.js ├── pblog.sql ├── pom.xml ├── src ├── main │ ├── java │ │ └── com │ │ │ └── pblog │ │ │ ├── core │ │ │ ├── orm │ │ │ │ ├── PageRequest.java │ │ │ │ └── Pagination.java │ │ │ └── utils │ │ │ │ ├── DateFormatUtils.java │ │ │ │ ├── GenerateUtils.java │ │ │ │ ├── ImageFormatUtils.java │ │ │ │ ├── ImageUploadUtils.java │ │ │ │ ├── MultipartFileValidator.java │ │ │ │ ├── RandomUtils.java │ │ │ │ └── ReflectUtils.java │ │ │ ├── dao │ │ │ ├── ArticleInfoMapper.java │ │ │ ├── ArticleReadLogMapper.java │ │ │ ├── AuthorInfoMapper.java │ │ │ ├── BookInfoMapper.java │ │ │ ├── BookReadLogMapper.java │ │ │ ├── BookTableMapper.java │ │ │ ├── CategoryInfoMapper.java │ │ │ ├── PicInfoMapper.java │ │ │ ├── RecordInfoMapper.java │ │ │ ├── SlugInfoMapper.java │ │ │ ├── TagInfoMapper.java │ │ │ ├── WebsiteTrafficMapper.java │ │ │ └── mapping │ │ │ │ ├── ArticleInfoMapper.xml │ │ │ │ ├── ArticleReadLogMapper.xml │ │ │ │ ├── AuthorInfoMapper.xml │ │ │ │ ├── BookInfoMapper.xml │ │ │ │ ├── BookReadLogMapper.xml │ │ │ │ ├── BookTableMapper.xml │ │ │ │ ├── CategoryInfoMapper.xml │ │ │ │ ├── PicInfoMapper.xml │ │ │ │ ├── RecordInfoMapper.xml │ │ │ │ ├── SlugInfoMapper.xml │ │ │ │ ├── TagInfoMapper.xml │ │ │ │ └── WebsiteTrafficMapper.xml │ │ │ ├── domain │ │ │ ├── ArticleInfo.java │ │ │ ├── ArticleReadLog.java │ │ │ ├── AuthorInfo.java │ │ │ ├── BookInfo.java │ │ │ ├── BookReadLog.java │ │ │ ├── BookTable.java │ │ │ ├── CategoryInfo.java │ │ │ ├── PicInfo.java │ │ │ ├── RecordInfo.java │ │ │ ├── SlugInfo.java │ │ │ ├── TagInfo.java │ │ │ └── WebsiteTraffic.java │ │ │ ├── service │ │ │ ├── Article │ │ │ │ ├── ArticleInfoService.java │ │ │ │ ├── ArticleInfoServiceImpl.java │ │ │ │ ├── ArticleInfoVO.java │ │ │ │ ├── ManageArticleInfoService.java │ │ │ │ ├── ManageArticleInfoServiceImpl.java │ │ │ │ └── SimpleArticleInfo.java │ │ │ ├── CommonUtilsService.java │ │ │ ├── CommonUtilsServiceImpl.java │ │ │ ├── archives │ │ │ │ ├── ArchivesService.java │ │ │ │ ├── ArchivesServiceImpl.java │ │ │ │ └── ArchivesVO.java │ │ │ ├── book │ │ │ │ ├── BookInfoService.java │ │ │ │ ├── BookInfoServiceImpl.java │ │ │ │ ├── BookInfoVO.java │ │ │ │ ├── BookTableService.java │ │ │ │ ├── BookTableServiceImpl.java │ │ │ │ ├── BookTableVO.java │ │ │ │ ├── ManageBookInfoService.java │ │ │ │ ├── ManageBookInfoServiceImpl.java │ │ │ │ ├── ManageBookTableService.java │ │ │ │ └── ManageBookTableServiceImpl.java │ │ │ ├── category │ │ │ │ ├── CategoryInfoService.java │ │ │ │ ├── CategoryInfoServiceImpl.java │ │ │ │ ├── CategoryInfoVO.java │ │ │ │ ├── ManageCategoryService.java │ │ │ │ ├── ManageCategoryServiceImpl.java │ │ │ │ └── SimpleCategoryInfo.java │ │ │ ├── log │ │ │ │ ├── WebsiteTrafficService.java │ │ │ │ └── WebsiteTrafficServiceImpl.java │ │ │ ├── pic │ │ │ │ ├── PicInfoService.java │ │ │ │ └── PicInfoServiceImpl.java │ │ │ ├── record │ │ │ │ ├── ManageRecordService.java │ │ │ │ ├── ManageRecordServiceImpl.java │ │ │ │ ├── RecordService.java │ │ │ │ └── RecordServiceImpl.java │ │ │ └── slug │ │ │ │ ├── SlugInfoService.java │ │ │ │ └── SlugInfoServiceImpl.java │ │ │ └── web │ │ │ ├── controller │ │ │ ├── AboutController.java │ │ │ ├── ArchivesController.java │ │ │ ├── ArticleController.java │ │ │ ├── CategoryController.java │ │ │ ├── GlobalController.java │ │ │ ├── IndexController.java │ │ │ ├── ReadController.java │ │ │ ├── RecordController.java │ │ │ ├── ResumeController.java │ │ │ ├── aboutmanage │ │ │ │ └── ManageAboutController.java │ │ │ ├── articlemanage │ │ │ │ ├── ArticleInfoFormBean.java │ │ │ │ └── ManageArticleController.java │ │ │ ├── bookmanage │ │ │ │ ├── BookInfoFormBean.java │ │ │ │ ├── ManageBookInfoController.java │ │ │ │ └── ManageBookTableController.java │ │ │ ├── categorymanage │ │ │ │ └── ManageCategoryController.java │ │ │ ├── picmanage │ │ │ │ └── ManagePicController.java │ │ │ └── recordmanage │ │ │ │ └── ManageRecordController.java │ │ │ └── interceptor │ │ │ ├── GlobalInterceptor.java │ │ │ └── PaginationInterceptor.java │ ├── resources │ │ ├── application-dispatch.xml │ │ ├── application.xml │ │ ├── configuration.xml │ │ ├── generatorConfig.xml │ │ ├── logback.xml │ │ └── properties │ │ │ └── pblog-local.properties │ └── webapp │ │ ├── WEB-INF │ │ ├── jsp │ │ │ ├── 404.jsp │ │ │ ├── manage │ │ │ │ ├── about │ │ │ │ │ └── about_edit.jsp │ │ │ │ ├── article │ │ │ │ │ ├── article_add.jsp │ │ │ │ │ └── article_list.jsp │ │ │ │ ├── book │ │ │ │ │ ├── edit.jsp │ │ │ │ │ └── list.jsp │ │ │ │ ├── category │ │ │ │ │ └── list.jsp │ │ │ │ ├── include │ │ │ │ │ ├── index_man_header.jsp │ │ │ │ │ ├── index_second_header.jsp │ │ │ │ │ └── namespace.jsp │ │ │ │ ├── index │ │ │ │ │ └── index.jsp │ │ │ │ ├── pic │ │ │ │ │ └── list.jsp │ │ │ │ └── record │ │ │ │ │ └── list.jsp │ │ │ └── web │ │ │ │ ├── about │ │ │ │ ├── about_mobile.jsp │ │ │ │ └── layout.jsp │ │ │ │ ├── archives │ │ │ │ ├── archives_mobile.jsp │ │ │ │ └── layout.jsp │ │ │ │ ├── article │ │ │ │ ├── article_mobile.jsp │ │ │ │ └── layout.jsp │ │ │ │ ├── book │ │ │ │ ├── detail.jsp │ │ │ │ ├── layout.jsp │ │ │ │ ├── read_mobile.jsp │ │ │ │ └── read_mobile_detail.jsp │ │ │ │ ├── category │ │ │ │ ├── category_mobile.jsp │ │ │ │ └── layout.jsp │ │ │ │ ├── common │ │ │ │ └── detail.jsp │ │ │ │ ├── home.jsp │ │ │ │ ├── include │ │ │ │ ├── footer.jsp │ │ │ │ ├── header.jsp │ │ │ │ ├── index_mobile_header.jsp │ │ │ │ └── namespace.jsp │ │ │ │ ├── index │ │ │ │ ├── index_mobile.jsp │ │ │ │ └── layout.jsp │ │ │ │ ├── record │ │ │ │ ├── layout.jsp │ │ │ │ └── record_mobile.jsp │ │ │ │ ├── resume │ │ │ │ └── resume.jsp │ │ │ │ └── rev-manifest.json │ │ └── web.xml │ │ └── resources │ │ ├── assets │ │ ├── css │ │ │ ├── about │ │ │ │ ├── day_layout.css │ │ │ │ └── night_layout.css │ │ │ ├── archives │ │ │ │ ├── day_layout.css │ │ │ │ └── night_layout.css │ │ │ ├── article │ │ │ │ ├── day_layout.css │ │ │ │ └── night_layout.css │ │ │ ├── book │ │ │ │ ├── day_detail.css │ │ │ │ ├── day_layout.css │ │ │ │ ├── night_detail.css │ │ │ │ └── night_layout.css │ │ │ ├── category │ │ │ │ ├── day_layout.css │ │ │ │ └── night_layout.css │ │ │ ├── day-pc-main-4b3b2e648a.css │ │ │ ├── include │ │ │ │ ├── day_index_global.css │ │ │ │ ├── global.css │ │ │ │ ├── index_global.css │ │ │ │ ├── index_man_header.css │ │ │ │ ├── index_mobile_global.css │ │ │ │ └── night_index_global.css │ │ │ ├── index │ │ │ │ ├── day_layout.css │ │ │ │ └── night_layout.css │ │ │ ├── manage │ │ │ │ ├── about_edit.css │ │ │ │ ├── article_add.css │ │ │ │ ├── article_list.css │ │ │ │ ├── book_edit.css │ │ │ │ ├── book_list.css │ │ │ │ ├── category_list.css │ │ │ │ ├── pic_list.css │ │ │ │ └── record_list.css │ │ │ ├── mobile │ │ │ │ ├── about_mobile.css │ │ │ │ ├── article_mobile.css │ │ │ │ ├── article_mobile_list.css │ │ │ │ ├── read_mobile.css │ │ │ │ ├── read_mobile_detail.css │ │ │ │ ├── record_mobile.css │ │ │ │ └── time_line.css │ │ │ ├── night-pc-main-4e6b1e8763.css │ │ │ ├── record │ │ │ │ ├── day_layout.css │ │ │ │ └── night_layout.css │ │ │ └── resume │ │ │ │ ├── resume_mobile.css │ │ │ │ └── resume_pc.css │ │ ├── js │ │ │ ├── angular-plugins.min.js │ │ │ ├── client-js.min.js │ │ │ ├── highlight.min.js │ │ │ ├── lib.min.js │ │ │ └── loading-bar.js │ │ ├── plugins │ │ │ ├── font-awesome.min.css │ │ │ ├── highlight.min.css │ │ │ └── loading-bar.css │ │ └── rev │ │ │ └── rev-manifest.json │ │ ├── font │ │ ├── FontAwesome.otf │ │ ├── anjingchen.ttf │ │ ├── fontawesome-webfont.eot │ │ ├── fontawesome-webfont.svg │ │ ├── fontawesome-webfont.ttf │ │ ├── fontawesome-webfont.woff │ │ ├── fontawesome-webfont.woff2 │ │ └── xiaofeng.ttf │ │ ├── image │ │ ├── about_me.jpg │ │ ├── author_header.png │ │ ├── circle-h.png │ │ ├── clock.png │ │ ├── csdn.png │ │ ├── day_content_backgrund.jpg │ │ ├── mobile_slider_bar.jpg │ │ ├── pblog_icon.ico │ │ ├── record_background.png │ │ ├── record_background_bottom.png │ │ ├── record_background_top.png │ │ ├── resume │ │ │ ├── honor_reward_icon.png │ │ │ ├── li_icon.png │ │ │ ├── open_source_icon.png │ │ │ ├── person_info_icon.png │ │ │ ├── pro_skill_icon.png │ │ │ ├── self_evaluation_icon.png │ │ │ └── work_experience_icon.png │ │ ├── search_background.png │ │ └── zhihu.png │ │ ├── js │ │ ├── app.js │ │ ├── controllers │ │ │ ├── AboutController.js │ │ │ ├── ArchivesController.js │ │ │ ├── ArchivesTimeStampController.js │ │ │ ├── ArticleController.js │ │ │ ├── BookController.js │ │ │ ├── CategoryController.js │ │ │ ├── CategorySlugController.js │ │ │ ├── IndexController.js │ │ │ ├── ReadController.js │ │ │ └── RecordController.js │ │ ├── directives.js │ │ ├── filters.js │ │ ├── manage │ │ │ └── book_list.js │ │ ├── mobile │ │ │ ├── analytics.js │ │ │ └── global_mobile.js │ │ ├── plugins │ │ │ ├── SliderBar.js │ │ │ ├── angular-animate.min.js │ │ │ ├── angular-route.min.js │ │ │ ├── angular-sanitize.min.js │ │ │ ├── angular.min.js │ │ │ ├── jquery.min.js │ │ │ └── marked.js │ │ ├── routes.js │ │ └── services.js │ │ └── less │ │ ├── about │ │ ├── day_layout.less │ │ └── night_layout.less │ │ ├── archives │ │ ├── day_layout.less │ │ └── night_layout.less │ │ ├── article │ │ ├── day_layout.less │ │ └── night_layout.less │ │ ├── book │ │ ├── day_detail.less │ │ ├── day_layout.less │ │ ├── night_detail.less │ │ └── night_layout.less │ │ ├── category │ │ ├── day_layout.less │ │ └── night_layout.less │ │ ├── include │ │ ├── day_index_global.less │ │ ├── global.less │ │ ├── index_man_header.less │ │ ├── index_mobile_global.less │ │ └── night_index_global.less │ │ ├── index │ │ ├── day_layout.less │ │ └── night_layout.less │ │ ├── manage │ │ ├── about_edit.less │ │ ├── article_add.less │ │ ├── article_list.less │ │ ├── book_edit.less │ │ ├── book_list.less │ │ ├── category_list.less │ │ ├── pic_list.less │ │ └── record_list.less │ │ ├── mobile │ │ ├── about_mobile.less │ │ ├── article_mobile.less │ │ ├── article_mobile_list.less │ │ ├── read_mobile.less │ │ ├── read_mobile_detail.less │ │ ├── record_mobile.less │ │ └── time_line.less │ │ ├── record │ │ ├── day_layout.less │ │ └── night_layout.less │ │ └── resume │ │ ├── resume_mobile.less │ │ └── resume_pc.less └── test │ └── GenerateSlugInfo.java ├── 前台页面功能设计.md └── 数据库设计.md /.gitignore: -------------------------------------------------------------------------------- 1 | .classpath 2 | .project 3 | /.metadata 4 | /.settings 5 | /build 6 | /bin 7 | /dist 8 | /.idea 9 | /PBlog.iml 10 | /target 11 | /properties 12 | /node_modules -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: java 2 | jdk: 3 | - oraclejdk7 4 | - openjdk7 5 | 6 | services: 7 | - mysql 8 | 9 | service_name: 10 | - travis-pro 11 | 12 | before_script: 13 | - mysql -e 'CREATE DATABASE test;' 14 | - mysql test < pblog.sql 15 | 16 | script: 17 | - mvn test -f pom.xml 18 | 19 | after_script: 20 | - mysql -e 'DROP DATABASE test;' 21 | 22 | after_success: 23 | - mvn clean cobertura:cobertura coveralls:report 24 | -------------------------------------------------------------------------------- /dbmigrate/201602041443-alter-article_info.sql: -------------------------------------------------------------------------------- 1 | alter table article_info add `markdown` longtext DEFAULT NULL; -------------------------------------------------------------------------------- /dbmigrate/201602122214-alter-article_info.sql: -------------------------------------------------------------------------------- 1 | alter table article_info add `description` longtext DEFAULT NULL; 2 | alter table article_info change `tagId` `tag` varchar(200); -------------------------------------------------------------------------------- /dbmigrate/201603241501-create-slug_info.sql: -------------------------------------------------------------------------------- 1 | create table `slug_info`( 2 | `id` INT PRIMARY KEY not null auto_increment, 3 | `slug` bigint DEFAULT NULL 4 | ) -------------------------------------------------------------------------------- /dbmigrate/201603271539-alter-article_info.sql: -------------------------------------------------------------------------------- 1 | alter table article_info drop markdown; 2 | -------------------------------------------------------------------------------- /dbmigrate/201604061516-create-website_traffic.sql: -------------------------------------------------------------------------------- 1 | create table `website_traffic`( 2 | `id` bigint(24) PRIMARY KEY NOT NULL auto_increment, 3 | `ipAddress` varchar(20) DEFAULT NULL, 4 | `createTime` datetime DEFAULT NULL, 5 | `operateSystem` varchar(20) DEFAULT NULL, 6 | `browser` varchar(20) DEFAULT NULL 7 | ) -------------------------------------------------------------------------------- /dbmigrate/201604182004-alter-article_read_log.sql: -------------------------------------------------------------------------------- 1 | alter table `article_read_log` change `articleId` `articleSlug` bigint(20) default null; 2 | create INDEX idx_artSlug on `article_read_log` (articleSlug); -------------------------------------------------------------------------------- /dbmigrate/201605011706-alter-article_article_info.sql: -------------------------------------------------------------------------------- 1 | alter table article_info add `descriptionMd` longtext DEFAULT NULL; -------------------------------------------------------------------------------- /dbmigrate/201605060954-create-book_table.sql: -------------------------------------------------------------------------------- 1 | create table `book_table`( 2 | `id` INT PRIMARY KEY NOT NULL auto_increment, 3 | `bookName` varchar(50) DEFAULT NULL, 4 | `bookUrl` varchar(100) DEFAULT NULL, 5 | `bookBanner` varchar(100) DEFAULT NULL 6 | )DEFAULT CHARSET=utf8; -------------------------------------------------------------------------------- /dbmigrate/201605111534-alter-record_info.sql: -------------------------------------------------------------------------------- 1 | alter table `record_info` drop column `slug`; -------------------------------------------------------------------------------- /dbmigrate/201605111536-delete-record_log_info.sql: -------------------------------------------------------------------------------- 1 | drop table `record_read_log`; -------------------------------------------------------------------------------- /dbmigrate/201605131224-create-pic_info.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE `pic_info` ( 2 | `id` bigint(24) PRIMARY KEY not null auto_increment, 3 | `relativePath` VARCHAR(100) DEFAULT NULL, 4 | `physicalPath` VARCHAR(100) DEFAULT NULL, 5 | `createTime` DATE DEFAULT NULL 6 | ) 7 | -------------------------------------------------------------------------------- /deploy.sh: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/penglongli/PBlog/6824591e56afeee5d06c02ab79f47a27584709c1/deploy.sh -------------------------------------------------------------------------------- /src/main/java/com/pblog/core/orm/PageRequest.java: -------------------------------------------------------------------------------- 1 | package com.pblog.core.orm; 2 | 3 | public class PageRequest { 4 | 5 | protected int pageNo = 1; 6 | 7 | protected int pageSize = 10; 8 | 9 | protected String orderBy = "id"; 10 | 11 | protected String orderDir = Sort.DESC; 12 | 13 | protected int offset = 1; 14 | 15 | protected int totalCount = -1; 16 | 17 | protected int totalPage; 18 | 19 | public PageRequest(){} 20 | 21 | public PageRequest(int pageNo, int pageSize){ 22 | this.pageNo = pageNo; 23 | this.pageSize = pageSize; 24 | this.offset = (pageNo -1) * pageSize; 25 | } 26 | 27 | public int getPageNo() { 28 | return pageNo; 29 | } 30 | 31 | public void setPageNo(int pageNo) { 32 | this.pageNo = pageNo; 33 | 34 | if(pageNo < 1){ 35 | this.pageNo = 1; 36 | } 37 | } 38 | 39 | public int getPageSize() { 40 | return pageSize; 41 | } 42 | 43 | public void setPageSize(int pageSize) { 44 | this.pageSize = pageSize; 45 | 46 | if(pageSize < 1){ 47 | this.pageSize = 1; 48 | } 49 | } 50 | 51 | public String getOrderBy() { 52 | return orderBy; 53 | } 54 | 55 | public void setOrderBy(String orderBy) { 56 | this.orderBy = orderBy; 57 | } 58 | 59 | public String getOrderDir() { 60 | return orderDir; 61 | } 62 | 63 | public void setOrderDir(String orderDir) { 64 | this.orderDir = orderDir; 65 | } 66 | 67 | public int getOffset() { 68 | return offset; 69 | } 70 | 71 | public void setOffset(int offset) { 72 | this.offset = offset; 73 | } 74 | 75 | public int getTotalCount() { 76 | return totalCount; 77 | } 78 | 79 | public void setTotalCount(int totalCount) { 80 | this.totalCount = totalCount; 81 | } 82 | 83 | public int getTotalPage() { 84 | return totalPage; 85 | } 86 | 87 | public void setTotalPage(int totalPage) { 88 | this.totalPage = totalPage; 89 | } 90 | 91 | public static class Sort{ 92 | public static final String ASC = "asc"; 93 | 94 | public static final String DESC = "desc"; 95 | 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /src/main/java/com/pblog/core/orm/Pagination.java: -------------------------------------------------------------------------------- 1 | package com.pblog.core.orm; 2 | 3 | import java.io.Serializable; 4 | import java.util.Iterator; 5 | import java.util.List; 6 | 7 | public class Pagination extends PageRequest implements Iterable, Serializable { 8 | protected List items = null; 9 | 10 | public Pagination(){} 11 | 12 | public Pagination(PageRequest pageRequest){ 13 | this.pageNo = pageRequest.getPageNo(); 14 | this.pageSize = pageRequest.getPageSize(); 15 | this.orderBy = pageRequest.getOrderBy(); 16 | this.orderDir = pageRequest.getOrderDir(); 17 | this.offset = pageRequest.getOffset(); 18 | this.totalCount = pageRequest.getTotalCount(); 19 | this.totalPage = pageRequest.getTotalPage(); 20 | } 21 | 22 | public Iterator iterator() { 23 | return items.iterator(); 24 | } 25 | 26 | public List getItems() { 27 | return items; 28 | } 29 | 30 | public void setItems(List items) { 31 | this.items = items; 32 | } 33 | 34 | public int getTotalPage() { 35 | return totalPage; 36 | } 37 | 38 | public void setTotalPage(int totalPage) { 39 | this.totalPage = totalPage; 40 | } 41 | 42 | public int getTotalCount() { 43 | return totalCount; 44 | } 45 | 46 | public void setTotalCount(int totalCount) { 47 | this.totalCount = totalCount; 48 | } 49 | 50 | public int getOffset() { 51 | return offset; 52 | } 53 | 54 | public void setOffset(int offset) { 55 | this.offset = offset; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/main/java/com/pblog/core/utils/DateFormatUtils.java: -------------------------------------------------------------------------------- 1 | package com.pblog.core.utils; 2 | 3 | import java.text.ParseException; 4 | import java.text.SimpleDateFormat; 5 | import java.util.Calendar; 6 | import java.util.Date; 7 | 8 | public class DateFormatUtils { 9 | public static Long HOURS_LONG = 3600000L; 10 | 11 | /** 12 | * 取得时间的年和月 13 | * @param date 日期 14 | * @return 15 | */ 16 | public static String formatToYearMonth(Date date){ 17 | SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM"); 18 | 19 | return dateFormat.format(date); 20 | } 21 | 22 | /** 23 | * 取得日 24 | * @param date 日期 25 | */ 26 | public static String formatToDay(Date date){ 27 | SimpleDateFormat dateFormat = new SimpleDateFormat("dd"); 28 | 29 | return dateFormat.format(date); 30 | } 31 | 32 | /** 33 | * 取得小时 34 | * @param date 35 | * @return 36 | */ 37 | public static Integer formatToHour(Date date) { 38 | SimpleDateFormat dateFormat = new SimpleDateFormat("HH"); 39 | 40 | return Integer.valueOf(dateFormat.format(date)); 41 | } 42 | 43 | /** 44 | * 字符串转日期格式(格式:yyyy-MM) 45 | * @param dateStr 日期字符串 46 | * @throws ParseException 47 | */ 48 | public static Date formatStrToYM(String dateStr) throws ParseException { 49 | SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM"); 50 | 51 | return sdf.parse(dateStr); 52 | } 53 | 54 | /** 55 | * 为时间类型增加月份 56 | * @param timeStamp 时间 57 | * @param number 增加月份数 58 | * @throws ParseException 59 | */ 60 | public static Date addMonth(String timeStamp, int number) throws ParseException { 61 | SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM"); 62 | Date date = sdf.parse(timeStamp); 63 | Calendar calendar = Calendar.getInstance(); 64 | 65 | calendar.setTime(date); 66 | calendar.add(Calendar.MONTH, number); 67 | date = calendar.getTime(); 68 | 69 | return date; 70 | } 71 | 72 | /** 73 | * 74 | * 判断日期相减是否大于1小时 75 | * @param minuendDate 被减数 76 | * @param subtrahendDate 减数 77 | * @return 如果间隔大于等于1小时,则返回true; 如果间隔小于1小时,则返回false 78 | */ 79 | public static boolean isThanOneHour(Date minuendDate, Date subtrahendDate){ 80 | Long minuendLong = minuendDate.getTime(); 81 | Long subtrahendLong = subtrahendDate.getTime(); 82 | 83 | Long result = minuendLong - subtrahendLong; 84 | if((result / HOURS_LONG) < 1){ 85 | return false; 86 | }else{ 87 | return true; 88 | } 89 | } 90 | 91 | 92 | } 93 | -------------------------------------------------------------------------------- /src/main/java/com/pblog/core/utils/GenerateUtils.java: -------------------------------------------------------------------------------- 1 | package com.pblog.core.utils; 2 | 3 | import com.google.common.collect.Lists; 4 | import org.apache.commons.lang.StringUtils; 5 | 6 | import javax.servlet.http.HttpServletRequest; 7 | import java.text.ParseException; 8 | import java.util.Date; 9 | import java.util.List; 10 | 11 | public class GenerateUtils { 12 | 13 | /** 14 | * 以逗号分割字符串 15 | * @param tags 16 | * @return 17 | */ 18 | public static List spiltStringByComma(String tags){ 19 | List tagList = Lists.newArrayList(); 20 | if(null != tags){ 21 | String[] regexStr = tags.split(","); 22 | for (String str : regexStr){ 23 | tagList.add(str); 24 | } 25 | } 26 | return tagList; 27 | } 28 | 29 | /** 30 | * 获取访客IP 31 | * @param request 32 | * @return 33 | */ 34 | public static String getIpAddress(HttpServletRequest request){ 35 | String ip = request.getHeader("X-Real-IP"); 36 | if (!StringUtils.isBlank(ip) && !"unknown".equalsIgnoreCase(ip)) { 37 | return ip; 38 | } 39 | ip = request.getHeader("X-Forwarded-For"); 40 | if (!StringUtils.isBlank(ip) && !"unknown".equalsIgnoreCase(ip)) { 41 | // 多次反向代理后会有多个IP值,第一个为真实IP。 42 | int index = ip.indexOf(','); 43 | if (index != -1) { 44 | return ip.substring(0, index); 45 | } else { 46 | return ip; 47 | } 48 | } else { 49 | return request.getRemoteAddr(); 50 | } 51 | } 52 | 53 | public static boolean judgeTimeStamp(String timeStamp){ 54 | try { 55 | Date date = DateFormatUtils.formatStrToYM(timeStamp); 56 | if(date.compareTo(new Date()) == -1){ 57 | return true; 58 | }else{ 59 | return false; 60 | } 61 | } catch (ParseException e) { 62 | e.printStackTrace(); 63 | } 64 | 65 | return false; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/main/java/com/pblog/core/utils/ImageFormatUtils.java: -------------------------------------------------------------------------------- 1 | package com.pblog.core.utils; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | 6 | import javax.imageio.ImageIO; 7 | import java.awt.*; 8 | import java.awt.image.BufferedImage; 9 | import java.io.File; 10 | import java.io.IOException; 11 | 12 | /** 13 | * 图片格式类,暂时把水印位置,水印颜色,水印字体写死。以后如果有时间可以考虑增加前台页面操作。 14 | */ 15 | public class ImageFormatUtils { 16 | 17 | private static Logger logger = LoggerFactory.getLogger(ImageFormatUtils.class); 18 | 19 | private static Font font = new Font(Font.MONOSPACED, Font.BOLD, 16);// 添加字体的属性设置 20 | 21 | 22 | /** 23 | * 为图片增加水印 24 | * @param uploadFile 图片 25 | * @return 26 | */ 27 | public static void waterMark(File uploadFile) throws IOException { 28 | BufferedImage uploadImage = ImageIO.read(uploadFile); 29 | int width = uploadImage.getWidth(); 30 | int height = uploadImage.getHeight(); 31 | 32 | BufferedImage combined = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); 33 | Graphics g = combined.getGraphics(); 34 | g.drawImage(uploadImage, 0, 0, null); 35 | g.setFont(font); 36 | g.setColor(new Color(216, 216, 210)); 37 | g.drawString("PBlog | www.pelinli.com", 5, height - 24); 38 | g.drawString("https://github.com/penglongli", 5, height - 10); 39 | 40 | ImageIO.write(combined, "png", uploadFile); 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/com/pblog/core/utils/ImageUploadUtils.java: -------------------------------------------------------------------------------- 1 | package com.pblog.core.utils; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | import org.springframework.stereotype.Component; 6 | import org.springframework.web.multipart.MultipartFile; 7 | 8 | import java.io.File; 9 | import java.io.IOException; 10 | import java.util.UUID; 11 | 12 | @Component 13 | public class ImageUploadUtils { 14 | 15 | private static Logger logger = LoggerFactory.getLogger(ImageUploadUtils.class); 16 | 17 | public static String uploadImage(MultipartFile file, String staticPath) throws IOException { 18 | String fileName = makeFileName(file); 19 | File tempFile = new File(staticPath, fileName); 20 | 21 | boolean success = tempFile.createNewFile(); 22 | if (success) { 23 | file.transferTo(tempFile); 24 | 25 | ImageFormatUtils.waterMark(tempFile); 26 | } else { 27 | logger.info("image failed to upload!"); 28 | } 29 | 30 | return fileName; 31 | } 32 | 33 | //获得文件扩展名 34 | private static String getSuffix(MultipartFile file) { 35 | String fileName = file.getOriginalFilename(); 36 | int n = fileName.indexOf("."); 37 | 38 | return fileName.substring(n); 39 | } 40 | 41 | //重新生成文件名称 42 | private static String makeFileName(MultipartFile file) { 43 | String suffix = getSuffix(file); 44 | String fileName = UUID.randomUUID().toString().replace("-", ""); 45 | 46 | return fileName + suffix; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/com/pblog/core/utils/MultipartFileValidator.java: -------------------------------------------------------------------------------- 1 | package com.pblog.core.utils; 2 | 3 | 4 | import org.apache.commons.lang.ArrayUtils; 5 | import org.springframework.web.multipart.MultipartFile; 6 | 7 | public class MultipartFileValidator { 8 | 9 | private final static long MAX_SIZE = 5 * 1024 * 1024; 10 | 11 | //文件上传上限 12 | private static long maxSize = MAX_SIZE; 13 | 14 | //可接受的content-type 15 | private static String[] allowedContentTypes = {"image/jpeg", "image/jpg", "image/png", "image/gif"}; 16 | 17 | public static void validate(MultipartFile file) throws RuntimeException { 18 | 19 | if (!ArrayUtils.contains(allowedContentTypes, file.getContentType())) { 20 | throw new RuntimeException("The content type is not a valid content type!"); 21 | } 22 | 23 | if(file.getSize() > maxSize) { 24 | throw new RuntimeException("The file uploaded is out of max file size!"); 25 | } 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/com/pblog/core/utils/RandomUtils.java: -------------------------------------------------------------------------------- 1 | package com.pblog.core.utils; 2 | 3 | import com.google.common.collect.Sets; 4 | 5 | import java.util.Random; 6 | import java.util.Set; 7 | 8 | /** 9 | * 生成随机数 10 | */ 11 | public class RandomUtils { 12 | 13 | /** 14 | * 这是典型的随机洗牌算法。 15 | * 流程是从备选数组中选择一个放入目标数组中,将选取的数组从备选数组移除(放至最后,并缩小选择区域) 16 | * 算法时间复杂度O(n) 17 | * @return 随机8为不重复数组 18 | */ 19 | public static String generateNumber() { 20 | String no=""; 21 | //初始化备选数组 22 | int[] defaultNums = new int[10]; 23 | for (int i = 0; i < defaultNums.length; i++) { 24 | defaultNums[i] = i; 25 | } 26 | 27 | Random random = new Random(); 28 | int[] nums = new int[LENGTH]; 29 | //默认数组中可以选择的部分长度 30 | int canBeUsed = 10; 31 | //填充目标数组 32 | for (int i = 0; i < nums.length; i++) { 33 | //将随机选取的数字存入目标数组 34 | int index = random.nextInt(canBeUsed); 35 | nums[i] = defaultNums[index]; 36 | //将已用过的数字扔到备选数组最后,并减小可选区域 37 | swap(index, canBeUsed - 1, defaultNums); 38 | canBeUsed--; 39 | } 40 | if (nums.length>0) { 41 | for (int i = 0; i < nums.length; i++) { 42 | no+=nums[i]; 43 | } 44 | } 45 | 46 | return no; 47 | } 48 | private static final int LENGTH = 8; 49 | 50 | private static void swap(int i, int j, int[] nums) { 51 | int temp = nums[i]; 52 | nums[i] = nums[j]; 53 | nums[j] = temp; 54 | } 55 | 56 | public static String generateNumber2() { 57 | String no=""; 58 | int num[]=new int[8]; 59 | int c=0; 60 | for (int i = 0; i < 8; i++) { 61 | num[i] = new Random().nextInt(10); 62 | c = num[i]; 63 | for (int j = 0; j < i; j++) { 64 | if (num[j] == c) { 65 | i--; 66 | break; 67 | } 68 | } 69 | } 70 | if (num.length>0) { 71 | for (int i = 0; i < num.length; i++) { 72 | no+=num[i]; 73 | } 74 | } 75 | return no; 76 | } 77 | 78 | public static void main(String[] args) { 79 | Set strSet = Sets.newHashSet(); 80 | for(int i = 0; i < 10000; i++){ 81 | strSet.add(generateNumber2()); 82 | } 83 | Object[] strList = strSet.toArray(); 84 | System.out.println(strList.length); 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /src/main/java/com/pblog/core/utils/ReflectUtils.java: -------------------------------------------------------------------------------- 1 | package com.pblog.core.utils; 2 | 3 | import java.lang.reflect.Field; 4 | 5 | public class ReflectUtils { 6 | 7 | public static Object getFieldValue(Object obj, String fieldName){ 8 | Object result = null; 9 | 10 | Field field = ReflectUtils.getField(obj, fieldName); 11 | if(field != null){ 12 | field.setAccessible(true); 13 | 14 | try { 15 | result = field.get(obj); 16 | } catch (IllegalAccessException e) { 17 | e.printStackTrace(); 18 | } catch (IllegalArgumentException e){ 19 | e.printStackTrace(); 20 | } 21 | } 22 | return result; 23 | } 24 | 25 | public static void setFieldValue(Object obj, String fieldName, Object fieldValue){ 26 | Field field = ReflectUtils.getField(obj, fieldName); 27 | 28 | if(field != null){ 29 | try { 30 | field.setAccessible(true); 31 | field.set(obj, fieldValue); 32 | } catch (IllegalAccessException e) { 33 | e.printStackTrace(); 34 | } catch (IllegalArgumentException e){ 35 | e.printStackTrace(); 36 | } 37 | } 38 | } 39 | 40 | private static Field getField(Object obj, String fieldName){ 41 | Field field = null; 42 | 43 | for(Class clazz = obj.getClass(); clazz != Object.class; clazz = clazz.getSuperclass()){ 44 | try { 45 | field = clazz.getDeclaredField(fieldName); 46 | } catch (NoSuchFieldException e) { 47 | 48 | } 49 | } 50 | return field; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/main/java/com/pblog/dao/ArticleInfoMapper.java: -------------------------------------------------------------------------------- 1 | package com.pblog.dao; 2 | 3 | import com.pblog.core.orm.PageRequest; 4 | import com.pblog.domain.ArticleInfo; 5 | import org.apache.ibatis.annotations.Param; 6 | import org.springframework.stereotype.Repository; 7 | 8 | import java.util.Date; 9 | import java.util.List; 10 | 11 | @Repository 12 | public interface ArticleInfoMapper { 13 | 14 | int insert(ArticleInfo articleInfo); 15 | 16 | List findList(); 17 | 18 | List findListByCategorySlug(Long categorySlug); 19 | 20 | List findTopTenByCreateTimeDesc(); 21 | 22 | ArticleInfo findBySlug(Long slug); 23 | 24 | ArticleInfo findById(Integer id); 25 | 26 | List page(PageRequest pageRequest); 27 | 28 | List findByCreateTimeDesc(); 29 | 30 | int update(ArticleInfo articleInfo); 31 | 32 | List findArticleListByMonth(@Param("startTime") Date startTime, @Param("endTime") Date endTime); 33 | } -------------------------------------------------------------------------------- /src/main/java/com/pblog/dao/ArticleReadLogMapper.java: -------------------------------------------------------------------------------- 1 | package com.pblog.dao; 2 | 3 | import com.pblog.domain.ArticleReadLog; 4 | 5 | public interface ArticleReadLogMapper { 6 | 7 | int insert(ArticleReadLog record); 8 | 9 | /** 10 | * 查看文章点击次数 11 | * @param articleSlug 文章slug 12 | * @return 点击次数 13 | */ 14 | Long queryForClickNumByArticle(Long articleSlug); 15 | } -------------------------------------------------------------------------------- /src/main/java/com/pblog/dao/AuthorInfoMapper.java: -------------------------------------------------------------------------------- 1 | package com.pblog.dao; 2 | 3 | import com.pblog.domain.AuthorInfo; 4 | 5 | public interface AuthorInfoMapper { 6 | int deleteByPrimaryKey(Integer id); 7 | 8 | int insert(AuthorInfo record); 9 | 10 | int insertSelective(AuthorInfo record); 11 | 12 | AuthorInfo selectByPrimaryKey(Integer id); 13 | 14 | int updateByPrimaryKeySelective(AuthorInfo record); 15 | 16 | int updateByPrimaryKey(AuthorInfo record); 17 | } -------------------------------------------------------------------------------- /src/main/java/com/pblog/dao/BookInfoMapper.java: -------------------------------------------------------------------------------- 1 | package com.pblog.dao; 2 | 3 | import com.pblog.domain.BookInfo; 4 | 5 | import java.util.List; 6 | 7 | public interface BookInfoMapper { 8 | int deleteByPrimaryKey(Integer id); 9 | 10 | int insert(BookInfo record); 11 | 12 | BookInfo selectByPrimaryKey(Integer id); 13 | 14 | int updateByPrimaryKey(BookInfo record); 15 | 16 | List selectAll(); 17 | 18 | BookInfo selectBySlug(Long slug); 19 | } -------------------------------------------------------------------------------- /src/main/java/com/pblog/dao/BookReadLogMapper.java: -------------------------------------------------------------------------------- 1 | package com.pblog.dao; 2 | 3 | import com.pblog.domain.BookReadLog; 4 | 5 | public interface BookReadLogMapper { 6 | int insert(BookReadLog record); 7 | 8 | BookReadLog selectByPrimaryKey(Long id); 9 | 10 | Long selectNumById(Integer id); 11 | } -------------------------------------------------------------------------------- /src/main/java/com/pblog/dao/BookTableMapper.java: -------------------------------------------------------------------------------- 1 | package com.pblog.dao; 2 | 3 | import com.pblog.domain.BookTable; 4 | 5 | import java.util.List; 6 | 7 | public interface BookTableMapper { 8 | int deleteByPrimaryKey(Integer id); 9 | 10 | int insert(BookTable record); 11 | 12 | BookTable selectByPrimaryKey(Integer id); 13 | 14 | int updateByPrimaryKey(BookTable record); 15 | 16 | List selectAll(); 17 | } -------------------------------------------------------------------------------- /src/main/java/com/pblog/dao/CategoryInfoMapper.java: -------------------------------------------------------------------------------- 1 | package com.pblog.dao; 2 | 3 | import com.pblog.domain.CategoryInfo; 4 | 5 | import java.util.List; 6 | 7 | public interface CategoryInfoMapper { 8 | 9 | CategoryInfo selectBySlug(Long slug); 10 | 11 | List selectAll(); 12 | 13 | int save(CategoryInfo categoryInfo); 14 | 15 | void update(CategoryInfo categoryInfo); 16 | 17 | void updateBySlug(CategoryInfo categoryInfo); 18 | } -------------------------------------------------------------------------------- /src/main/java/com/pblog/dao/PicInfoMapper.java: -------------------------------------------------------------------------------- 1 | package com.pblog.dao; 2 | 3 | import com.pblog.domain.PicInfo; 4 | 5 | import java.util.List; 6 | 7 | public interface PicInfoMapper { 8 | int deleteByPrimaryKey(Long id); 9 | 10 | int insert(PicInfo record); 11 | 12 | List selectAll(); 13 | 14 | PicInfo selectById(Long id); 15 | } -------------------------------------------------------------------------------- /src/main/java/com/pblog/dao/RecordInfoMapper.java: -------------------------------------------------------------------------------- 1 | package com.pblog.dao; 2 | 3 | import com.pblog.domain.RecordInfo; 4 | 5 | import java.util.List; 6 | 7 | public interface RecordInfoMapper { 8 | int deleteByPrimaryKey(Integer id); 9 | 10 | int insert(RecordInfo record); 11 | 12 | int updateByPrimaryKey(RecordInfo record); 13 | 14 | List selectAll(); 15 | 16 | RecordInfo selectById(Integer id); 17 | } -------------------------------------------------------------------------------- /src/main/java/com/pblog/dao/SlugInfoMapper.java: -------------------------------------------------------------------------------- 1 | package com.pblog.dao; 2 | 3 | import com.pblog.domain.SlugInfo; 4 | 5 | public interface SlugInfoMapper { 6 | 7 | int insert(SlugInfo record); 8 | 9 | SlugInfo queryById(Integer id); 10 | } -------------------------------------------------------------------------------- /src/main/java/com/pblog/dao/TagInfoMapper.java: -------------------------------------------------------------------------------- 1 | package com.pblog.dao; 2 | 3 | import com.pblog.domain.TagInfo; 4 | 5 | public interface TagInfoMapper { 6 | int deleteByPrimaryKey(Integer id); 7 | 8 | int insert(TagInfo record); 9 | 10 | int insertSelective(TagInfo record); 11 | 12 | TagInfo selectByPrimaryKey(Integer id); 13 | 14 | int updateByPrimaryKeySelective(TagInfo record); 15 | 16 | int updateByPrimaryKey(TagInfo record); 17 | } -------------------------------------------------------------------------------- /src/main/java/com/pblog/dao/WebsiteTrafficMapper.java: -------------------------------------------------------------------------------- 1 | package com.pblog.dao; 2 | 3 | import com.pblog.domain.WebsiteTraffic; 4 | 5 | import java.util.List; 6 | 7 | public interface WebsiteTrafficMapper { 8 | 9 | int insert(WebsiteTraffic record); 10 | 11 | List queryByIpAddress(String ipAddress); 12 | } -------------------------------------------------------------------------------- /src/main/java/com/pblog/dao/mapping/ArticleReadLogMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | id, articleSlug, ipAddress, createTime, type 14 | 15 | 16 | 17 | insert into article_read_log (id, articleSlug, ipAddress, 18 | createTime, type) 19 | values (#{id,jdbcType=BIGINT}, #{articleSlug,jdbcType=BIGINT}, #{ipAddress,jdbcType=VARCHAR}, 20 | #{createTime,jdbcType=TIMESTAMP}, #{type,jdbcType=INTEGER}) 21 | 22 | 23 | 27 | 28 | -------------------------------------------------------------------------------- /src/main/java/com/pblog/dao/mapping/BookReadLogMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | id, bookId, ipAddress, createTime, type 13 | 14 | 15 | 21 | 22 | 23 | 24 | insert into book_read_log (id, bookId, ipAddress, 25 | createTime, type) 26 | values (#{id,jdbcType=BIGINT}, #{bookId,jdbcType=INTEGER}, #{ipAddress,jdbcType=VARCHAR}, 27 | #{createTime,jdbcType=TIMESTAMP}, #{type,jdbcType=INTEGER}) 28 | 29 | 30 | 33 | 34 | -------------------------------------------------------------------------------- /src/main/java/com/pblog/dao/mapping/BookTableMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | id, bookName, bookUrl, bookBanner 13 | 14 | 15 | 21 | 22 | delete from book_table 23 | where id = #{id,jdbcType=INTEGER} 24 | 25 | 26 | insert into book_table (id, bookName, bookUrl, 27 | bookBanner) 28 | values (#{id,jdbcType=INTEGER}, #{bookName,jdbcType=VARCHAR}, #{bookUrl,jdbcType=VARCHAR}, 29 | #{bookBanner,jdbcType=VARCHAR}) 30 | 31 | 32 | 33 | update book_table 34 | set bookName = #{bookName,jdbcType=VARCHAR}, 35 | bookUrl = #{bookUrl,jdbcType=VARCHAR}, 36 | bookBanner = #{bookBanner,jdbcType=VARCHAR} 37 | where id = #{id,jdbcType=INTEGER} 38 | 39 | 40 | 43 | -------------------------------------------------------------------------------- /src/main/java/com/pblog/dao/mapping/CategoryInfoMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | id, createTime, title, slug 7 | 8 | 9 | 15 | 16 | 21 | 22 | 23 | 24 | SELECT LAST_INSERT_ID() AS id 25 | 26 | insert into category_info 27 | () 28 | VALUES 29 | (#{id, jdbcType=INTEGER}, #{createTime, jdbcType=DATE}, #{title, jdbcType=VARCHAR}, #{slug, jdbcType=BIGINT}) 30 | 31 | 32 | 33 | update category_info 34 | SET `title` = #{title, jdbcType=VARCHAR}, `slug` = #{slug, jdbcType=BIGINT} 35 | WHERE `id` = #{id, jdbcType=INTEGER} 36 | 37 | 38 | 39 | update category_info 40 | SET `title` = #{title, jdbcType=VARCHAR} 41 | WHERE `slug` = #{slug, jdbcType=BIGINT} 42 | 43 | 44 | -------------------------------------------------------------------------------- /src/main/java/com/pblog/dao/mapping/PicInfoMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | id, relativePath, physicalPath, createTime 14 | 15 | 16 | 17 | delete from pic_info 18 | where id = #{id,jdbcType=BIGINT} 19 | 20 | 21 | insert into pic_info (id, relativePath, physicalPath, 22 | createTime) 23 | values (#{id,jdbcType=BIGINT}, #{relativePath,jdbcType=VARCHAR}, #{physicalPath,jdbcType=VARCHAR}, 24 | #{createTime,jdbcType=DATE}) 25 | 26 | 27 | 33 | 34 | 40 | 41 | -------------------------------------------------------------------------------- /src/main/java/com/pblog/dao/mapping/RecordInfoMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | id, title, createTime, content 13 | 14 | 15 | 16 | delete from record_info 17 | where id = #{id,jdbcType=INTEGER} 18 | 19 | 20 | insert into record_info (id, title, createTime, content) 21 | values (#{id,jdbcType=INTEGER}, #{title,jdbcType=VARCHAR}, #{createTime,jdbcType=TIMESTAMP}, 22 | #{content}) 23 | 24 | 25 | 26 | update record_info 27 | set title = #{title,jdbcType=VARCHAR}, 28 | createTime = #{createTime,jdbcType=TIMESTAMP}, 29 | content = #{content} 30 | where id = #{id,jdbcType=INTEGER} 31 | 32 | 33 | 36 | 37 | 40 | -------------------------------------------------------------------------------- /src/main/java/com/pblog/dao/mapping/SlugInfoMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | insert into slug_info (id, slug) 7 | values (#{id,jdbcType=INTEGER}, #{slug,jdbcType=BIGINT}) 8 | 9 | 10 | 13 | -------------------------------------------------------------------------------- /src/main/java/com/pblog/dao/mapping/TagInfoMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | id, createTime, title 11 | 12 | 18 | 19 | delete from tag_info 20 | where id = #{id,jdbcType=INTEGER} 21 | 22 | 23 | insert into tag_info (id, createTime, title 24 | ) 25 | values (#{id,jdbcType=INTEGER}, #{createTime,jdbcType=TIMESTAMP}, #{title,jdbcType=VARCHAR} 26 | ) 27 | 28 | 29 | insert into tag_info 30 | 31 | 32 | id, 33 | 34 | 35 | createTime, 36 | 37 | 38 | title, 39 | 40 | 41 | 42 | 43 | #{id,jdbcType=INTEGER}, 44 | 45 | 46 | #{createTime,jdbcType=TIMESTAMP}, 47 | 48 | 49 | #{title,jdbcType=VARCHAR}, 50 | 51 | 52 | 53 | 54 | update tag_info 55 | 56 | 57 | createTime = #{createTime,jdbcType=TIMESTAMP}, 58 | 59 | 60 | title = #{title,jdbcType=VARCHAR}, 61 | 62 | 63 | where id = #{id,jdbcType=INTEGER} 64 | 65 | 66 | update tag_info 67 | set createTime = #{createTime,jdbcType=TIMESTAMP}, 68 | title = #{title,jdbcType=VARCHAR} 69 | where id = #{id,jdbcType=INTEGER} 70 | 71 | -------------------------------------------------------------------------------- /src/main/java/com/pblog/dao/mapping/WebsiteTrafficMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | insert into website_traffic (id, ipAddress, createTime, 7 | operateSystem, browser) 8 | values (#{id,jdbcType=BIGINT}, #{ipAddress,jdbcType=VARCHAR}, #{createTime,jdbcType=TIMESTAMP}, 9 | #{operateSystem,jdbcType=VARCHAR}, #{browser,jdbcType=VARCHAR}) 10 | 11 | 12 | 17 | 18 | -------------------------------------------------------------------------------- /src/main/java/com/pblog/domain/ArticleReadLog.java: -------------------------------------------------------------------------------- 1 | package com.pblog.domain; 2 | 3 | import java.util.Date; 4 | 5 | public class ArticleReadLog { 6 | private Long id; 7 | 8 | private Long articleSlug; 9 | 10 | private String ipAddress; 11 | 12 | private Date createTime; 13 | 14 | private Integer type; 15 | 16 | public Long getId() { 17 | return id; 18 | } 19 | 20 | public void setId(Long id) { 21 | this.id = id; 22 | } 23 | 24 | public Long getArticleSlug() { 25 | return articleSlug; 26 | } 27 | 28 | public void setArticleSlug(Long articleSlug) { 29 | this.articleSlug = articleSlug; 30 | } 31 | 32 | public String getIpAddress() { 33 | return ipAddress; 34 | } 35 | 36 | public void setIpAddress(String ipAddress) { 37 | this.ipAddress = ipAddress == null ? null : ipAddress.trim(); 38 | } 39 | 40 | public Date getCreateTime() { 41 | return createTime; 42 | } 43 | 44 | public void setCreateTime(Date createTime) { 45 | this.createTime = createTime; 46 | } 47 | 48 | public Integer getType() { 49 | return type; 50 | } 51 | 52 | public void setType(Integer type) { 53 | this.type = type; 54 | } 55 | 56 | public enum ArticleReadType { 57 | TYPE_READ(1), 58 | 59 | TYPE_LIKE(2), 60 | 61 | TYPE_THUMB(3); 62 | 63 | private Integer id; 64 | 65 | ArticleReadType(Integer id){ 66 | this.id = id; 67 | } 68 | 69 | public Integer getId(){ 70 | return id; 71 | } 72 | } 73 | } -------------------------------------------------------------------------------- /src/main/java/com/pblog/domain/AuthorInfo.java: -------------------------------------------------------------------------------- 1 | package com.pblog.domain; 2 | 3 | public class AuthorInfo { 4 | private Integer id; 5 | 6 | private String name; 7 | 8 | private String motto; 9 | 10 | private String email; 11 | 12 | private String address; 13 | 14 | private String github; 15 | 16 | private String zhihu; 17 | 18 | private String csdn; 19 | 20 | private String headImage; 21 | 22 | public Integer getId() { 23 | return id; 24 | } 25 | 26 | public void setId(Integer id) { 27 | this.id = id; 28 | } 29 | 30 | public String getName() { 31 | return name; 32 | } 33 | 34 | public void setName(String name) { 35 | this.name = name == null ? null : name.trim(); 36 | } 37 | 38 | public String getMotto() { 39 | return motto; 40 | } 41 | 42 | public void setMotto(String motto) { 43 | this.motto = motto == null ? null : motto.trim(); 44 | } 45 | 46 | public String getEmail() { 47 | return email; 48 | } 49 | 50 | public void setEmail(String email) { 51 | this.email = email == null ? null : email.trim(); 52 | } 53 | 54 | public String getAddress() { 55 | return address; 56 | } 57 | 58 | public void setAddress(String address) { 59 | this.address = address == null ? null : address.trim(); 60 | } 61 | 62 | public String getGithub() { 63 | return github; 64 | } 65 | 66 | public void setGithub(String github) { 67 | this.github = github == null ? null : github.trim(); 68 | } 69 | 70 | public String getZhihu() { 71 | return zhihu; 72 | } 73 | 74 | public void setZhihu(String zhihu) { 75 | this.zhihu = zhihu == null ? null : zhihu.trim(); 76 | } 77 | 78 | public String getCsdn() { 79 | return csdn; 80 | } 81 | 82 | public void setCsdn(String csdn) { 83 | this.csdn = csdn == null ? null : csdn.trim(); 84 | } 85 | 86 | public String getHeadImage() { 87 | return headImage; 88 | } 89 | 90 | public void setHeadImage(String headImage) { 91 | this.headImage = headImage == null ? null : headImage.trim(); 92 | } 93 | } -------------------------------------------------------------------------------- /src/main/java/com/pblog/domain/BookInfo.java: -------------------------------------------------------------------------------- 1 | package com.pblog.domain; 2 | 3 | import java.util.Date; 4 | 5 | public class BookInfo { 6 | private Integer id; 7 | 8 | private String title; 9 | 10 | private Date createTime; 11 | 12 | private Long slug; 13 | 14 | private String banner; 15 | 16 | private Integer thumb = 0; 17 | 18 | private String introduction; 19 | 20 | private String content; 21 | 22 | public Integer getId() { 23 | return id; 24 | } 25 | 26 | public void setId(Integer id) { 27 | this.id = id; 28 | } 29 | 30 | public String getTitle() { 31 | return title; 32 | } 33 | 34 | public void setTitle(String title) { 35 | this.title = title == null ? null : title.trim(); 36 | } 37 | 38 | public Date getCreateTime() { 39 | return createTime; 40 | } 41 | 42 | public void setCreateTime(Date createTime) { 43 | this.createTime = createTime; 44 | } 45 | 46 | public Long getSlug() { 47 | return slug; 48 | } 49 | 50 | public void setSlug(Long slug) { 51 | this.slug = slug; 52 | } 53 | 54 | public String getBanner() { 55 | return banner; 56 | } 57 | 58 | public void setBanner(String banner) { 59 | this.banner = banner == null ? null : banner.trim(); 60 | } 61 | 62 | public Integer getThumb() { 63 | return thumb; 64 | } 65 | 66 | public void setThumb(Integer thumb) { 67 | this.thumb = thumb; 68 | } 69 | 70 | public String getIntroduction() { 71 | return introduction; 72 | } 73 | 74 | public void setIntroduction(String introduction) { 75 | this.introduction = introduction == null ? null : introduction.trim(); 76 | } 77 | 78 | public String getContent() { 79 | return content; 80 | } 81 | 82 | public void setContent(String content) { 83 | this.content = content == null ? null : content.trim(); 84 | } 85 | } -------------------------------------------------------------------------------- /src/main/java/com/pblog/domain/BookReadLog.java: -------------------------------------------------------------------------------- 1 | package com.pblog.domain; 2 | 3 | import java.util.Date; 4 | 5 | public class BookReadLog { 6 | private Long id; 7 | 8 | private Integer bookId; 9 | 10 | private String ipAddress; 11 | 12 | private Date createTime; 13 | 14 | private Integer type; 15 | 16 | public Long getId() { 17 | return id; 18 | } 19 | 20 | public void setId(Long id) { 21 | this.id = id; 22 | } 23 | 24 | public Integer getBookId() { 25 | return bookId; 26 | } 27 | 28 | public void setBookId(Integer bookId) { 29 | this.bookId = bookId; 30 | } 31 | 32 | public String getIpAddress() { 33 | return ipAddress; 34 | } 35 | 36 | public void setIpAddress(String ipAddress) { 37 | this.ipAddress = ipAddress == null ? null : ipAddress.trim(); 38 | } 39 | 40 | public Date getCreateTime() { 41 | return createTime; 42 | } 43 | 44 | public void setCreateTime(Date createTime) { 45 | this.createTime = createTime; 46 | } 47 | 48 | public Integer getType() { 49 | return type; 50 | } 51 | 52 | public void setType(Integer type) { 53 | this.type = type; 54 | } 55 | 56 | public enum BookReadType { 57 | TYPE_READ(1), 58 | 59 | TYPE_LIKE(2), 60 | 61 | TYPE_THUMB(3); 62 | 63 | private Integer id; 64 | 65 | BookReadType(Integer id){ 66 | this.id = id; 67 | } 68 | 69 | public Integer getId(){ 70 | return id; 71 | } 72 | } 73 | } -------------------------------------------------------------------------------- /src/main/java/com/pblog/domain/BookTable.java: -------------------------------------------------------------------------------- 1 | package com.pblog.domain; 2 | 3 | public class BookTable { 4 | private Integer id; 5 | 6 | private String bookName; 7 | 8 | private String bookUrl; 9 | 10 | private String bookBanner; 11 | 12 | public Integer getId() { 13 | return id; 14 | } 15 | 16 | public void setId(Integer id) { 17 | this.id = id; 18 | } 19 | 20 | public String getBookName() { 21 | return bookName; 22 | } 23 | 24 | public void setBookName(String bookName) { 25 | this.bookName = bookName == null ? null : bookName.trim(); 26 | } 27 | 28 | public String getBookUrl() { 29 | return bookUrl; 30 | } 31 | 32 | public void setBookUrl(String bookUrl) { 33 | this.bookUrl = bookUrl == null ? null : bookUrl.trim(); 34 | } 35 | 36 | public String getBookBanner() { 37 | return bookBanner; 38 | } 39 | 40 | public void setBookBanner(String bookBanner) { 41 | this.bookBanner = bookBanner == null ? null : bookBanner.trim(); 42 | } 43 | } -------------------------------------------------------------------------------- /src/main/java/com/pblog/domain/CategoryInfo.java: -------------------------------------------------------------------------------- 1 | package com.pblog.domain; 2 | 3 | import java.util.Date; 4 | 5 | public class CategoryInfo { 6 | private Integer id; 7 | 8 | private Date createTime; 9 | 10 | private String title; 11 | 12 | private Long slug; 13 | 14 | public Integer getId() { 15 | return id; 16 | } 17 | 18 | public void setId(Integer id) { 19 | this.id = id; 20 | } 21 | 22 | public Date getCreateTime() { 23 | return createTime; 24 | } 25 | 26 | public void setCreateTime(Date createTime) { 27 | this.createTime = createTime; 28 | } 29 | 30 | public String getTitle() { 31 | return title; 32 | } 33 | 34 | public void setTitle(String title) { 35 | this.title = title == null ? null : title.trim(); 36 | } 37 | 38 | public Long getSlug() { 39 | return slug; 40 | } 41 | 42 | public void setSlug(Long slug) { 43 | this.slug = slug; 44 | } 45 | } -------------------------------------------------------------------------------- /src/main/java/com/pblog/domain/PicInfo.java: -------------------------------------------------------------------------------- 1 | package com.pblog.domain; 2 | 3 | import java.util.Date; 4 | 5 | public class PicInfo { 6 | private Long id; 7 | 8 | private String relativePath; 9 | 10 | private String physicalPath; 11 | 12 | private Date createTime; 13 | 14 | public Long getId() { 15 | return id; 16 | } 17 | 18 | public void setId(Long id) { 19 | this.id = id; 20 | } 21 | 22 | public String getRelativePath() { 23 | return relativePath; 24 | } 25 | 26 | public void setRelativePath(String relativePath) { 27 | this.relativePath = relativePath == null ? null : relativePath.trim(); 28 | } 29 | 30 | public String getPhysicalPath() { 31 | return physicalPath; 32 | } 33 | 34 | public void setPhysicalPath(String physicalPath) { 35 | this.physicalPath = physicalPath == null ? null : physicalPath.trim(); 36 | } 37 | 38 | public Date getCreateTime() { 39 | return createTime; 40 | } 41 | 42 | public void setCreateTime(Date createTime) { 43 | this.createTime = createTime; 44 | } 45 | } -------------------------------------------------------------------------------- /src/main/java/com/pblog/domain/RecordInfo.java: -------------------------------------------------------------------------------- 1 | package com.pblog.domain; 2 | 3 | import java.util.Date; 4 | 5 | public class RecordInfo { 6 | private Integer id; 7 | 8 | private String title; 9 | 10 | private Date createTime; 11 | 12 | private String content; 13 | 14 | public Integer getId() { 15 | return id; 16 | } 17 | 18 | public void setId(Integer id) { 19 | this.id = id; 20 | } 21 | 22 | public String getTitle() { 23 | return title; 24 | } 25 | 26 | public void setTitle(String title) { 27 | this.title = title == null ? null : title.trim(); 28 | } 29 | 30 | public Date getCreateTime() { 31 | return createTime; 32 | } 33 | 34 | public void setCreateTime(Date createTime) { 35 | this.createTime = createTime; 36 | } 37 | 38 | public String getContent() { 39 | return content; 40 | } 41 | 42 | public void setContent(String content) { 43 | this.content = content == null ? null : content.trim(); 44 | } 45 | } -------------------------------------------------------------------------------- /src/main/java/com/pblog/domain/SlugInfo.java: -------------------------------------------------------------------------------- 1 | package com.pblog.domain; 2 | 3 | public class SlugInfo { 4 | private Integer id; 5 | 6 | private Long slug; 7 | 8 | public Integer getId() { 9 | return id; 10 | } 11 | 12 | public void setId(Integer id) { 13 | this.id = id; 14 | } 15 | 16 | public Long getSlug() { 17 | return slug; 18 | } 19 | 20 | public void setSlug(Long slug) { 21 | this.slug = slug; 22 | } 23 | } -------------------------------------------------------------------------------- /src/main/java/com/pblog/domain/TagInfo.java: -------------------------------------------------------------------------------- 1 | package com.pblog.domain; 2 | 3 | import java.util.Date; 4 | 5 | public class TagInfo { 6 | private Integer id; 7 | 8 | private Date createTime; 9 | 10 | private String title; 11 | 12 | public Integer getId() { 13 | return id; 14 | } 15 | 16 | public void setId(Integer id) { 17 | this.id = id; 18 | } 19 | 20 | public Date getCreateTime() { 21 | return createTime; 22 | } 23 | 24 | public void setCreateTime(Date createTime) { 25 | this.createTime = createTime; 26 | } 27 | 28 | public String getTitle() { 29 | return title; 30 | } 31 | 32 | public void setTitle(String title) { 33 | this.title = title == null ? null : title.trim(); 34 | } 35 | } -------------------------------------------------------------------------------- /src/main/java/com/pblog/domain/WebsiteTraffic.java: -------------------------------------------------------------------------------- 1 | package com.pblog.domain; 2 | 3 | import java.util.Date; 4 | 5 | public class WebsiteTraffic { 6 | private Long id; 7 | 8 | private String ipAddress; 9 | 10 | private Date createTime; 11 | 12 | private String operateSystem; 13 | 14 | private String browser; 15 | 16 | public Long getId() { 17 | return id; 18 | } 19 | 20 | public void setId(Long id) { 21 | this.id = id; 22 | } 23 | 24 | public String getIpAddress() { 25 | return ipAddress; 26 | } 27 | 28 | public void setIpAddress(String ipAddress) { 29 | this.ipAddress = ipAddress == null ? null : ipAddress.trim(); 30 | } 31 | 32 | public Date getCreateTime() { 33 | return createTime; 34 | } 35 | 36 | public void setCreateTime(Date createTime) { 37 | this.createTime = createTime; 38 | } 39 | 40 | public String getOperateSystem() { 41 | return operateSystem; 42 | } 43 | 44 | public void setOperateSystem(String operateSystem) { 45 | this.operateSystem = operateSystem == null ? null : operateSystem.trim(); 46 | } 47 | 48 | public String getBrowser() { 49 | return browser; 50 | } 51 | 52 | public void setBrowser(String browser) { 53 | this.browser = browser == null ? null : browser.trim(); 54 | } 55 | } -------------------------------------------------------------------------------- /src/main/java/com/pblog/service/Article/ArticleInfoService.java: -------------------------------------------------------------------------------- 1 | package com.pblog.service.article; 2 | 3 | import com.pblog.core.orm.PageRequest; 4 | import com.pblog.core.orm.Pagination; 5 | 6 | import javax.servlet.http.HttpServletRequest; 7 | import java.util.List; 8 | 9 | public interface ArticleInfoService { 10 | 11 | ArticleInfoVO findArticleBySlug(Long slug, String ipAddress); 12 | 13 | /** 14 | * 根据pageRequest分页 15 | * @return 分页对象 16 | */ 17 | Pagination page(PageRequest pageRequest, HttpServletRequest request); 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/com/pblog/service/Article/ArticleInfoVO.java: -------------------------------------------------------------------------------- 1 | package com.pblog.service.article; 2 | 3 | import java.util.Date; 4 | import java.util.List; 5 | 6 | public class ArticleInfoVO { 7 | 8 | private String categoryName; 9 | 10 | private Long categorySlug; 11 | 12 | private String title; 13 | 14 | private String description; 15 | 16 | private String content; 17 | 18 | private List tags; 19 | 20 | private Date createTime; 21 | 22 | private Long reviewNum; 23 | 24 | private Integer likeNum; 25 | 26 | private Long articleSlug; 27 | 28 | public String getCategoryName() { 29 | return categoryName; 30 | } 31 | 32 | public void setCategoryName(String categoryName) { 33 | this.categoryName = categoryName; 34 | } 35 | 36 | public String getTitle() { 37 | return title; 38 | } 39 | 40 | public void setTitle(String title) { 41 | this.title = title; 42 | } 43 | 44 | public String getDescription() { 45 | return description; 46 | } 47 | 48 | public void setDescription(String description) { 49 | this.description = description; 50 | } 51 | 52 | public String getContent() { 53 | return content; 54 | } 55 | 56 | public void setContent(String content) { 57 | this.content = content; 58 | } 59 | 60 | public List getTags() { 61 | return tags; 62 | } 63 | 64 | public void setTags(List tags) { 65 | this.tags = tags; 66 | } 67 | 68 | public Date getCreateTime() { 69 | return createTime; 70 | } 71 | 72 | public void setCreateTime(Date createTime) { 73 | this.createTime = createTime; 74 | } 75 | 76 | public Long getReviewNum() { 77 | return reviewNum; 78 | } 79 | 80 | public void setReviewNum(Long reviewNum) { 81 | this.reviewNum = reviewNum; 82 | } 83 | 84 | public Integer getLikeNum() { 85 | return likeNum; 86 | } 87 | 88 | public void setLikeNum(Integer likeNum) { 89 | this.likeNum = likeNum; 90 | } 91 | 92 | public Long getArticleSlug() { 93 | return articleSlug; 94 | } 95 | 96 | public void setArticleSlug(Long articleSlug) { 97 | this.articleSlug = articleSlug; 98 | } 99 | 100 | public Long getCategorySlug() { 101 | return categorySlug; 102 | } 103 | 104 | public void setCategorySlug(Long categorySlug) { 105 | this.categorySlug = categorySlug; 106 | } 107 | 108 | } 109 | -------------------------------------------------------------------------------- /src/main/java/com/pblog/service/Article/ManageArticleInfoService.java: -------------------------------------------------------------------------------- 1 | package com.pblog.service.article; 2 | 3 | import com.pblog.domain.ArticleInfo; 4 | import com.pblog.web.controller.articlemanage.ArticleInfoFormBean; 5 | 6 | import java.util.List; 7 | 8 | public interface ManageArticleInfoService { 9 | 10 | void insert(ArticleInfoFormBean articleInfoFormBean); 11 | 12 | List findListByCategorySlug(Long categorySlug); 13 | 14 | int updateArticleEnabled(int articleId); 15 | 16 | ArticleInfo findById(Integer id); 17 | 18 | int updateArticle(ArticleInfoFormBean articleInfoFormBean); 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/com/pblog/service/Article/SimpleArticleInfo.java: -------------------------------------------------------------------------------- 1 | package com.pblog.service.article; 2 | 3 | import java.util.Date; 4 | 5 | public class SimpleArticleInfo { 6 | 7 | private Date createTime; 8 | 9 | private String title; 10 | 11 | private Long slug; 12 | 13 | public Date getCreateTime() { 14 | return createTime; 15 | } 16 | 17 | public void setCreateTime(Date createTime) { 18 | this.createTime = createTime; 19 | } 20 | 21 | public String getTitle() { 22 | return title; 23 | } 24 | 25 | public void setTitle(String title) { 26 | this.title = title; 27 | } 28 | 29 | public Long getSlug() { 30 | return slug; 31 | } 32 | 33 | public void setSlug(Long slug) { 34 | this.slug = slug; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/com/pblog/service/CommonUtilsService.java: -------------------------------------------------------------------------------- 1 | package com.pblog.service; 2 | 3 | import com.pblog.domain.ArticleInfo; 4 | import com.pblog.service.article.ArticleInfoVO; 5 | import com.pblog.service.article.SimpleArticleInfo; 6 | 7 | public interface CommonUtilsService { 8 | 9 | ArticleInfoVO transArticleInfoVO(ArticleInfo articleInfo); 10 | 11 | SimpleArticleInfo transArticleToSimpleArticle(ArticleInfo articleInfo); 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/com/pblog/service/CommonUtilsServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.pblog.service; 2 | 3 | import com.pblog.core.utils.GenerateUtils; 4 | import com.pblog.dao.ArticleInfoMapper; 5 | import com.pblog.dao.ArticleReadLogMapper; 6 | import com.pblog.dao.CategoryInfoMapper; 7 | import com.pblog.domain.ArticleInfo; 8 | import com.pblog.domain.CategoryInfo; 9 | import com.pblog.service.article.ArticleInfoVO; 10 | import com.pblog.service.article.SimpleArticleInfo; 11 | import org.springframework.stereotype.Service; 12 | import org.springframework.transaction.annotation.Transactional; 13 | 14 | import javax.annotation.Resource; 15 | 16 | @Service("commonUtilsService") 17 | @Transactional 18 | public class CommonUtilsServiceImpl implements CommonUtilsService{ 19 | 20 | @Resource 21 | private CategoryInfoMapper categoryInfoMapper; 22 | 23 | @Resource 24 | private ArticleReadLogMapper articleReadLogMapper; 25 | 26 | public ArticleInfoVO transArticleInfoVO(ArticleInfo articleInfo) { 27 | ArticleInfoVO articleInfoVO = new ArticleInfoVO(); 28 | 29 | articleInfoVO.setTitle(articleInfo.getTitle()); 30 | articleInfoVO.setDescription(articleInfo.getDescription()); 31 | articleInfoVO.setContent(articleInfo.getContent()); 32 | articleInfoVO.setTags(GenerateUtils.spiltStringByComma(articleInfo.getTag())); 33 | articleInfoVO.setCreateTime(articleInfo.getCreateTime()); 34 | articleInfoVO.setArticleSlug(articleInfo.getSlug()); 35 | articleInfoVO.setCategorySlug(articleInfo.getCategorySlug()); 36 | articleInfoVO.setLikeNum(articleInfo.getThumb()); 37 | 38 | Long categorySlug = articleInfo.getCategorySlug(); 39 | CategoryInfo categoryInfo = categoryInfoMapper.selectBySlug(categorySlug); 40 | articleInfoVO.setCategoryName(categoryInfo.getTitle()); 41 | 42 | Long clickNum = articleReadLogMapper.queryForClickNumByArticle(articleInfo.getSlug()); 43 | articleInfoVO.setReviewNum(clickNum); 44 | 45 | return articleInfoVO; 46 | } 47 | 48 | public SimpleArticleInfo transArticleToSimpleArticle(ArticleInfo articleInfo){ 49 | SimpleArticleInfo simpleArticleInfo = new SimpleArticleInfo(); 50 | 51 | simpleArticleInfo.setCreateTime(articleInfo.getCreateTime()); 52 | simpleArticleInfo.setSlug(articleInfo.getSlug()); 53 | simpleArticleInfo.setTitle(articleInfo.getTitle()); 54 | return simpleArticleInfo; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/main/java/com/pblog/service/archives/ArchivesService.java: -------------------------------------------------------------------------------- 1 | package com.pblog.service.archives; 2 | 3 | import com.pblog.service.article.ArticleInfoVO; 4 | 5 | import java.text.ParseException; 6 | import java.util.List; 7 | 8 | public interface ArchivesService { 9 | 10 | List findArchivesList() throws ParseException; 11 | 12 | List findArticleByMonth(String timeStamp) throws ParseException; 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/com/pblog/service/archives/ArchivesVO.java: -------------------------------------------------------------------------------- 1 | package com.pblog.service.archives; 2 | 3 | 4 | import com.pblog.service.article.ArticleInfoVO; 5 | import com.pblog.service.article.SimpleArticleInfo; 6 | 7 | import java.util.Date; 8 | import java.util.List; 9 | 10 | public class ArchivesVO { 11 | 12 | private Date timeStamp; 13 | 14 | List articleInfoVOList; 15 | 16 | public Date getTimeStamp() { 17 | return timeStamp; 18 | } 19 | 20 | public void setTimeStamp(Date timeStamp) { 21 | this.timeStamp = timeStamp; 22 | } 23 | 24 | public List getArticleInfoVOList() { 25 | return articleInfoVOList; 26 | } 27 | 28 | public void setArticleInfoVOList(List articleInfoVOList) { 29 | this.articleInfoVOList = articleInfoVOList; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/com/pblog/service/book/BookInfoService.java: -------------------------------------------------------------------------------- 1 | package com.pblog.service.book; 2 | 3 | 4 | import java.util.List; 5 | 6 | public interface BookInfoService { 7 | 8 | List findList(); 9 | 10 | BookInfoVO findBySlug(Long slug, String ipAddress); 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/com/pblog/service/book/BookInfoServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.pblog.service.book; 2 | 3 | import com.google.common.collect.Lists; 4 | import com.pblog.dao.BookInfoMapper; 5 | import com.pblog.dao.BookReadLogMapper; 6 | import com.pblog.domain.BookInfo; 7 | import com.pblog.domain.BookReadLog; 8 | import org.springframework.beans.factory.annotation.Autowired; 9 | import org.springframework.stereotype.Service; 10 | import org.springframework.transaction.annotation.Transactional; 11 | 12 | import java.util.Date; 13 | import java.util.List; 14 | 15 | @Service(value = "bookInfoService") 16 | @Transactional 17 | public class BookInfoServiceImpl implements BookInfoService{ 18 | 19 | @Autowired 20 | private BookInfoMapper bookInfoMapper; 21 | 22 | @Autowired 23 | private BookReadLogMapper bookReadLogMapper; 24 | 25 | 26 | public List findList() { 27 | List bookInfoVOList = Lists.newArrayList(); 28 | 29 | List bookInfoList = bookInfoMapper.selectAll(); 30 | for (BookInfo bookInfo : bookInfoList) { 31 | BookInfoVO bookInfoVO = transToBookInfoVO(bookInfo); 32 | bookInfoVOList.add(bookInfoVO); 33 | } 34 | 35 | return bookInfoVOList; 36 | } 37 | 38 | public BookInfoVO findBySlug(Long slug, String ipAddress) { 39 | BookInfo bookInfo = bookInfoMapper.selectBySlug(slug); 40 | 41 | BookReadLog bookReadLog = new BookReadLog(); 42 | bookReadLog.setBookId(bookInfo.getId()); 43 | bookReadLog.setCreateTime(new Date()); 44 | bookReadLog.setIpAddress(ipAddress); 45 | bookReadLog.setType(BookReadLog.BookReadType.TYPE_READ.getId()); 46 | bookReadLogMapper.insert(bookReadLog); 47 | 48 | return transToBookInfoVO(bookInfo); 49 | } 50 | 51 | private BookInfoVO transToBookInfoVO(BookInfo bookInfo) { 52 | BookInfoVO bookInfoVO = new BookInfoVO(); 53 | bookInfoVO.setSlug(bookInfo.getSlug()); 54 | bookInfoVO.setTitle(bookInfo.getTitle()); 55 | bookInfoVO.setBanner(bookInfo.getBanner()); 56 | bookInfoVO.setThumb(bookInfo.getThumb()); 57 | bookInfoVO.setIntroduction(bookInfo.getIntroduction()); 58 | bookInfoVO.setContent(bookInfo.getContent()); 59 | bookInfoVO.setCreateTime(bookInfo.getCreateTime()); 60 | 61 | Long reviewNum = bookReadLogMapper.selectNumById(bookInfo.getId()); 62 | bookInfoVO.setReviewNum(reviewNum); 63 | 64 | return bookInfoVO; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/main/java/com/pblog/service/book/BookInfoVO.java: -------------------------------------------------------------------------------- 1 | package com.pblog.service.book; 2 | 3 | import java.util.Date; 4 | 5 | public class BookInfoVO { 6 | 7 | public Long slug; 8 | 9 | public String title; 10 | 11 | public String banner; 12 | 13 | public Integer thumb; 14 | 15 | public String introduction; 16 | 17 | public Date createTime; 18 | 19 | public String content; 20 | 21 | public Long reviewNum; 22 | 23 | public Long getSlug() { 24 | return slug; 25 | } 26 | 27 | public void setSlug(Long slug) { 28 | this.slug = slug; 29 | } 30 | 31 | public String getTitle() { 32 | return title; 33 | } 34 | 35 | public void setTitle(String title) { 36 | this.title = title; 37 | } 38 | 39 | public String getBanner() { 40 | return banner; 41 | } 42 | 43 | public void setBanner(String banner) { 44 | this.banner = banner; 45 | } 46 | 47 | public Integer getThumb() { 48 | return thumb; 49 | } 50 | 51 | public void setThumb(Integer thumb) { 52 | this.thumb = thumb; 53 | } 54 | 55 | public String getIntroduction() { 56 | return introduction; 57 | } 58 | 59 | public void setIntroduction(String introduction) { 60 | this.introduction = introduction; 61 | } 62 | 63 | public String getContent() { 64 | return content; 65 | } 66 | 67 | public void setContent(String content) { 68 | this.content = content; 69 | } 70 | 71 | public Long getReviewNum() { 72 | return reviewNum; 73 | } 74 | 75 | public void setReviewNum(Long reviewNum) { 76 | this.reviewNum = reviewNum; 77 | } 78 | 79 | public Date getCreateTime() { 80 | return createTime; 81 | } 82 | 83 | public void setCreateTime(Date createTime) { 84 | this.createTime = createTime; 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /src/main/java/com/pblog/service/book/BookTableService.java: -------------------------------------------------------------------------------- 1 | package com.pblog.service.book; 2 | 3 | import java.util.List; 4 | 5 | public interface BookTableService { 6 | 7 | List findList(); 8 | 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/com/pblog/service/book/BookTableServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.pblog.service.book; 2 | 3 | import com.google.common.collect.Lists; 4 | import com.pblog.dao.BookTableMapper; 5 | import com.pblog.domain.BookTable; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.stereotype.Service; 8 | import org.springframework.transaction.annotation.Transactional; 9 | 10 | import java.util.List; 11 | 12 | @Service(value = "bookTableService") 13 | @Transactional 14 | public class BookTableServiceImpl implements BookTableService{ 15 | 16 | @Autowired 17 | private BookTableMapper bookTableMapper; 18 | 19 | public List findList() { 20 | List bookTableVOList = Lists.newArrayList(); 21 | 22 | List bookTableList = bookTableMapper.selectAll(); 23 | for(BookTable bookTable : bookTableList) { 24 | BookTableVO bookTableVO = transToBookTableVO(bookTable); 25 | 26 | bookTableVOList.add(bookTableVO); 27 | } 28 | return bookTableVOList; 29 | } 30 | 31 | private BookTableVO transToBookTableVO(BookTable bookTable) { 32 | BookTableVO bookTableVO = new BookTableVO(); 33 | 34 | bookTableVO.setBookBanner(bookTable.getBookBanner()); 35 | bookTableVO.setBookName(bookTable.getBookName()); 36 | bookTableVO.setBookUrl(bookTable.getBookUrl()); 37 | 38 | return bookTableVO; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/com/pblog/service/book/BookTableVO.java: -------------------------------------------------------------------------------- 1 | package com.pblog.service.book; 2 | 3 | public class BookTableVO { 4 | 5 | private String bookName; 6 | 7 | private String bookUrl; 8 | 9 | private String bookBanner; 10 | 11 | public String getBookName() { 12 | return bookName; 13 | } 14 | 15 | public void setBookName(String bookName) { 16 | this.bookName = bookName; 17 | } 18 | 19 | public String getBookUrl() { 20 | return bookUrl; 21 | } 22 | 23 | public void setBookUrl(String bookUrl) { 24 | this.bookUrl = bookUrl; 25 | } 26 | 27 | public String getBookBanner() { 28 | return bookBanner; 29 | } 30 | 31 | public void setBookBanner(String bookBanner) { 32 | this.bookBanner = bookBanner; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/com/pblog/service/book/ManageBookInfoService.java: -------------------------------------------------------------------------------- 1 | package com.pblog.service.book; 2 | 3 | import com.pblog.domain.BookInfo; 4 | import com.pblog.web.controller.bookmanage.BookInfoFormBean; 5 | 6 | import java.util.List; 7 | 8 | public interface ManageBookInfoService { 9 | 10 | void insert(BookInfoFormBean bookInfoFormBean); 11 | 12 | void update(BookInfoFormBean bookInfoFormBean); 13 | 14 | List findList(); 15 | 16 | BookInfo findById(Integer id); 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/com/pblog/service/book/ManageBookInfoServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.pblog.service.book; 2 | 3 | import com.pblog.dao.BookInfoMapper; 4 | import com.pblog.dao.SlugInfoMapper; 5 | import com.pblog.domain.BookInfo; 6 | import com.pblog.domain.SlugInfo; 7 | import com.pblog.web.controller.bookmanage.BookInfoFormBean; 8 | import org.springframework.beans.factory.annotation.Autowired; 9 | import org.springframework.stereotype.Service; 10 | 11 | import java.util.Date; 12 | import java.util.List; 13 | 14 | @Service(value = "manageBookInfoService") 15 | public class ManageBookInfoServiceImpl implements ManageBookInfoService{ 16 | 17 | @Autowired 18 | private BookInfoMapper bookInfoMapper; 19 | 20 | @Autowired 21 | private SlugInfoMapper slugInfoMapper; 22 | 23 | public void insert(BookInfoFormBean bookInfoFormBean) { 24 | BookInfo bookInfo = new BookInfo(); 25 | bookInfo.setTitle(bookInfoFormBean.getTitle()); 26 | bookInfo.setBanner(bookInfoFormBean.getBanner()); 27 | bookInfo.setIntroduction(bookInfoFormBean.getIntroduction()); 28 | bookInfo.setContent(bookInfoFormBean.getContent()); 29 | bookInfo.setCreateTime(new Date()); 30 | bookInfoMapper.insert(bookInfo); 31 | 32 | SlugInfo slugInfo = slugInfoMapper.queryById(bookInfo.getId()); 33 | bookInfo.setSlug(slugInfo.getSlug()); 34 | bookInfoMapper.updateByPrimaryKey(bookInfo); 35 | } 36 | 37 | public void update(BookInfoFormBean bookInfoFormBean) { 38 | BookInfo bookInfo = bookInfoMapper.selectByPrimaryKey(bookInfoFormBean.getId()); 39 | 40 | if(null == bookInfo) { 41 | throw new RuntimeException("updates book filed, please check 'id' is correct !"); 42 | } 43 | bookInfo.setTitle(bookInfoFormBean.getTitle()); 44 | bookInfo.setBanner(bookInfoFormBean.getBanner()); 45 | bookInfo.setIntroduction(bookInfoFormBean.getIntroduction()); 46 | bookInfo.setContent(bookInfoFormBean.getContent()); 47 | 48 | bookInfoMapper.updateByPrimaryKey(bookInfo); 49 | } 50 | 51 | public List findList() { 52 | 53 | return bookInfoMapper.selectAll(); 54 | } 55 | 56 | public BookInfo findById(Integer id) { 57 | return bookInfoMapper.selectByPrimaryKey(id); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/main/java/com/pblog/service/book/ManageBookTableService.java: -------------------------------------------------------------------------------- 1 | package com.pblog.service.book; 2 | 3 | import com.pblog.domain.BookTable; 4 | 5 | import java.util.List; 6 | 7 | public interface ManageBookTableService { 8 | 9 | int insert(BookTable bookTable); 10 | 11 | int update(BookTable bookTable); 12 | 13 | int delete(Integer id); 14 | 15 | List findAll(); 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/com/pblog/service/book/ManageBookTableServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.pblog.service.book; 2 | 3 | import com.pblog.dao.BookTableMapper; 4 | import com.pblog.domain.BookTable; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.stereotype.Service; 7 | 8 | import java.util.List; 9 | 10 | @Service(value = "manageBookTableService") 11 | public class ManageBookTableServiceImpl implements ManageBookTableService{ 12 | 13 | @Autowired 14 | private BookTableMapper bookTableMapper; 15 | 16 | public int insert(BookTable bookTable) { 17 | if(null == bookTable.getBookBanner() || null == bookTable.getBookUrl()) { 18 | throw new NullPointerException("in insert(), bookTable's banner or url cannot be null !"); 19 | } 20 | 21 | return bookTableMapper.insert(bookTable); 22 | } 23 | 24 | public int update(BookTable bookTable) { 25 | if(null == bookTable.getId()) { 26 | throw new NullPointerException("in update(), bookTable's id cannot be null !"); 27 | } 28 | if(null == bookTable.getBookBanner() || null == bookTable.getBookUrl()) { 29 | throw new NullPointerException("in update(), bookTable's banner or url cannot be null !"); 30 | } 31 | 32 | return bookTableMapper.updateByPrimaryKey(bookTable); 33 | } 34 | 35 | public int delete(Integer id) { 36 | if(null == id) { 37 | throw new NullPointerException("in delete(), id cannot be null !"); 38 | } 39 | 40 | return bookTableMapper.deleteByPrimaryKey(id); 41 | } 42 | 43 | public List findAll() { 44 | 45 | return bookTableMapper.selectAll(); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/com/pblog/service/category/CategoryInfoService.java: -------------------------------------------------------------------------------- 1 | package com.pblog.service.category; 2 | 3 | import com.pblog.service.article.ArticleInfoVO; 4 | 5 | import java.util.List; 6 | 7 | public interface CategoryInfoService { 8 | 9 | List findArticleListByCategory(Long categorySlug); 10 | 11 | List findCategoryInfoVO(); 12 | 13 | List findSimpleCategoryInfo(); 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/com/pblog/service/category/CategoryInfoVO.java: -------------------------------------------------------------------------------- 1 | package com.pblog.service.category; 2 | 3 | import com.pblog.service.article.ArticleInfoVO; 4 | import com.pblog.service.article.SimpleArticleInfo; 5 | 6 | import java.util.List; 7 | 8 | public class CategoryInfoVO { 9 | 10 | private Long slug; 11 | 12 | private String categoryTitle; 13 | 14 | private List articleInfoVOList; 15 | 16 | public Long getSlug() { 17 | return slug; 18 | } 19 | 20 | public void setSlug(Long slug) { 21 | this.slug = slug; 22 | } 23 | 24 | public String getCategoryTitle() { 25 | return categoryTitle; 26 | } 27 | 28 | public void setCategoryTitle(String categoryTitle) { 29 | this.categoryTitle = categoryTitle; 30 | } 31 | 32 | public List getArticleInfoVOList() { 33 | return articleInfoVOList; 34 | } 35 | 36 | public void setArticleInfoVOList(List articleInfoVOList) { 37 | this.articleInfoVOList = articleInfoVOList; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/com/pblog/service/category/ManageCategoryService.java: -------------------------------------------------------------------------------- 1 | package com.pblog.service.category; 2 | 3 | import com.pblog.domain.CategoryInfo; 4 | 5 | import java.util.List; 6 | 7 | public interface ManageCategoryService { 8 | 9 | void insert(CategoryInfo categoryInfo); 10 | 11 | List list(); 12 | 13 | int updateBySlug(CategoryInfo categoryInfo); 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/com/pblog/service/category/ManageCategoryServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.pblog.service.category; 2 | 3 | import com.google.common.collect.Lists; 4 | import com.pblog.dao.ArticleInfoMapper; 5 | import com.pblog.dao.CategoryInfoMapper; 6 | import com.pblog.dao.SlugInfoMapper; 7 | import com.pblog.domain.ArticleInfo; 8 | import com.pblog.domain.CategoryInfo; 9 | import com.pblog.domain.SlugInfo; 10 | import org.springframework.beans.factory.annotation.Autowired; 11 | import org.springframework.stereotype.Service; 12 | import org.springframework.transaction.annotation.Transactional; 13 | 14 | import java.util.Date; 15 | import java.util.List; 16 | 17 | @Service(value = "manageCategoryService") 18 | @Transactional 19 | public class ManageCategoryServiceImpl implements ManageCategoryService{ 20 | 21 | @Autowired 22 | private CategoryInfoMapper categoryInfoMapper; 23 | 24 | @Autowired 25 | private ArticleInfoMapper articleInfoMapper; 26 | 27 | @Autowired 28 | private SlugInfoMapper slugInfoMapper; 29 | 30 | public void insert(CategoryInfo categoryInfo) { 31 | categoryInfo.setCreateTime(new Date()); 32 | categoryInfoMapper.save(categoryInfo); 33 | 34 | SlugInfo slugInfo = slugInfoMapper.queryById(categoryInfo.getId()); 35 | categoryInfo.setSlug(slugInfo.getSlug()); 36 | categoryInfoMapper.update(categoryInfo); 37 | } 38 | 39 | public List list() { 40 | List simpleCategoryInfoList = Lists.newArrayList(); 41 | 42 | List categoryInfoList = categoryInfoMapper.selectAll(); 43 | for(CategoryInfo categoryInfo : categoryInfoList) { 44 | SimpleCategoryInfo simpleCategoryInfo = new SimpleCategoryInfo(); 45 | simpleCategoryInfo.setCategorySlug(categoryInfo.getSlug()); 46 | simpleCategoryInfo.setTitle(categoryInfo.getTitle()); 47 | 48 | List articleInfoList = articleInfoMapper.findListByCategorySlug(categoryInfo.getSlug()); 49 | simpleCategoryInfo.setNum(articleInfoList == null ? 0 : articleInfoList.size()); 50 | 51 | simpleCategoryInfoList.add(simpleCategoryInfo); 52 | } 53 | 54 | return simpleCategoryInfoList; 55 | } 56 | 57 | public int updateBySlug(CategoryInfo categoryInfo) { 58 | categoryInfoMapper.updateBySlug(categoryInfo); 59 | return 0; 60 | } 61 | 62 | 63 | } 64 | -------------------------------------------------------------------------------- /src/main/java/com/pblog/service/category/SimpleCategoryInfo.java: -------------------------------------------------------------------------------- 1 | package com.pblog.service.category; 2 | 3 | public class SimpleCategoryInfo { 4 | 5 | private Long categorySlug; 6 | 7 | private String title; 8 | 9 | private Integer num; 10 | 11 | public Long getCategorySlug() { 12 | return categorySlug; 13 | } 14 | 15 | public void setCategorySlug(Long categorySlug) { 16 | this.categorySlug = categorySlug; 17 | } 18 | 19 | public String getTitle() { 20 | return title; 21 | } 22 | 23 | public void setTitle(String title) { 24 | this.title = title; 25 | } 26 | 27 | public Integer getNum() { 28 | return num; 29 | } 30 | 31 | public void setNum(Integer num) { 32 | this.num = num; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/com/pblog/service/log/WebsiteTrafficService.java: -------------------------------------------------------------------------------- 1 | package com.pblog.service.log; 2 | 3 | import com.pblog.domain.WebsiteTraffic; 4 | 5 | public interface WebsiteTrafficService { 6 | 7 | void save(WebsiteTraffic websiteTraffic); 8 | 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/com/pblog/service/log/WebsiteTrafficServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.pblog.service.log; 2 | 3 | import com.pblog.core.utils.DateFormatUtils; 4 | import com.pblog.dao.WebsiteTrafficMapper; 5 | import com.pblog.domain.WebsiteTraffic; 6 | import org.slf4j.Logger; 7 | import org.slf4j.LoggerFactory; 8 | import org.springframework.beans.factory.annotation.Autowired; 9 | import org.springframework.stereotype.Service; 10 | import org.springframework.transaction.annotation.Transactional; 11 | import org.springframework.util.StringUtils; 12 | 13 | import java.util.List; 14 | 15 | @Service(value = "websiteTrafficService") 16 | @Transactional 17 | public class WebsiteTrafficServiceImpl implements WebsiteTrafficService{ 18 | 19 | private static Logger logger = LoggerFactory.getLogger(WebsiteTrafficServiceImpl.class); 20 | 21 | @Autowired 22 | private WebsiteTrafficMapper websiteTrafficMapper; 23 | 24 | 25 | public void save(WebsiteTraffic websiteTraffic) { 26 | String ipAddress = websiteTraffic.getIpAddress(); 27 | 28 | List websiteTrafficList = websiteTrafficMapper.queryByIpAddress(ipAddress); 29 | if(!StringUtils.isEmpty(websiteTrafficList) && websiteTrafficList.size() > 0){ 30 | WebsiteTraffic temp = websiteTrafficList.get(0); 31 | boolean thanOneHour = DateFormatUtils.isThanOneHour(websiteTraffic.getCreateTime(), temp.getCreateTime()); 32 | //如果间隔小于一小时,则不记录日志 33 | if(thanOneHour){ 34 | websiteTrafficMapper.insert(websiteTraffic); 35 | } 36 | }else{ 37 | websiteTrafficMapper.insert(websiteTraffic); 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/com/pblog/service/pic/PicInfoService.java: -------------------------------------------------------------------------------- 1 | package com.pblog.service.pic; 2 | 3 | 4 | import com.pblog.domain.PicInfo; 5 | import org.springframework.web.multipart.MultipartFile; 6 | 7 | import java.io.IOException; 8 | import java.util.List; 9 | 10 | public interface PicInfoService { 11 | 12 | void upload(MultipartFile file) throws IOException; 13 | 14 | List list(); 15 | 16 | int deleteById(Long picId); 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/com/pblog/service/pic/PicInfoServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.pblog.service.pic; 2 | 3 | import com.pblog.core.utils.ImageUploadUtils; 4 | import com.pblog.core.utils.MultipartFileValidator; 5 | import com.pblog.dao.PicInfoMapper; 6 | import com.pblog.domain.PicInfo; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.beans.factory.annotation.Value; 9 | import org.springframework.stereotype.Service; 10 | import org.springframework.transaction.annotation.Transactional; 11 | import org.springframework.web.multipart.MultipartFile; 12 | 13 | import java.io.File; 14 | import java.io.IOException; 15 | import java.util.Date; 16 | import java.util.List; 17 | 18 | @Service(value = "picInfoService") 19 | @Transactional 20 | public class PicInfoServiceImpl implements PicInfoService{ 21 | 22 | @Autowired 23 | private PicInfoMapper picInfoMapper; 24 | 25 | @Value("${server.root.staticPath}") 26 | private String staticPath; 27 | 28 | @Value("${server.root.relPath}") 29 | private String relPath; 30 | 31 | public List list() { 32 | 33 | return picInfoMapper.selectAll(); 34 | } 35 | 36 | public void upload(MultipartFile file) throws IOException { 37 | MultipartFileValidator.validate(file); 38 | String fileName = ImageUploadUtils.uploadImage(file, staticPath); 39 | 40 | PicInfo picInfo = new PicInfo(); 41 | picInfo.setCreateTime(new Date()); 42 | picInfo.setPhysicalPath(staticPath + File.separator + fileName); 43 | picInfo.setRelativePath(relPath + fileName); 44 | picInfoMapper.insert(picInfo); 45 | } 46 | 47 | public int deleteById(Long picId) { 48 | PicInfo picInfo = picInfoMapper.selectById(picId); 49 | 50 | File file = new File(picInfo.getPhysicalPath()); 51 | if(!file.exists()) { 52 | //文件删除失败,不存在 53 | return 0; 54 | } else { 55 | boolean success = file.delete(); 56 | if(success) { 57 | return picInfoMapper.deleteByPrimaryKey(picId); 58 | } else { 59 | //文件删除失败 60 | return 0; 61 | } 62 | } 63 | } 64 | 65 | 66 | } 67 | -------------------------------------------------------------------------------- /src/main/java/com/pblog/service/record/ManageRecordService.java: -------------------------------------------------------------------------------- 1 | package com.pblog.service.record; 2 | 3 | 4 | import com.pblog.domain.RecordInfo; 5 | 6 | import java.util.List; 7 | 8 | public interface ManageRecordService { 9 | 10 | int insert(RecordInfo recordInfo); 11 | 12 | List list(); 13 | 14 | RecordInfo findById(Integer id); 15 | 16 | int update(RecordInfo recordInfo); 17 | 18 | int delete(Integer id); 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/com/pblog/service/record/ManageRecordServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.pblog.service.record; 2 | 3 | import com.pblog.dao.RecordInfoMapper; 4 | import com.pblog.domain.RecordInfo; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.stereotype.Service; 7 | import org.springframework.transaction.annotation.Transactional; 8 | 9 | import java.util.Date; 10 | import java.util.List; 11 | 12 | @Service(value = "manageRecordService") 13 | @Transactional 14 | public class ManageRecordServiceImpl implements ManageRecordService{ 15 | 16 | @Autowired 17 | private RecordInfoMapper recordInfoMapper; 18 | 19 | public int insert(RecordInfo recordInfo) { 20 | recordInfo.setCreateTime(new Date()); 21 | 22 | return recordInfoMapper.insert(recordInfo); 23 | } 24 | 25 | public List list() { 26 | 27 | return recordInfoMapper.selectAll(); 28 | } 29 | 30 | public RecordInfo findById(Integer id) { 31 | RecordInfo recordInfo = recordInfoMapper.selectById(id); 32 | 33 | return recordInfo; 34 | } 35 | 36 | public int update(RecordInfo recordInfo) { 37 | if(recordInfo.getId() == null) { 38 | throw new RuntimeException("RecordInfo'S id cannot be null when update"); 39 | } 40 | 41 | RecordInfo temp = recordInfoMapper.selectById(recordInfo.getId()); 42 | temp.setTitle(recordInfo.getTitle()); 43 | temp.setContent(recordInfo.getContent()); 44 | 45 | return recordInfoMapper.updateByPrimaryKey(temp); 46 | } 47 | 48 | public int delete(Integer id) { 49 | 50 | return recordInfoMapper.deleteByPrimaryKey(id); 51 | } 52 | } 53 | 54 | -------------------------------------------------------------------------------- /src/main/java/com/pblog/service/record/RecordService.java: -------------------------------------------------------------------------------- 1 | package com.pblog.service.record; 2 | 3 | import com.pblog.domain.RecordInfo; 4 | 5 | import java.util.List; 6 | 7 | public interface RecordService { 8 | 9 | List list(); 10 | 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/com/pblog/service/record/RecordServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.pblog.service.record; 2 | 3 | import com.google.common.collect.Lists; 4 | import com.pblog.dao.RecordInfoMapper; 5 | import com.pblog.domain.RecordInfo; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.stereotype.Service; 8 | import org.springframework.transaction.annotation.Transactional; 9 | 10 | import java.util.List; 11 | 12 | @Service(value = "recordService") 13 | @Transactional 14 | public class RecordServiceImpl implements RecordService{ 15 | 16 | @Autowired 17 | private RecordInfoMapper recordInfoMapper; 18 | 19 | public List list() { 20 | List recordInfoList = Lists.newArrayList(); 21 | 22 | recordInfoList = recordInfoMapper.selectAll(); 23 | for(RecordInfo recordInfo : recordInfoList) { 24 | recordInfo.setId(null); 25 | } 26 | 27 | return recordInfoList; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/com/pblog/service/slug/SlugInfoService.java: -------------------------------------------------------------------------------- 1 | package com.pblog.service.slug; 2 | 3 | public interface SlugInfoService { 4 | 5 | void insert(); 6 | } 7 | -------------------------------------------------------------------------------- /src/main/java/com/pblog/service/slug/SlugInfoServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.pblog.service.slug; 2 | 3 | import com.google.common.collect.Sets; 4 | import com.pblog.core.utils.RandomUtils; 5 | import com.pblog.dao.SlugInfoMapper; 6 | import com.pblog.domain.SlugInfo; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.stereotype.Service; 9 | import org.springframework.transaction.annotation.Transactional; 10 | 11 | import java.util.Set; 12 | 13 | @Service(value = "slugInfoService") 14 | @Transactional 15 | public class SlugInfoServiceImpl implements SlugInfoService{ 16 | 17 | @Autowired 18 | private SlugInfoMapper slugInfoMapper; 19 | 20 | public void insert() { 21 | Set strSet = Sets.newHashSet(); 22 | for(int i = 0; i < 2000; i++){ 23 | strSet.add(RandomUtils.generateNumber2()); 24 | } 25 | Object[] strList = strSet.toArray(); 26 | 27 | for(int i = 0; i < strList.length; i++){ 28 | SlugInfo slugInfo = new SlugInfo(); 29 | slugInfo.setSlug(Long.valueOf(String.valueOf(strList[i]))); 30 | slugInfoMapper.insert(slugInfo); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/com/pblog/web/controller/AboutController.java: -------------------------------------------------------------------------------- 1 | package com.pblog.web.controller; 2 | 3 | import org.springframework.stereotype.Controller; 4 | import org.springframework.ui.Model; 5 | import org.springframework.web.bind.annotation.RequestMapping; 6 | import org.springframework.web.bind.annotation.RequestMethod; 7 | 8 | import javax.servlet.http.HttpServletRequest; 9 | 10 | @Controller 11 | public class AboutController { 12 | 13 | //----------------移动端——-------------------- 14 | @RequestMapping(value = "/about", method = RequestMethod.GET) 15 | public String index(HttpServletRequest request, Model model) { 16 | Boolean mobile = (Boolean) request.getAttribute("mobile"); 17 | 18 | if(mobile) { 19 | return "web/about/about_mobile"; 20 | } else { 21 | return "redirect:/#/about"; 22 | } 23 | } 24 | 25 | //----------------PC端------------------------ 26 | @RequestMapping(value = "/about/layout", method = RequestMethod.GET) 27 | public String layout(HttpServletRequest request, Model model) { 28 | 29 | return "web/about/layout"; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/com/pblog/web/controller/ArticleController.java: -------------------------------------------------------------------------------- 1 | package com.pblog.web.controller; 2 | 3 | import com.google.common.collect.Maps; 4 | import com.pblog.service.article.ArticleInfoService; 5 | import com.pblog.service.article.ArticleInfoVO; 6 | import org.springframework.stereotype.Controller; 7 | import org.springframework.ui.Model; 8 | import org.springframework.web.bind.annotation.PathVariable; 9 | import org.springframework.web.bind.annotation.RequestMapping; 10 | import org.springframework.web.bind.annotation.RequestMethod; 11 | import org.springframework.web.bind.annotation.ResponseBody; 12 | 13 | import javax.annotation.Resource; 14 | import javax.servlet.http.HttpServletRequest; 15 | import java.util.Map; 16 | 17 | @Controller 18 | @RequestMapping("/article") 19 | public class ArticleController { 20 | 21 | @Resource(name = "articleInfoService") 22 | private ArticleInfoService articleInfoService; 23 | 24 | //------------------移动端------------------------- 25 | 26 | @RequestMapping(value = "/{slug}/detail", method = RequestMethod.GET) 27 | public String index(@PathVariable Long slug, HttpServletRequest request, Model model) { 28 | Boolean mobile = (Boolean) request.getAttribute("mobile"); 29 | if (!mobile) { 30 | return "redirect:/#/article/" + slug; 31 | } 32 | 33 | String ipAddress = (String) request.getAttribute("realIp"); 34 | ArticleInfoVO articleInfoVO = articleInfoService.findArticleBySlug(slug, ipAddress); 35 | model.addAttribute("articleInfo", articleInfoVO); 36 | return "web/article/article_mobile"; 37 | } 38 | 39 | //--------------------PC端——----------------------- 40 | 41 | @RequestMapping(value = "/slug/layout", method = RequestMethod.GET) 42 | public String layout(HttpServletRequest request, Model model) { 43 | 44 | return "web/article/layout"; 45 | } 46 | 47 | @RequestMapping(value ="/{slug}", method = RequestMethod.GET, produces = {"application/xml", "application/json"}) 48 | @ResponseBody 49 | public Map articleJson(@PathVariable Long slug, HttpServletRequest request) { 50 | String ipAddress = (String) request.getAttribute("realIp"); 51 | ArticleInfoVO articleInfoVO = articleInfoService.findArticleBySlug(slug, ipAddress); 52 | 53 | Map map = Maps.newHashMap(); 54 | map.put("articleVO", articleInfoVO); 55 | return map; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/main/java/com/pblog/web/controller/GlobalController.java: -------------------------------------------------------------------------------- 1 | package com.pblog.web.controller; 2 | 3 | import org.springframework.stereotype.Controller; 4 | import org.springframework.ui.Model; 5 | import org.springframework.web.bind.annotation.RequestMapping; 6 | import org.springframework.web.bind.annotation.RequestParam; 7 | 8 | import javax.servlet.http.HttpServletRequest; 9 | 10 | @Controller 11 | public class GlobalController { 12 | 13 | @RequestMapping("/switch") 14 | public String switchModel(@RequestParam(value = "mo")Integer mo, HttpServletRequest request, 15 | Model model) { 16 | if(mo == 1) { 17 | request.getSession().setAttribute("mo", "1"); //夜间模式 18 | } else { 19 | request.getSession().setAttribute("mo", "2"); //日间模式 20 | } 21 | 22 | return "redirect:/"; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/com/pblog/web/controller/RecordController.java: -------------------------------------------------------------------------------- 1 | package com.pblog.web.controller; 2 | 3 | import com.google.common.collect.Lists; 4 | import com.google.common.collect.Maps; 5 | import com.pblog.core.utils.DateFormatUtils; 6 | import com.pblog.domain.RecordInfo; 7 | import com.pblog.service.record.RecordService; 8 | import org.springframework.stereotype.Controller; 9 | import org.springframework.ui.Model; 10 | import org.springframework.web.bind.annotation.RequestMapping; 11 | import org.springframework.web.bind.annotation.RequestMethod; 12 | import org.springframework.web.bind.annotation.ResponseBody; 13 | 14 | import javax.annotation.Resource; 15 | import javax.servlet.http.HttpServletRequest; 16 | import java.util.List; 17 | import java.util.Map; 18 | 19 | @Controller 20 | public class RecordController { 21 | 22 | @Resource(name = "recordService") 23 | private RecordService recordService; 24 | 25 | //------------------PC端---------------------- 26 | 27 | @RequestMapping(value = "/record/layout", method = RequestMethod.GET) 28 | public String layout() { 29 | 30 | return "web/record/layout"; 31 | } 32 | 33 | @RequestMapping(value = "/record", method = RequestMethod.GET, produces = {"application/xml", "application/json"}) 34 | @ResponseBody 35 | public Map record() { 36 | Map map = Maps.newHashMap(); 37 | 38 | List recordInfoList = recordService.list(); 39 | map.put("recordInfoList", recordInfoList); 40 | return map; 41 | } 42 | 43 | //-----------移动端-------------------- 44 | @RequestMapping(value = "/record/detail", method = RequestMethod.GET) 45 | public String index(HttpServletRequest request, Model model) { 46 | List recordInfoList = recordService.list(); 47 | List nightList = Lists.newArrayList(); 48 | 49 | for (RecordInfo recordInfo : recordInfoList) { 50 | Integer hour = DateFormatUtils.formatToHour(recordInfo.getCreateTime()); 51 | 52 | //19:00 — 5:00 夜晚,6:00 — 19:00 白天 53 | if (hour >= 19 || hour <= 5) { 54 | nightList.add(true); 55 | } else { 56 | nightList.add(false); 57 | } 58 | } 59 | 60 | model.addAttribute("recordInfoList", recordInfoList); 61 | model.addAttribute("nightList", nightList); 62 | return "web/record/record_mobile"; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/main/java/com/pblog/web/controller/ResumeController.java: -------------------------------------------------------------------------------- 1 | package com.pblog.web.controller; 2 | 3 | import org.springframework.stereotype.Controller; 4 | import org.springframework.web.bind.annotation.RequestMapping; 5 | import org.springframework.web.bind.annotation.RequestMethod; 6 | 7 | import javax.servlet.http.HttpServletRequest; 8 | 9 | @Controller 10 | public class ResumeController { 11 | 12 | @RequestMapping(value = "/resume", method = RequestMethod.GET) 13 | public String index(HttpServletRequest request) { 14 | 15 | return "web/resume/resume"; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/com/pblog/web/controller/aboutmanage/ManageAboutController.java: -------------------------------------------------------------------------------- 1 | package com.pblog.web.controller.aboutmanage; 2 | 3 | import org.springframework.stereotype.Controller; 4 | import org.springframework.ui.Model; 5 | import org.springframework.web.bind.annotation.RequestMapping; 6 | import org.springframework.web.bind.annotation.RequestMethod; 7 | 8 | import javax.servlet.http.HttpServletRequest; 9 | 10 | @Controller 11 | @RequestMapping(value = "manage/about") 12 | public class ManageAboutController { 13 | 14 | @RequestMapping(value = "/edit", method = RequestMethod.GET) 15 | public String index(HttpServletRequest request, Model model) { 16 | 17 | return "manage/about/about_edit"; 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/com/pblog/web/controller/articlemanage/ArticleInfoFormBean.java: -------------------------------------------------------------------------------- 1 | package com.pblog.web.controller.articlemanage; 2 | 3 | public class ArticleInfoFormBean { 4 | 5 | private Integer id; 6 | 7 | private String title; 8 | 9 | private String content; 10 | 11 | private Long categorySlug; 12 | 13 | private String tag; 14 | 15 | private String description; 16 | 17 | private String descriptionMd; 18 | 19 | public String getTitle() { 20 | return title; 21 | } 22 | 23 | public void setTitle(String title) { 24 | this.title = title; 25 | } 26 | 27 | public String getContent() { 28 | return content; 29 | } 30 | 31 | public void setContent(String content) { 32 | this.content = content; 33 | } 34 | 35 | public Long getCategorySlug() { 36 | return categorySlug; 37 | } 38 | 39 | public void setCategorySlug(Long categorySlug) { 40 | this.categorySlug = categorySlug; 41 | } 42 | 43 | public String getTag() { 44 | return tag; 45 | } 46 | 47 | public void setTag(String tag) { 48 | this.tag = tag; 49 | } 50 | 51 | public String getDescription() { 52 | return description; 53 | } 54 | 55 | public void setDescription(String description) { 56 | this.description = description; 57 | } 58 | 59 | public Integer getId() { 60 | return id; 61 | } 62 | 63 | public void setId(Integer id) { 64 | this.id = id; 65 | } 66 | 67 | public String getDescriptionMd() { 68 | return descriptionMd; 69 | } 70 | 71 | public void setDescriptionMd(String descriptionMd) { 72 | this.descriptionMd = descriptionMd; 73 | } 74 | } -------------------------------------------------------------------------------- /src/main/java/com/pblog/web/controller/bookmanage/BookInfoFormBean.java: -------------------------------------------------------------------------------- 1 | package com.pblog.web.controller.bookmanage; 2 | 3 | public class BookInfoFormBean { 4 | 5 | private Integer id; 6 | 7 | private String title; 8 | 9 | private String banner; 10 | 11 | private String introduction; 12 | 13 | private String content; 14 | 15 | public Integer getId() { 16 | return id; 17 | } 18 | 19 | public void setId(Integer id) { 20 | this.id = id; 21 | } 22 | 23 | public String getTitle() { 24 | return title; 25 | } 26 | 27 | public void setTitle(String title) { 28 | this.title = title; 29 | } 30 | 31 | public String getBanner() { 32 | return banner; 33 | } 34 | 35 | public void setBanner(String banner) { 36 | this.banner = banner; 37 | } 38 | 39 | public String getIntroduction() { 40 | return introduction; 41 | } 42 | 43 | public void setIntroduction(String introduction) { 44 | this.introduction = introduction; 45 | } 46 | 47 | public String getContent() { 48 | return content; 49 | } 50 | 51 | public void setContent(String content) { 52 | this.content = content; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/main/java/com/pblog/web/controller/bookmanage/ManageBookTableController.java: -------------------------------------------------------------------------------- 1 | package com.pblog.web.controller.bookmanage; 2 | 3 | import com.google.common.collect.Maps; 4 | import com.pblog.domain.BookTable; 5 | import com.pblog.service.book.ManageBookTableService; 6 | import org.springframework.stereotype.Controller; 7 | import org.springframework.ui.Model; 8 | import org.springframework.web.bind.annotation.*; 9 | 10 | import javax.annotation.Resource; 11 | import java.util.Map; 12 | 13 | @Controller 14 | @RequestMapping("manage/read") 15 | public class ManageBookTableController { 16 | 17 | @Resource(name = "manageBookTableService") 18 | private ManageBookTableService manageBookTableService; 19 | 20 | @RequestMapping(value = "/add", method = RequestMethod.POST) 21 | public String insert(@ModelAttribute BookTable bookTable, Model model) { 22 | manageBookTableService.insert(bookTable); 23 | 24 | return "redirect:/manage/book/list"; 25 | } 26 | 27 | @RequestMapping(value = "/update", method = RequestMethod.POST) 28 | public String update(@ModelAttribute BookTable bookTable, Model model) { 29 | manageBookTableService.update(bookTable); 30 | 31 | return "redirect:/manage/book/list"; 32 | } 33 | 34 | @RequestMapping(value = "/delete", method = RequestMethod.POST) 35 | @ResponseBody 36 | public Map delete(@RequestParam(name = "bookTableId", required = true)Integer bookTableId) { 37 | Map map = Maps.newHashMap(); 38 | 39 | int status = manageBookTableService.delete(bookTableId); 40 | map.put("status", status); 41 | return map; 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/com/pblog/web/controller/categorymanage/ManageCategoryController.java: -------------------------------------------------------------------------------- 1 | package com.pblog.web.controller.categorymanage; 2 | 3 | import com.google.common.collect.Maps; 4 | import com.pblog.domain.CategoryInfo; 5 | import com.pblog.service.category.ManageCategoryService; 6 | import com.pblog.service.category.SimpleCategoryInfo; 7 | import org.springframework.stereotype.Controller; 8 | import org.springframework.ui.Model; 9 | import org.springframework.web.bind.annotation.ModelAttribute; 10 | import org.springframework.web.bind.annotation.RequestMapping; 11 | import org.springframework.web.bind.annotation.RequestMethod; 12 | import org.springframework.web.bind.annotation.ResponseBody; 13 | 14 | import javax.annotation.Resource; 15 | import javax.servlet.http.HttpServletRequest; 16 | import java.util.List; 17 | import java.util.Map; 18 | 19 | @Controller 20 | @RequestMapping(value = "manage/category") 21 | public class ManageCategoryController { 22 | 23 | @Resource(name = "manageCategoryService") 24 | private ManageCategoryService manageCategoryService; 25 | 26 | @RequestMapping(value = "/list", method = RequestMethod.GET) 27 | private String list(HttpServletRequest request, Model model) { 28 | List simpleCategoryInfoList = manageCategoryService.list(); 29 | 30 | model.addAttribute("simpleCategoryList", simpleCategoryInfoList); 31 | return "manage/category/list"; 32 | } 33 | 34 | @RequestMapping(value = "/add", method = RequestMethod.POST) 35 | private String insert(@ModelAttribute CategoryInfo categoryInfo, HttpServletRequest request) { 36 | manageCategoryService.insert(categoryInfo); 37 | 38 | return "redirect:list"; 39 | } 40 | 41 | @RequestMapping(value = "/update", method = RequestMethod.POST) 42 | private String update(@ModelAttribute CategoryInfo categoryInfo, HttpServletRequest request) { 43 | manageCategoryService.updateBySlug(categoryInfo); 44 | 45 | return "redirect:list"; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/com/pblog/web/controller/picmanage/ManagePicController.java: -------------------------------------------------------------------------------- 1 | package com.pblog.web.controller.picmanage; 2 | 3 | import com.google.common.collect.Maps; 4 | import com.pblog.domain.PicInfo; 5 | import com.pblog.service.pic.PicInfoService; 6 | import org.springframework.stereotype.Controller; 7 | import org.springframework.ui.Model; 8 | import org.springframework.web.bind.annotation.RequestMapping; 9 | import org.springframework.web.bind.annotation.RequestMethod; 10 | import org.springframework.web.bind.annotation.RequestParam; 11 | import org.springframework.web.bind.annotation.ResponseBody; 12 | import org.springframework.web.multipart.MultipartFile; 13 | 14 | import javax.annotation.Resource; 15 | import javax.servlet.http.HttpServletRequest; 16 | import java.io.IOException; 17 | import java.util.List; 18 | import java.util.Map; 19 | 20 | @Controller 21 | @RequestMapping("manage/pic") 22 | public class ManagePicController { 23 | 24 | @Resource(name = "picInfoService") 25 | private PicInfoService picInfoService; 26 | 27 | @RequestMapping(value = "/list", method = RequestMethod.GET) 28 | public String list(HttpServletRequest request, Model model) { 29 | List picInfoList = picInfoService.list(); 30 | 31 | model.addAttribute("picInfoList", picInfoList); 32 | return "manage/pic/list"; 33 | } 34 | 35 | @RequestMapping(value = "/upload", method = RequestMethod.POST) 36 | public String upload(@RequestParam(value = "file")MultipartFile file, 37 | HttpServletRequest request) throws IOException { 38 | picInfoService.upload(file); 39 | 40 | return "redirect:list"; 41 | } 42 | 43 | @RequestMapping(value = "/delete", method = RequestMethod.POST) 44 | @ResponseBody 45 | public Map delete(@RequestParam(value = "picId") Long picId, HttpServletRequest request) { 46 | Map map = Maps.newHashMap(); 47 | 48 | int status = picInfoService.deleteById(picId); 49 | map.put("status", status); 50 | return map; 51 | } 52 | 53 | 54 | } 55 | -------------------------------------------------------------------------------- /src/main/java/com/pblog/web/controller/recordmanage/ManageRecordController.java: -------------------------------------------------------------------------------- 1 | package com.pblog.web.controller.recordmanage; 2 | 3 | import com.google.common.collect.Maps; 4 | import com.pblog.domain.RecordInfo; 5 | import com.pblog.service.record.ManageRecordService; 6 | import org.springframework.stereotype.Controller; 7 | import org.springframework.ui.Model; 8 | import org.springframework.web.bind.annotation.*; 9 | 10 | import javax.annotation.Resource; 11 | import javax.servlet.http.HttpServletRequest; 12 | import java.util.List; 13 | import java.util.Map; 14 | 15 | @Controller 16 | @RequestMapping(value = "manage/record") 17 | public class ManageRecordController { 18 | 19 | @Resource(name = "manageRecordService") 20 | private ManageRecordService manageRecordService; 21 | 22 | @RequestMapping(value = "/list", method = RequestMethod.GET) 23 | public String list(HttpServletRequest request, Model model) { 24 | List recordInfoList = manageRecordService.list(); 25 | 26 | model.addAttribute("recordInfoList", recordInfoList); 27 | return "manage/record/list"; 28 | } 29 | 30 | @RequestMapping(value = "/add", method = RequestMethod.POST) 31 | public String insert(@ModelAttribute RecordInfo recordInfo, Model model) { 32 | manageRecordService.insert(recordInfo); 33 | 34 | return "redirect:list"; 35 | } 36 | 37 | @RequestMapping(value = "/update", method = RequestMethod.POST) 38 | public String update(@ModelAttribute RecordInfo recordInfo, Model model) { 39 | manageRecordService.update(recordInfo); 40 | 41 | return "redirect:list"; 42 | } 43 | 44 | @RequestMapping(value = "/edit/{id}", method = RequestMethod.GET) 45 | @ResponseBody 46 | public Map recordById(@PathVariable Integer id) { 47 | Map map = Maps.newHashMap(); 48 | 49 | RecordInfo recordInfo = manageRecordService.findById(id); 50 | map.put("recordInfo", recordInfo); 51 | return map; 52 | } 53 | 54 | @RequestMapping(value = "/delete", method = RequestMethod.POST) 55 | @ResponseBody 56 | public Map delete(@RequestParam(value = "id") Integer id) { 57 | Map map = Maps.newHashMap(); 58 | 59 | int status = manageRecordService.delete(id); 60 | map.put("status", status); 61 | 62 | return map; 63 | } 64 | 65 | } 66 | -------------------------------------------------------------------------------- /src/main/resources/application-dispatch.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | application/json;charset=UTF-8 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /src/main/resources/configuration.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /src/main/resources/logback.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36}:%line - %msg%n 11 | UTF-8 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | ${LOG_HOME}/PBlog.log.%d{yyyy-MM-dd}.log 20 | 30 21 | 22 | 23 | %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n 24 | UTF-8 25 | 26 | 27 | 28 | 50MB 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /src/main/resources/properties/pblog-local.properties: -------------------------------------------------------------------------------- 1 | ## jdbc properties 2 | jdbc.driverClassName=com.mysql.jdbc.Driver 3 | jdbc.url=jdbc:mysql://127.0.0.1:3306/pblog?useUnicode=true&characterEncoding=UTF-8 4 | jdbc.username=root 5 | jdbc.password=root 6 | 7 | 8 | ## imageUtils properties 9 | server.root.staticPath=/var/static/pblog/image 10 | server.root.relPath=/static/image/ 11 | 12 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/jsp/404.jsp: -------------------------------------------------------------------------------- 1 | <%@ page contentType="text/html;charset=UTF-8" language="java" %> 2 | 3 | 4 | Title 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/jsp/manage/about/about_edit.jsp: -------------------------------------------------------------------------------- 1 | <%@ include file="../include/namespace.jsp" %> 2 | <%@ page contentType="text/html;charset=UTF-8" language="java" %> 3 | 4 | 5 | 6 | 个人信息管理 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | <%@ include file="../include/index_man_header.jsp" %> 20 |
21 | <%@ include file="../include/index_second_header.jsp" %> 22 | 23 |
24 |
25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/jsp/manage/include/index_man_header.jsp: -------------------------------------------------------------------------------- 1 | <%@ page contentType="text/html;charset=UTF-8" language="java" %> 2 | 3 |
4 | 17 |
-------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/jsp/manage/include/index_second_header.jsp: -------------------------------------------------------------------------------- 1 | <%@ page contentType="text/html;charset=UTF-8" language="java" %> 2 |
3 |
    4 |
  1. ${first_nav}
  2. 5 |
  3. ${second_nav}
  4. 6 |
7 |
8 |
-------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/jsp/manage/include/namespace.jsp: -------------------------------------------------------------------------------- 1 | <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> 2 | <%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> 3 | <%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %> 4 | 5 | <%@ page language="java" contentType="text/html;charset=UTF-8" pageEncoding="utf-8" %> 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/jsp/web/archives/layout.jsp: -------------------------------------------------------------------------------- 1 | <%@ include file="../include/namespace.jsp" %> 2 | <%@ page contentType="text/html;charset=UTF-8" language="java" %> 3 | 4 |
5 |
6 |
文章存档
7 |
8 | 16 |
17 |
18 |
19 |
20 |
21 | 22 | {{ articleInfoVO.title }} 23 | 24 |
25 | 32 |
33 | 42 |
43 |
44 | 45 | <%@ include file="../include/footer.jsp" %> 46 |
47 |
-------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/jsp/web/article/article_mobile.jsp: -------------------------------------------------------------------------------- 1 | <%@ include file="../include/namespace.jsp" %> 2 | <%@ page contentType="text/html;charset=UTF-8" language="java" %> 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | Article | Pelin的个人博客 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | <%@ include file="../include/index_mobile_header.jsp"%> 23 |
24 |
25 |

${articleInfo.title}

26 |
27 |
28 |
29 |
30 | 31 | 32 | 33 | 41 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/jsp/web/article/layout.jsp: -------------------------------------------------------------------------------- 1 | <%@ include file="../include/namespace.jsp" %> 2 | <%@ page contentType="text/html;charset=UTF-8" language="java" %> 3 | 4 | 5 | 6 |
7 |
8 |
9 |

{{ articleVO.title }}

10 |
11 | 12 | 13 | {{ articleVO.createTime | date:'MMM d, EEEE' }} 14 | 15 | {{articleVO.reviewNum}}次点击 16 | {{ articleVO.categoryName }} 17 | 喜欢 18 |
19 |
20 |
21 |
22 | 23 | 24 |
25 |
26 |
27 | 28 | <%@ include file="../include/footer.jsp"%> 29 |
-------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/jsp/web/book/detail.jsp: -------------------------------------------------------------------------------- 1 | <%@ include file="../include/namespace.jsp" %> 2 | <%@ page contentType="text/html;charset=UTF-8" language="java" %> 3 | 4 |
5 |
6 |
7 |

{{ bookInfoVO.title }}

8 |
9 | 10 | 11 | {{ bookInfoVO.createTime | date:'MMM d, EEEE' }} 12 | 13 | {{ bookInfoVO.reviewNum }}次点击 14 | 喜欢 15 |
16 |
17 |
18 |
19 | > 星野道夫的北地之梦 20 | 21 |
22 |
23 |
24 | 25 | <%@ include file="../include/footer.jsp"%> 26 |
-------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/jsp/web/book/layout.jsp: -------------------------------------------------------------------------------- 1 | <%@ include file="../include/namespace.jsp" %> 2 | <%@ page contentType="text/html;charset=UTF-8" language="java" %> 3 | 4 |
5 |
6 | 读书 7 |
8 |
9 | 10 |
11 |
12 | 13 |
14 | Pelin / {{ bookInfo.createTime | date:'MM-dd HH:mm' }} / 阅读: {{ bookInfo.reviewNum }} 15 |
16 |
{{ bookInfo.introduction }}
17 |
18 |
19 | 20 |
21 |
22 | 23 |
24 | 在读 25 |
26 | {{ bookTable.bookName }} 27 |
28 |
29 |
30 |
31 | 32 | <%@ include file="../include/footer.jsp"%> -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/jsp/web/book/read_mobile.jsp: -------------------------------------------------------------------------------- 1 | <%@ include file="../include/namespace.jsp" %> 2 | <%@ page contentType="text/html;charset=UTF-8" language="java" %> 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | Books | Pelin的个人博客 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | <%@ include file="../include/index_mobile_header.jsp"%> 20 |
21 |
书评统计:1篇
22 |
书评列表
23 |
24 | 25 |
26 |
27 | 28 |
29 |
30 |

${bookInfoVO.title}

31 | 32 |
${bookInfoVO.introduction}
33 |
34 | 阅读 35 | 8344阅读 36 |
37 |
38 |
39 |
40 |
41 |
42 | 43 |
44 |
45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/jsp/web/book/read_mobile_detail.jsp: -------------------------------------------------------------------------------- 1 | <%@ include file="../include/namespace.jsp" %> 2 | <%@ page contentType="text/html;charset=UTF-8" language="java" %> 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | Read | Pelin的个人博客 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | <%@ include file="../include/index_mobile_header.jsp"%> 20 |
21 |
22 |

${bookInfoVO.title}

23 |
24 |
${bookInfoVO.content}
25 |
26 | 27 |
28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/jsp/web/category/layout.jsp: -------------------------------------------------------------------------------- 1 | <%@ include file="../include/namespace.jsp" %> 2 | <%@ page contentType="text/html;charset=UTF-8" language="java" %> 3 | 4 |
5 |
6 |
文章分类
7 |
8 | 14 |
15 |
16 |
17 |
18 |
19 | 20 | {{ articleInfoVO.title }} 21 | 22 |
23 | 30 |
31 | 40 |
41 |
42 | 43 | <%@ include file="../include/footer.jsp" %> 44 |
-------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/jsp/web/common/detail.jsp: -------------------------------------------------------------------------------- 1 | <%@ include file="../include/namespace.jsp" %> 2 | <%@ page contentType="text/html;charset=UTF-8" language="java" %> 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | Detail | Pelin的个人博客 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | <%@ include file="../include/index_mobile_header.jsp"%> 20 |
21 | 22 |
23 |

${articleInfo.title}

24 |
25 | 26 | 27 | 28 | 29 | ${articleInfo.categoryName} 30 |
31 |
${articleInfo.description}
32 | Continue reading 33 |
34 |
35 |
36 |
37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/jsp/web/home.jsp: -------------------------------------------------------------------------------- 1 | <%@ include file="include/namespace.jsp" %> 2 | <%@ page contentType="text/html;charset=UTF-8" language="java" %> 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 |
30 | 31 | <%@ include file="include/header.jsp" %> 32 |
33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/jsp/web/include/header.jsp: -------------------------------------------------------------------------------- 1 | <%@ page contentType="text/html;charset=UTF-8" language="java" %> 2 |
3 | 7 |
8 | 48 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/jsp/web/include/index_mobile_header.jsp: -------------------------------------------------------------------------------- 1 | <%@ page contentType="text/html;charset=UTF-8" language="java" %> 2 |
3 | 4 | Pelin's Blog 5 | 6 | 7 | 8 |
9 |
10 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/jsp/web/include/namespace.jsp: -------------------------------------------------------------------------------- 1 | <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> 2 | <%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> 3 | <%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %> 4 | <%@ page language="java" contentType="text/html;charset=UTF-8" pageEncoding="utf-8" %> 5 | <%@ page trimDirectiveWhitespaces="true" %> 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/jsp/web/index/index_mobile.jsp: -------------------------------------------------------------------------------- 1 | <%@ include file="../include/namespace.jsp" %> 2 | <%@ page contentType="text/html;charset=UTF-8" language="java" %> 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | Home | Pelin的个人博客 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | <%@ include file="../include/index_mobile_header.jsp"%> 20 |
21 | 22 |
23 |

${articleInfo.title}

24 |
25 | 26 | 27 | 28 | 29 | ${articleInfo.categoryName} 30 |
31 |
${articleInfo.description}
32 | Read More 33 |
34 |
35 |
36 |
37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/jsp/web/index/layout.jsp: -------------------------------------------------------------------------------- 1 | <%@ include file="../include/namespace.jsp" %> 2 | <%@ page contentType="text/html;charset=UTF-8" language="java" %> 3 | 4 |
5 |
6 |
7 |
8 |
9 | 10 | {{ article.title }} 11 |
12 |
13 | 21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |

{{ f_article.title }}

30 |
31 | 32 | 33 | {{ f_article.createTime | date:'MMM d, EEEE' }} 34 | 35 | {{f_article.reviewNum}}次点击 36 | {{ f_article.categoryName }} 37 | 喜欢 38 |
39 |
40 |
41 | 42 | <%@ include file="../include/footer.jsp"%> 43 |
44 |
-------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/jsp/web/record/layout.jsp: -------------------------------------------------------------------------------- 1 | <%@ include file="../include/namespace.jsp" %> 2 | <%@ page contentType="text/html;charset=UTF-8" language="java" %> 3 | 4 |
5 |
6 |
个人工作生活日志
7 |
8 |
9 |
10 |
2016年
11 |
12 |
13 |
{{ recordInfo.createTime | date:'MM月dd日' }}
14 |
{{ recordInfo.title }}
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 | 23 | 24 |
25 | <%@ include file="../include/footer.jsp"%> -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/jsp/web/rev-manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "night-pc-main.css": "night-pc-main-4e6b1e8763.min.css" 3 | } -------------------------------------------------------------------------------- /src/main/webapp/resources/assets/css/include/index_man_header.css: -------------------------------------------------------------------------------- 1 | header { 2 | top: 0; 3 | left: 0; 4 | background: #222222; 5 | position: fixed; 6 | z-index: 1000; 7 | } 8 | header .navbar-header { 9 | height: auto; 10 | position: fixed; 11 | right: 0; 12 | left: 0; 13 | top: 0; 14 | background: #222222; 15 | color: #9D9D9D; 16 | font-size: 18px; 17 | padding: 15px 0px 15px 20px; 18 | } 19 | header .navbar-right { 20 | position: fixed; 21 | right: 10px; 22 | color: #999999; 23 | top: 15px; 24 | font-size: 14px; 25 | } 26 | header .navbar-left { 27 | bottom: 0; 28 | position: fixed; 29 | top: 50px; 30 | background: #222222; 31 | width: 13%; 32 | } 33 | header .navbar-left ul { 34 | list-style: none; 35 | margin-top: 0; 36 | border: 0; 37 | } 38 | header .navbar-left ul a { 39 | text-decoration: none; 40 | color: #9D9D9D; 41 | } 42 | header .navbar-left ul li { 43 | line-height: 1.42857143; 44 | font-size: 14px; 45 | margin-left: -40px; 46 | padding: 15px 0px 15px 20px; 47 | } 48 | header .navbar-left ul li i { 49 | margin-right: 9px; 50 | } 51 | header .navbar-left ul li:hover { 52 | background: #000000; 53 | cursor: pointer; 54 | color: #ffffff; 55 | } 56 | header .navbar-left ul .active { 57 | line-height: 1.42857143; 58 | font-size: 14px; 59 | margin-left: -40px; 60 | padding: 15px 0px 15px 20px; 61 | background: #080808; 62 | color: #FFFFFF; 63 | } 64 | -------------------------------------------------------------------------------- /src/main/webapp/resources/assets/css/record/day_layout.css: -------------------------------------------------------------------------------- 1 | #record { 2 | position: relative; 3 | min-height: 600px; 4 | background: url("/resources/image/record_background.png") repeat; 5 | padding: 40px 0 223px 0; 6 | } 7 | #record .record-content { 8 | width: 55%; 9 | margin-left: 30%; 10 | } 11 | #record .record-content .record-title { 12 | font-size: 24px; 13 | height: 56px; 14 | line-height: 56px; 15 | padding-left: 60px; 16 | font-weight: 600; 17 | background: url("/resources/image/clock.png") no-repeat; 18 | background-position-y: 3px; 19 | background-size: 50px 50px; 20 | color: #7B95A7; 21 | } 22 | #record .record-content .main .year { 23 | position: relative; 24 | } 25 | #record .record-content .main .year .time-line { 26 | width: 2px; 27 | position: absolute; 28 | bottom: 0; 29 | top: -5px; 30 | background: #5495BA; 31 | left: 24px; 32 | } 33 | #record .record-content .main .year .year-title { 34 | width: 130px; 35 | font-size: 24px; 36 | color: #E5645D; 37 | margin-left: -132px; 38 | } 39 | #record .record-content .main .year .year-title i { 40 | margin-left: 10px; 41 | } 42 | #record .record-content .main .year .daily { 43 | margin-top: 40px; 44 | } 45 | #record .record-content .main .year .daily .daily-title { 46 | font-size: 19px; 47 | } 48 | #record .record-content .main .year .daily .daily-title .time { 49 | float: left; 50 | margin-left: -100px; 51 | color: #AB5411; 52 | } 53 | #record .record-content .main .year .daily .daily-title .title { 54 | float: left; 55 | margin-left: 65px; 56 | color: #37B158; 57 | font-weight: 600; 58 | } 59 | #record .record-content .main .year .daily .daily-content { 60 | margin: 10px 0 0 65px; 61 | color: #675050; 62 | padding-bottom: 5px; 63 | font-size: 14px; 64 | line-height: 24px; 65 | width: 525px; 66 | } 67 | #record .record-content .main .year .daily .daily-content p { 68 | margin: 0; 69 | padding: 0; 70 | } 71 | #record .record-content .main .year .daily .daily-content a { 72 | color: #675050; 73 | font-family: Consolas, serif; 74 | } 75 | #record .record-content .main .year .daily .daily-content img { 76 | max-width: 100%; 77 | margin-top: 10px; 78 | } 79 | #record .record-top { 80 | position: absolute; 81 | background: url("/resources/image/record_background_top.png"); 82 | width: 200px; 83 | height: 215px; 84 | display: inline-block; 85 | right: 26px; 86 | top: 14px; 87 | } 88 | #record .record-bottom { 89 | position: absolute; 90 | background: url("/resources/image/record_background_bottom.png"); 91 | width: 552px; 92 | height: 186px; 93 | display: inline-block; 94 | left: 130px; 95 | bottom: 25px; 96 | } 97 | -------------------------------------------------------------------------------- /src/main/webapp/resources/assets/css/record/night_layout.css: -------------------------------------------------------------------------------- 1 | #record { 2 | padding-top: 40px; 3 | min-height: 600px; 4 | background: #2F2D2D; 5 | border-bottom: 1px solid #000; 6 | } 7 | #record .record-content { 8 | width: 55%; 9 | margin-left: 30%; 10 | } 11 | #record .record-content .record-title { 12 | font-size: 24px; 13 | height: 56px; 14 | line-height: 56px; 15 | padding-left: 60px; 16 | font-weight: 600; 17 | background: url("/resources/image/clock.png") no-repeat; 18 | background-position-y: 3px; 19 | background-size: 50px 50px; 20 | color: #8A8888; 21 | } 22 | #record .record-content .main .year { 23 | position: relative; 24 | } 25 | #record .record-content .main .year .time-line { 26 | width: 2px; 27 | position: absolute; 28 | bottom: 0; 29 | top: -5px; 30 | background: #5495BA; 31 | left: 24px; 32 | } 33 | #record .record-content .main .year .year-title { 34 | width: 130px; 35 | font-size: 24px; 36 | color: #BD9662; 37 | margin-left: -132px; 38 | } 39 | #record .record-content .main .year .year-title i { 40 | margin-left: 10px; 41 | } 42 | #record .record-content .main .year .daily { 43 | padding-bottom: 40px; 44 | } 45 | #record .record-content .main .year .daily .daily-title { 46 | font-size: 19px; 47 | } 48 | #record .record-content .main .year .daily .daily-title .time { 49 | float: left; 50 | margin-left: -100px; 51 | color: #A9B7C6; 52 | } 53 | #record .record-content .main .year .daily .daily-title .title { 54 | float: left; 55 | margin-left: 65px; 56 | color: #63d029; 57 | } 58 | #record .record-content .main .year .daily .daily-content { 59 | font-size: 14px; 60 | color: #8A8888; 61 | font-family: Microsoft Yahei, serif; 62 | line-height: 24px; 63 | margin: 15px 0 0 65px; 64 | width: 530px; 65 | } 66 | #record .record-content .main .year .daily .daily-content p { 67 | margin: 0; 68 | padding: 0; 69 | } 70 | #record .record-content .main .year .daily .daily-content a { 71 | color: #AAAAAA; 72 | font-family: Consolas, serif; 73 | } 74 | #record .record-content .main .year .daily .daily-content img { 75 | max-width: 100%; 76 | margin-top: 10px; 77 | } 78 | #record .record-content .main .year .daily:first-child { 79 | margin-top: 40px; 80 | } 81 | -------------------------------------------------------------------------------- /src/main/webapp/resources/assets/css/resume/resume_mobile.css: -------------------------------------------------------------------------------- 1 | html { 2 | font-size: 14px; 3 | } 4 | body { 5 | font-size: 1rem; 6 | font-family: Arial, 'Microsoft YaHei', serif; 7 | word-break: break-all; 8 | background: #FFF; 9 | padding: 0; 10 | margin: 0; 11 | line-height: 1.6; 12 | } 13 | ul { 14 | padding: 0 0 0 2em; 15 | margin: 0; 16 | } 17 | #top { 18 | font-size: 1.2rem; 19 | background: #323639; 20 | height: 2.5em; 21 | } 22 | #top a { 23 | color: #FFF; 24 | text-decoration: none; 25 | line-height: 2.3em; 26 | } 27 | #top a .top-download { 28 | text-decoration: none; 29 | display: block; 30 | margin: auto; 31 | text-align: center; 32 | } 33 | #top .top-title { 34 | display: none; 35 | } 36 | #wrapper a { 37 | color: #42A5F5; 38 | text-decoration: none; 39 | } 40 | .header { 41 | margin-top: 0.5em; 42 | } 43 | .header .author-name { 44 | font-size: 1.4rem; 45 | } 46 | .header .header-list { 47 | margin-top: 0.8em; 48 | } 49 | .subtitle { 50 | font-size: 1.2rem; 51 | display: block; 52 | color: #943634; 53 | font-weight: 600; 54 | margin-bottom: 0.5em; 55 | } 56 | .person-info { 57 | margin-top: 1em; 58 | } 59 | .person-info .detail-list { 60 | padding-left: 1.5em; 61 | } 62 | .person-info .detail-list span { 63 | display: block; 64 | } 65 | .pro-skill { 66 | margin-top: 1em; 67 | } 68 | .work-experience { 69 | margin-top: 1em; 70 | } 71 | .work-experience .company { 72 | margin-top: 1em; 73 | } 74 | .work-experience .company h2 { 75 | font-size: 1.2rem; 76 | padding: 0; 77 | margin: 0; 78 | } 79 | .work-experience .company .tools { 80 | display: block; 81 | margin-bottom: 0.5em; 82 | text-indent: 0; 83 | } 84 | .work-experience .company .project-title { 85 | font-size: 1.1rem; 86 | display: block; 87 | padding-left: 0.5em; 88 | background: url("/resources/image/resume/li_icon.png") no-repeat; 89 | background-position-y: 0.4em; 90 | background-position-x: 0.35em; 91 | -webkit-background-size: 0.6em; 92 | background-size: 0.6em; 93 | font-weight: 600; 94 | } 95 | .work-experience .company span { 96 | display: block; 97 | text-indent: 1em; 98 | } 99 | .work-experience .company p { 100 | margin: 0; 101 | } 102 | .work-experience .company:first-child { 103 | margin-top: 0; 104 | } 105 | .open-source { 106 | margin-top: 1em; 107 | } 108 | .open-source .source-name { 109 | font-size: 1.1rem; 110 | font-weight: 600; 111 | } 112 | .open-source .source-url { 113 | display: block; 114 | } 115 | .honor-reward { 116 | margin-top: 1em; 117 | } 118 | .self-evaluation { 119 | margin: 1em 0 3em 0; 120 | } 121 | -------------------------------------------------------------------------------- /src/main/webapp/resources/assets/plugins/highlight.min.css: -------------------------------------------------------------------------------- 1 | code { 2 | line-height: 1.5!important; 3 | background: #2B2B2B!important; 4 | } 5 | 6 | .hljs { 7 | display: block; 8 | overflow-x: auto; 9 | padding: 0.5em; 10 | background: #23241f; 11 | } 12 | 13 | .hljs, 14 | .hljs-tag, 15 | .hljs-subst { 16 | color: #f8f8f2; 17 | } 18 | 19 | .hljs-strong, 20 | .hljs-emphasis { 21 | color: #a8a8a2; 22 | } 23 | 24 | .hljs-bullet, 25 | .hljs-quote, 26 | .hljs-number, 27 | .hljs-regexp, 28 | .hljs-literal, 29 | .hljs-link { 30 | color: #ae81ff; 31 | } 32 | 33 | .hljs-code, 34 | .hljs-title, 35 | .hljs-section, 36 | .hljs-selector-class { 37 | color: #a6e22e; 38 | } 39 | 40 | .hljs-strong { 41 | font-weight: bold; 42 | } 43 | 44 | .hljs-emphasis { 45 | font-style: italic; 46 | } 47 | 48 | .hljs-keyword, 49 | .hljs-selector-tag, 50 | .hljs-name, 51 | .hljs-attr { 52 | color: #f92672; 53 | } 54 | 55 | .hljs-symbol, 56 | .hljs-attribute { 57 | color: #66d9ef; 58 | } 59 | 60 | .hljs-params, 61 | .hljs-class .hljs-title { 62 | color: #f8f8f2; 63 | } 64 | 65 | .hljs-string, 66 | .hljs-type, 67 | .hljs-built_in, 68 | .hljs-builtin-name, 69 | .hljs-selector-id, 70 | .hljs-selector-attr, 71 | .hljs-selector-pseudo, 72 | .hljs-addition, 73 | .hljs-variable, 74 | .hljs-template-variable { 75 | color: #e6db74; 76 | } 77 | 78 | .hljs-comment, 79 | .hljs-deletion, 80 | .hljs-meta { 81 | color: #75715e; 82 | } -------------------------------------------------------------------------------- /src/main/webapp/resources/assets/rev/rev-manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "day-pc-main.css": "day-pc-main-4b3b2e648a.css", 3 | "night-pc-main.css": "night-pc-main-4e6b1e8763.css" 4 | } -------------------------------------------------------------------------------- /src/main/webapp/resources/font/FontAwesome.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/penglongli/PBlog/6824591e56afeee5d06c02ab79f47a27584709c1/src/main/webapp/resources/font/FontAwesome.otf -------------------------------------------------------------------------------- /src/main/webapp/resources/font/anjingchen.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/penglongli/PBlog/6824591e56afeee5d06c02ab79f47a27584709c1/src/main/webapp/resources/font/anjingchen.ttf -------------------------------------------------------------------------------- /src/main/webapp/resources/font/fontawesome-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/penglongli/PBlog/6824591e56afeee5d06c02ab79f47a27584709c1/src/main/webapp/resources/font/fontawesome-webfont.eot -------------------------------------------------------------------------------- /src/main/webapp/resources/font/fontawesome-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/penglongli/PBlog/6824591e56afeee5d06c02ab79f47a27584709c1/src/main/webapp/resources/font/fontawesome-webfont.ttf -------------------------------------------------------------------------------- /src/main/webapp/resources/font/fontawesome-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/penglongli/PBlog/6824591e56afeee5d06c02ab79f47a27584709c1/src/main/webapp/resources/font/fontawesome-webfont.woff -------------------------------------------------------------------------------- /src/main/webapp/resources/font/fontawesome-webfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/penglongli/PBlog/6824591e56afeee5d06c02ab79f47a27584709c1/src/main/webapp/resources/font/fontawesome-webfont.woff2 -------------------------------------------------------------------------------- /src/main/webapp/resources/font/xiaofeng.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/penglongli/PBlog/6824591e56afeee5d06c02ab79f47a27584709c1/src/main/webapp/resources/font/xiaofeng.ttf -------------------------------------------------------------------------------- /src/main/webapp/resources/image/about_me.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/penglongli/PBlog/6824591e56afeee5d06c02ab79f47a27584709c1/src/main/webapp/resources/image/about_me.jpg -------------------------------------------------------------------------------- /src/main/webapp/resources/image/author_header.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/penglongli/PBlog/6824591e56afeee5d06c02ab79f47a27584709c1/src/main/webapp/resources/image/author_header.png -------------------------------------------------------------------------------- /src/main/webapp/resources/image/circle-h.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/penglongli/PBlog/6824591e56afeee5d06c02ab79f47a27584709c1/src/main/webapp/resources/image/circle-h.png -------------------------------------------------------------------------------- /src/main/webapp/resources/image/clock.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/penglongli/PBlog/6824591e56afeee5d06c02ab79f47a27584709c1/src/main/webapp/resources/image/clock.png -------------------------------------------------------------------------------- /src/main/webapp/resources/image/csdn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/penglongli/PBlog/6824591e56afeee5d06c02ab79f47a27584709c1/src/main/webapp/resources/image/csdn.png -------------------------------------------------------------------------------- /src/main/webapp/resources/image/day_content_backgrund.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/penglongli/PBlog/6824591e56afeee5d06c02ab79f47a27584709c1/src/main/webapp/resources/image/day_content_backgrund.jpg -------------------------------------------------------------------------------- /src/main/webapp/resources/image/mobile_slider_bar.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/penglongli/PBlog/6824591e56afeee5d06c02ab79f47a27584709c1/src/main/webapp/resources/image/mobile_slider_bar.jpg -------------------------------------------------------------------------------- /src/main/webapp/resources/image/pblog_icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/penglongli/PBlog/6824591e56afeee5d06c02ab79f47a27584709c1/src/main/webapp/resources/image/pblog_icon.ico -------------------------------------------------------------------------------- /src/main/webapp/resources/image/record_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/penglongli/PBlog/6824591e56afeee5d06c02ab79f47a27584709c1/src/main/webapp/resources/image/record_background.png -------------------------------------------------------------------------------- /src/main/webapp/resources/image/record_background_bottom.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/penglongli/PBlog/6824591e56afeee5d06c02ab79f47a27584709c1/src/main/webapp/resources/image/record_background_bottom.png -------------------------------------------------------------------------------- /src/main/webapp/resources/image/record_background_top.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/penglongli/PBlog/6824591e56afeee5d06c02ab79f47a27584709c1/src/main/webapp/resources/image/record_background_top.png -------------------------------------------------------------------------------- /src/main/webapp/resources/image/resume/honor_reward_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/penglongli/PBlog/6824591e56afeee5d06c02ab79f47a27584709c1/src/main/webapp/resources/image/resume/honor_reward_icon.png -------------------------------------------------------------------------------- /src/main/webapp/resources/image/resume/li_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/penglongli/PBlog/6824591e56afeee5d06c02ab79f47a27584709c1/src/main/webapp/resources/image/resume/li_icon.png -------------------------------------------------------------------------------- /src/main/webapp/resources/image/resume/open_source_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/penglongli/PBlog/6824591e56afeee5d06c02ab79f47a27584709c1/src/main/webapp/resources/image/resume/open_source_icon.png -------------------------------------------------------------------------------- /src/main/webapp/resources/image/resume/person_info_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/penglongli/PBlog/6824591e56afeee5d06c02ab79f47a27584709c1/src/main/webapp/resources/image/resume/person_info_icon.png -------------------------------------------------------------------------------- /src/main/webapp/resources/image/resume/pro_skill_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/penglongli/PBlog/6824591e56afeee5d06c02ab79f47a27584709c1/src/main/webapp/resources/image/resume/pro_skill_icon.png -------------------------------------------------------------------------------- /src/main/webapp/resources/image/resume/self_evaluation_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/penglongli/PBlog/6824591e56afeee5d06c02ab79f47a27584709c1/src/main/webapp/resources/image/resume/self_evaluation_icon.png -------------------------------------------------------------------------------- /src/main/webapp/resources/image/resume/work_experience_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/penglongli/PBlog/6824591e56afeee5d06c02ab79f47a27584709c1/src/main/webapp/resources/image/resume/work_experience_icon.png -------------------------------------------------------------------------------- /src/main/webapp/resources/image/search_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/penglongli/PBlog/6824591e56afeee5d06c02ab79f47a27584709c1/src/main/webapp/resources/image/search_background.png -------------------------------------------------------------------------------- /src/main/webapp/resources/image/zhihu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/penglongli/PBlog/6824591e56afeee5d06c02ab79f47a27584709c1/src/main/webapp/resources/image/zhihu.png -------------------------------------------------------------------------------- /src/main/webapp/resources/js/controllers/AboutController.js: -------------------------------------------------------------------------------- 1 | 2 | var AboutController = function ($scope, $interval, $http, $timeout) { 3 | initializeAbout(); 4 | initializeLoad($scope, $timeout); 5 | }; 6 | 7 | function initializeAbout() { 8 | $(".menu_bar ul li").each(function (index) { 9 | if(index == 5) { 10 | $(this).addClass("active"); 11 | }else { 12 | $(this).removeClass("active"); 13 | } 14 | }); 15 | 16 | $(document).attr("title","关于 | Pelin的个人博客"); 17 | } -------------------------------------------------------------------------------- /src/main/webapp/resources/js/controllers/ArchivesController.js: -------------------------------------------------------------------------------- 1 | 2 | var ArchivesController = function ($scope, $interval, $http, $timeout) { 3 | 4 | $scope.fetchArchivesList = function () { 5 | $http.get('/archivesList.json'). 6 | success(function (data) { 7 | $scope.archivesList = data.archivesVOList; 8 | $scope.articleList = data.archivesVOList[0].articleInfoVOList; 9 | }). 10 | error(function (err) { 11 | console.log(err); 12 | }); 13 | }; 14 | 15 | initializeArchives(); 16 | initializeLoad($scope, $timeout); 17 | $scope.fetchArchivesList(); 18 | }; 19 | 20 | /** 21 | * 初始化 22 | */ 23 | function initializeArchives() { 24 | $(".menu_bar ul li").each(function (index) { 25 | if(index == 1) { 26 | $(this).addClass("active"); 27 | }else { 28 | $(this).removeClass("active"); 29 | } 30 | }); 31 | 32 | $(document).attr("title","归档 | Pelin的个人博客"); 33 | } -------------------------------------------------------------------------------- /src/main/webapp/resources/js/controllers/ArchivesTimeStampController.js: -------------------------------------------------------------------------------- 1 | 2 | var ArchivesTimeStampController = function ($scope, $interval, $http, $timeout, $routeParams) { 3 | var timeStamp = $routeParams.timeStamp; 4 | 5 | $scope.fetchArchivesTimeStampList = function () { 6 | $http.get('/archives/' + timeStamp + '.json'). 7 | success(function (data) { 8 | $scope.archivesList = data.archivesVOList; 9 | $scope.articleList = data.articleInfoVOList; 10 | $scope.timeStamp = timeStamp; 11 | }). 12 | error(function (err) { 13 | console.log(err); 14 | }); 15 | }; 16 | 17 | initializeArchivesTimeStamp(); 18 | initializeLoad($scope, $timeout); 19 | 20 | $scope.fetchArchivesTimeStampList(); 21 | }; 22 | 23 | function initializeArchivesTimeStamp() { 24 | $(".menu_bar ul li").each(function (index) { 25 | if(index == 1) { 26 | $(this).addClass("active"); 27 | }else { 28 | $(this).removeClass("active"); 29 | } 30 | }); 31 | 32 | $(document).attr("title","归档 | Pelin的个人博客"); 33 | } -------------------------------------------------------------------------------- /src/main/webapp/resources/js/controllers/BookController.js: -------------------------------------------------------------------------------- 1 | 2 | var BookController = function ($scope, $interval, $http, $timeout, $routeParams) { 3 | var bookSlug = $routeParams.bookSlug; 4 | 5 | $scope.fetchBooksDetail = function () { 6 | $http.get('/book/' + bookSlug + '.json'). 7 | success(function(data) { 8 | initializeBook(data.bookInfoVO.title); 9 | initializeBookContent(data.bookInfoVO.content); 10 | 11 | $scope.bookInfoVO = data.bookInfoVO; 12 | }). 13 | error(function(err) { 14 | console.log(err); 15 | }); 16 | }; 17 | 18 | initializeLoad($scope, $timeout); 19 | $scope.fetchBooksDetail(); 20 | }; 21 | 22 | 23 | function initializeBook(book_title) { 24 | $(".menu_bar ul li").each(function (index) { 25 | if(index == 3) { 26 | $(this).addClass("active"); 27 | }else { 28 | $(this).removeClass("active"); 29 | } 30 | }); 31 | 32 | $(document).attr("title", book_title + " | Pelin的个人博客"); 33 | } 34 | 35 | function initializeBookContent(content_md) { 36 | var $contentBody = $(".content-body"); 37 | 38 | //初始化书评内容 39 | console.log(marked(content_md)); 40 | $contentBody.html(marked(content_md)); 41 | 42 | //监测窗口滚动并更新文章导航条active 43 | $(window).scroll(function () { 44 | //45为搜索栏高度 45 | var scrollDistance = $("body").scrollTop() + 30; 46 | 47 | if (scrollDistance > 165) { 48 | $(".content-nav").addClass("fixed"); 49 | } else if (scrollDistance <= 165) { 50 | $(".content-nav").removeClass("fixed"); 51 | } 52 | }); 53 | } -------------------------------------------------------------------------------- /src/main/webapp/resources/js/controllers/CategoryController.js: -------------------------------------------------------------------------------- 1 | 2 | var CategoryController = function ($scope, $interval, $http, $timeout) { 3 | 4 | $scope.fetchCategoryList = function () { 5 | $http.get('/categoryList.json'). 6 | success(function (data) { 7 | $scope.categoryList = data.categoryInfoVOList; 8 | $scope.articleList = data.articleInfoVOList; 9 | }). 10 | error(function (err) { 11 | console.log(err); 12 | }); 13 | }; 14 | 15 | initializeCategory(); 16 | initializeLoad($scope, $timeout); 17 | $scope.fetchCategoryList(); 18 | }; 19 | 20 | function initializeCategory() { 21 | $(".menu_bar ul li").each(function (index) { 22 | if(index == 2) { 23 | $(this).addClass("active"); 24 | }else { 25 | $(this).removeClass("active"); 26 | } 27 | }); 28 | 29 | $(document).attr("title","分类 | Pelin的个人博客"); 30 | } -------------------------------------------------------------------------------- /src/main/webapp/resources/js/controllers/CategorySlugController.js: -------------------------------------------------------------------------------- 1 | 2 | var CategorySlugController = function ($scope, $interval, $http, $timeout, $routeParams) { 3 | var categorySlug = $routeParams.categorySlug; 4 | 5 | $scope.fetchCategorySlugList = function () { 6 | $http.get('/category/' + categorySlug + '.json'). 7 | success(function (data) { 8 | $scope.categoryList = data.categoryInfoVOList; 9 | $scope.articleList = data.articleInfoVOList; 10 | }). 11 | error(function (err) { 12 | console.log(err); 13 | }); 14 | }; 15 | 16 | initializeCategorySlug(); 17 | initializeLoad($scope, $timeout); 18 | 19 | $scope.fetchCategorySlugList(); 20 | }; 21 | 22 | function initializeCategorySlug () { 23 | $(".menu_bar ul li").each(function (index) { 24 | if(index == 2) { 25 | $(this).addClass("active"); 26 | }else { 27 | $(this).removeClass("active"); 28 | } 29 | }); 30 | 31 | $(document).attr("title","分类 | Pelin的个人博客"); 32 | } -------------------------------------------------------------------------------- /src/main/webapp/resources/js/controllers/IndexController.js: -------------------------------------------------------------------------------- 1 | 2 | var IndexController = function ($scope, $interval, $http, $timeout) { 3 | 4 | $scope.fetchArticlesList = function () { 5 | $http.get('/topTenArticle.json'). 6 | success(function(data) { 7 | $scope.detail = data.detail; 8 | $scope.articleList = data.pagination.items; 9 | $scope.f_article = data.firstArticle; 10 | 11 | initializeIndex($scope.f_article.content); 12 | }). 13 | error(function (err) { 14 | console.log(err); 15 | }); 16 | }; 17 | 18 | initializeIndexLoad($scope, $timeout); 19 | $scope.fetchArticlesList(); 20 | }; 21 | /** 22 | * 初始化文章内容 23 | * @param content_md 文章内容MD 24 | */ 25 | function initializeIndex(content_md){ 26 | var $contentBody = $(".content-body"); 27 | 28 | $(".menu_bar ul li").each(function (index) { 29 | if(index == 0) { 30 | $(this).addClass("active"); 31 | }else { 32 | $(this).removeClass("active"); 33 | } 34 | }); 35 | 36 | $(document).attr("title","首页 | Pelin的个人博客"); 37 | 38 | $contentBody.html(marked(content_md)); 39 | } 40 | 41 | /** 42 | * 加载首页进度条(因为首页有滚动条,为了让 **滚动条** 能够加载,必须等到数据已经动态加载结束后加载 **滚动条**) 43 | * @param $scope 44 | * @param $timeout 45 | */ 46 | 47 | function initializeIndexLoad($scope, $timeout) { 48 | $scope.start(); 49 | $scope.fakeIntro = true; 50 | $timeout(function() { 51 | $scope.complete(); 52 | $scope.fakeIntro = false; 53 | 54 | initializeHighLight(); 55 | loadSlider(); 56 | }, 750); 57 | } 58 | 59 | /** 60 | * 加载滚动条 61 | */ 62 | function loadSlider(){ 63 | var $container = $(".scroll-area"); 64 | var $content = $(".index-article-list"); 65 | var $slideArea = $(".scroll-vertical"); 66 | var $bar = $(".scroll-bar"); 67 | 68 | $container.slider({ 69 | container: $container, 70 | content: $content, 71 | slideArea: $slideArea, 72 | bar: $bar 73 | }); 74 | } -------------------------------------------------------------------------------- /src/main/webapp/resources/js/controllers/ReadController.js: -------------------------------------------------------------------------------- 1 | 2 | var ReadController = function ($scope, $interval, $http, $timeout) { 3 | 4 | $scope.fetchBooksList = function () { 5 | $http.get('/book/list.json'). 6 | success(function(data) { 7 | $scope.bookInfoList = data.bookInfoVOList; 8 | $scope.bookTableList = data.bookTableVOList; 9 | }). 10 | error(function(err) { 11 | console.log(err); 12 | }); 13 | }; 14 | 15 | initializeRead(); 16 | initializeLoad($scope, $timeout); 17 | $scope.fetchBooksList(); 18 | }; 19 | 20 | function initializeRead() { 21 | $(".menu_bar ul li").each(function (index) { 22 | if(index == 3) { 23 | $(this).addClass("active"); 24 | }else { 25 | $(this).removeClass("active"); 26 | } 27 | }); 28 | 29 | $(document).attr("title","读书 | Pelin的个人博客"); 30 | } -------------------------------------------------------------------------------- /src/main/webapp/resources/js/controllers/RecordController.js: -------------------------------------------------------------------------------- 1 | 2 | var RecordController = function ($scope, $interval, $http, $timeout, $routeParams) { 3 | 4 | $scope.fetchRecordList = function () { 5 | $http.get('/record.json'). 6 | success(function (data) { 7 | $scope.recordInfoList = data.recordInfoList; 8 | 9 | for(var i = 0; i < data.recordInfoList.length; i++) { 10 | $scope.recordInfoList[i].content = marked(data.recordInfoList[i].content); 11 | } 12 | }) 13 | }; 14 | 15 | initializeRecord(); 16 | initializeLoad($scope, $timeout); 17 | $scope.fetchRecordList(); 18 | }; 19 | 20 | function initializeRecord () { 21 | $(".menu_bar ul li").each(function (index) { 22 | if(index == 4) { 23 | $(this).addClass("active"); 24 | }else { 25 | $(this).removeClass("active"); 26 | } 27 | }); 28 | 29 | $(document).attr("title","记录 | Pelin的个人博客"); 30 | } 31 | 32 | -------------------------------------------------------------------------------- /src/main/webapp/resources/js/directives.js: -------------------------------------------------------------------------------- 1 | /* Directives */ 2 | 3 | var AppDirectives = angular.module('pBlogApp.directives', []); 4 | 5 | AppDirectives.directive('appVersion', ['version', function (version) { 6 | return function (scope, elm, attrs) { 7 | elm.text(version); 8 | }; 9 | }]); 10 | -------------------------------------------------------------------------------- /src/main/webapp/resources/js/filters.js: -------------------------------------------------------------------------------- 1 | /* Filters */ 2 | 3 | var AppFilters = angular.module('pBlogApp.filters', []); 4 | 5 | AppFilters.filter('interpolate', ['version', function (version) { 6 | return function (text) { 7 | return String(text).replace(/\%VERSION\%/mg, version); 8 | } 9 | }]); 10 | -------------------------------------------------------------------------------- /src/main/webapp/resources/js/mobile/analytics.js: -------------------------------------------------------------------------------- 1 | var _hmt = _hmt || []; 2 | (function() { 3 | var hm = document.createElement("script"); 4 | hm.src = "//hm.baidu.com/hm.js?03296f04a7ca2b9ee9d16adfbd1e2c17"; 5 | var s = document.getElementsByTagName("script")[0]; 6 | s.parentNode.insertBefore(hm, s); 7 | })(); -------------------------------------------------------------------------------- /src/main/webapp/resources/js/mobile/global_mobile.js: -------------------------------------------------------------------------------- 1 | var $Wrapper = $("#Wrapper"); 2 | var $SlideBar = $("#SlideBar"); 3 | var $Content = $("#Content"); 4 | var $Top = $("#Top"); 5 | var $body = $(document.body); 6 | var startX, endX, status = 0; 7 | 8 | $(document).ready(function(){ 9 | loadFontSize(); 10 | }); 11 | 12 | function loadFontSize() { 13 | var templateWidth = 320; 14 | var actualWidth = $(window).width(); 15 | 16 | $("html").css("font-size", (actualWidth * 1.0) / templateWidth * 12 + "px"); 17 | } 18 | 19 | 20 | function slide() { 21 | if (status == 1) { 22 | //向左滑动 23 | $SlideBar.animate({'right': '100%'}, 500); 24 | $Top.animate({'left': '0'}, 500); 25 | $Content.animate({'left': '0'}, 500, function () { 26 | $body.removeClass("body-slide"); 27 | $Content.removeClass("content-slide"); 28 | }); 29 | status = 0; 30 | } else if (status == 0) { 31 | //向右滑动 32 | $body.addClass("body-slide"); 33 | $Content.addClass("content-slide"); 34 | $SlideBar.animate({'right': '24%'}, 500); 35 | $Top.animate({'left': '76%'}, 500); 36 | $Content.animate({'left': '76%'}, 500); 37 | status = 1; 38 | } 39 | } 40 | 41 | function sleep(n){ 42 | var start = new Date().getTime(); 43 | while (true) if (new Date().getTime() - start > n){ 44 | break; 45 | } 46 | } 47 | 48 | $Wrapper.on({ 49 | touchstart: function (e) { 50 | var touch = e.originalEvent.touches[0] || e.originalEvent.changedTouches[0]; 51 | startX = touch.pageX; 52 | }, 53 | touchend: function (e) { 54 | var touch = e.originalEvent.touches[0] || e.originalEvent.changedTouches[0]; 55 | endX = touch.pageX; 56 | 57 | var distanceX = endX - startX; 58 | 59 | if (status == 1) { 60 | if (distanceX < 0) { 61 | //向左滑动 62 | $SlideBar.animate({'right': '100%'}, 500); 63 | $Top.animate({'left': '0'}, 500); 64 | $Content.animate({'left': '0'}, 500, function () { 65 | $body.removeClass("body-slide"); 66 | $Content.removeClass("content-slide"); 67 | }); 68 | status = 0; 69 | } 70 | } 71 | } 72 | }); 73 | 74 | //初始化时间轴 75 | function timeLineInitial(){ 76 | var $rightItem = $(".right-item"); 77 | var $leftItem = $(".left-item"); 78 | var nodeSize = $leftItem.size(); 79 | 80 | for(var i = 0; i < nodeSize; i++){ 81 | var rightHeight = $rightItem.eq(i).outerHeight(); 82 | 83 | $($leftItem[i]).css({"height": rightHeight + 40}); 84 | $($rightItem[i]).fadeIn("slow"); 85 | $($leftItem[i]).fadeIn("slow"); 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /src/main/webapp/resources/js/routes.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/penglongli/PBlog/6824591e56afeee5d06c02ab79f47a27584709c1/src/main/webapp/resources/js/routes.js -------------------------------------------------------------------------------- /src/main/webapp/resources/js/services.js: -------------------------------------------------------------------------------- 1 | /* Services */ 2 | 3 | var AppServices = angular.module('pBlogApp.services', []); 4 | 5 | AppServices.value('version', '0.1'); 6 | -------------------------------------------------------------------------------- /src/main/webapp/resources/less/book/day_detail.less: -------------------------------------------------------------------------------- 1 | 2 | #bookDetail { 3 | .book-content{ 4 | font-size: 1.5rem; 5 | width: 100%; 6 | line-height: 1.85em; 7 | color: #424242; 8 | font-weight: 300; 9 | padding-bottom: 20px; 10 | margin-bottom: 30px; 11 | border-bottom: 1px solid #515658; 12 | 13 | .content-head { 14 | border-bottom: 1px solid #DDDDDD; 15 | text-align: center; 16 | width: 60%; 17 | padding-right: 30%; 18 | padding-left: 10%; 19 | 20 | h1 { 21 | margin-left: 2%; 22 | font-size: 21px; 23 | color: #444; 24 | } 25 | 26 | .content-head-detail { 27 | margin-bottom: 0.6em; 28 | margin-left: 2%; 29 | 30 | span { 31 | font-size: 1rem; 32 | color: #BDBDBD; 33 | margin-left: 1.35rem; 34 | 35 | i { 36 | margin-right: 0.15rem; 37 | } 38 | } 39 | 40 | .c_time { 41 | margin: 0; 42 | } 43 | 44 | .c_name a{ 45 | color: red; 46 | text-decoration: none; 47 | } 48 | 49 | .c_eye { 50 | 51 | } 52 | 53 | .c_like a{ 54 | color: red; 55 | text-decoration: none; 56 | } 57 | 58 | a:hover{ 59 | text-decoration: underline; 60 | } 61 | 62 | } 63 | 64 | } 65 | 66 | .content-body { 67 | width: 60%; 68 | float: left; 69 | min-height: 600px; 70 | margin-left: 10%; 71 | color: #666; 72 | 73 | p { 74 | text-indent: 2em; 75 | } 76 | } 77 | 78 | .content-nav { 79 | width: 240px; 80 | float: right; 81 | margin-top: 1em; 82 | margin-right: 25px; 83 | 84 | span { 85 | font-size: 14px; 86 | color: #D9D9D9; 87 | 88 | a { 89 | color: #4094c7; 90 | text-decoration: none; 91 | } 92 | } 93 | 94 | img { 95 | margin: 10px 0 0 10px; 96 | } 97 | } 98 | 99 | .fixed { 100 | position: fixed; 101 | right: 0; 102 | top: 50px; 103 | } 104 | 105 | em { 106 | font-size: 1.3rem; 107 | font-style: normal!important; 108 | background: #F6F6F6; 109 | padding: 0.2em 0.8em; 110 | color: #C7254E; 111 | font-family: Consolas, sans-serif !important; 112 | } 113 | 114 | code { 115 | font-size: 1.1rem; 116 | font-family: Menlo,Monaco,Consolas,"Courier New",monospace; 117 | } 118 | 119 | h1, h2, h3 { 120 | font-family: GothicCustom,'Arial Narrow',sans-serif; 121 | } 122 | } 123 | 124 | } -------------------------------------------------------------------------------- /src/main/webapp/resources/less/book/night_detail.less: -------------------------------------------------------------------------------- 1 | 2 | #bookDetail { 3 | .book-content{ 4 | font-size: 1.5rem; 5 | width: 100%; 6 | line-height: 1.85em; 7 | color: #424242; 8 | font-weight: 300; 9 | padding-bottom: 30px; 10 | border-bottom: 1px solid #000; 11 | 12 | .content-head { 13 | border-bottom: 1px solid #515658; 14 | text-align: center; 15 | width: 60%; 16 | padding-right: 30%; 17 | padding-left: 10%; 18 | 19 | h1 { 20 | margin-left: 2%; 21 | font-size: 21px; 22 | } 23 | 24 | .content-head-detail { 25 | margin-bottom: 0.6em; 26 | margin-left: 2%; 27 | 28 | span { 29 | font-size: 1rem; 30 | color: #BDBDBD; 31 | margin-left: 1.35rem; 32 | 33 | i { 34 | margin-right: 0.15rem; 35 | } 36 | } 37 | 38 | .c_time { 39 | margin: 0; 40 | } 41 | 42 | .c_name a{ 43 | color: red; 44 | text-decoration: none; 45 | } 46 | 47 | .c_eye { 48 | 49 | } 50 | 51 | .c_like a{ 52 | color: red; 53 | text-decoration: none; 54 | } 55 | 56 | a:hover{ 57 | text-decoration: underline; 58 | } 59 | 60 | } 61 | 62 | } 63 | 64 | .content-body { 65 | width: 60%; 66 | float: left; 67 | min-height: 600px; 68 | margin-left: 10%; 69 | color: #8A8888; 70 | 71 | p { 72 | text-indent: 2em; 73 | } 74 | } 75 | 76 | .content-nav { 77 | width: 240px; 78 | float: right; 79 | margin-top: 1em; 80 | margin-right: 25px; 81 | 82 | span { 83 | font-size: 14px; 84 | color: #D9D9D9; 85 | 86 | a { 87 | color: #4094c7; 88 | text-decoration: none; 89 | } 90 | } 91 | 92 | img { 93 | margin: 10px 0 0 10px; 94 | } 95 | } 96 | 97 | .fixed { 98 | position: fixed; 99 | right: 0; 100 | top: 50px; 101 | } 102 | 103 | em { 104 | font-size: 1.3rem; 105 | font-style: normal!important; 106 | background: #F6F6F6; 107 | padding: 0.2em 0.8em; 108 | color: #C7254E; 109 | font-family: Consolas, sans-serif !important; 110 | } 111 | 112 | code { 113 | font-size: 1.1rem; 114 | font-family: Menlo,Monaco,Consolas,"Courier New",monospace; 115 | } 116 | 117 | h1, h2, h3 { 118 | font-family: GothicCustom,'Arial Narrow',sans-serif; 119 | } 120 | 121 | h1 { 122 | color: #D2D8BA; 123 | } 124 | } 125 | 126 | } -------------------------------------------------------------------------------- /src/main/webapp/resources/less/include/index_man_header.less: -------------------------------------------------------------------------------- 1 | header{ 2 | top: 0; 3 | left: 0; 4 | background: #222222; 5 | position: fixed; 6 | z-index: 1000; 7 | 8 | .navbar-header{ 9 | height: auto; 10 | position: fixed; 11 | right: 0; 12 | left: 0; 13 | top: 0; 14 | background: #222222; 15 | color: #9D9D9D; 16 | font-size: 18px; 17 | padding: 15px 0px 15px 20px; 18 | } 19 | 20 | .navbar-right{ 21 | position: fixed; 22 | right: 10px; 23 | color: #999999; 24 | top: 15px; 25 | font-size: 14px; 26 | } 27 | 28 | .navbar-left{ 29 | bottom: 0; 30 | position: fixed; 31 | top: 50px; 32 | background: #222222; 33 | width: 13%; 34 | 35 | ul{ 36 | list-style: none; 37 | margin-top: 0; 38 | border: 0; 39 | 40 | a { 41 | text-decoration: none; 42 | color: #9D9D9D; 43 | } 44 | 45 | li{ 46 | line-height: 1.42857143; 47 | font-size: 14px; 48 | margin-left: -40px; 49 | padding: 15px 0px 15px 20px; 50 | 51 | i{ 52 | margin-right: 9px; 53 | } 54 | 55 | &:hover{ 56 | background: #000000; 57 | cursor: pointer; 58 | color: #ffffff; 59 | } 60 | } 61 | .active{ 62 | line-height: 1.42857143; 63 | font-size: 14px; 64 | margin-left: -40px; 65 | padding: 15px 0px 15px 20px; 66 | background: #080808; 67 | color: #FFFFFF; 68 | } 69 | } 70 | } 71 | } -------------------------------------------------------------------------------- /src/main/webapp/resources/less/manage/about_edit.less: -------------------------------------------------------------------------------- 1 | @import "../include/index_man_header"; 2 | @import "../include/global"; 3 | -------------------------------------------------------------------------------- /src/main/webapp/resources/less/manage/article_list.less: -------------------------------------------------------------------------------- 1 | @import "../include/index_man_header"; 2 | @import "../include/global"; 3 | 4 | body{ 5 | font-family: "Microsoft Yahei",sans-serif; 6 | margin: 0; 7 | 8 | .content-find{ 9 | width: 99%; 10 | padding-bottom: 10px; 11 | padding-top: 10px; 12 | border-bottom: 1px solid #F5F5F5; 13 | 14 | .find-by-type{ 15 | float: left; 16 | font-size: 12px; 17 | color: #999999; 18 | 19 | select{ 20 | margin-left: 5px; 21 | font-size: 13px; 22 | padding: 1px 0px; 23 | } 24 | } 25 | 26 | .add-article{ 27 | float: right; 28 | font-size: 14px; 29 | 30 | a{ 31 | padding: 8px 13px; 32 | background: #3BB2D6; 33 | color: #FFFFFF; 34 | font-weight: bold; 35 | 36 | &:link{ 37 | text-decoration: none; 38 | } 39 | } 40 | } 41 | } 42 | 43 | .content-article-list{ 44 | width: 99%; 45 | 46 | table{ 47 | width: 100%; 48 | border-collapse: collapse; 49 | text-align: center; 50 | 51 | thead{ 52 | width: inherit; 53 | background: #4DBCE9; 54 | color: #FFFFFF; 55 | 56 | tr th{ 57 | padding: 10px 0px; 58 | } 59 | } 60 | tbody{ 61 | width: inherit; 62 | font-size: 14px; 63 | 64 | tr{ 65 | border-top: 1px solid #EEEEEE; 66 | 67 | td{ 68 | padding: 10px 0; 69 | line-height: 1.5; 70 | 71 | span{ 72 | color: #999999; 73 | font-size: 12px; 74 | } 75 | 76 | a{ 77 | font-size: 12px; 78 | padding: 6px 10px; 79 | background: #57D249!important; 80 | margin-left: 3px; 81 | color: #FFFFFF; 82 | border: 1px solid #fff; 83 | 84 | &:link{ 85 | text-decoration: none; 86 | } 87 | } 88 | } 89 | } 90 | 91 | } 92 | .slug{ 93 | width: 10%; 94 | } 95 | .title{ 96 | width: 35%; 97 | text-align: left !important; 98 | } 99 | .viewNum{ 100 | width: 10%; 101 | } 102 | .thumbNum{ 103 | width:10%; 104 | } 105 | .status{ 106 | width: 10%; 107 | } 108 | .operate{ 109 | width: 25%; 110 | } 111 | } 112 | 113 | } 114 | } 115 | 116 | -------------------------------------------------------------------------------- /src/main/webapp/resources/less/manage/category_list.less: -------------------------------------------------------------------------------- 1 | @import "../include/index_man_header"; 2 | @import "../include/global"; 3 | 4 | .cat-list { 5 | margin-top: 14px; 6 | 7 | table { 8 | width: 99%; 9 | border-collapse: collapse; 10 | text-align: center; 11 | 12 | thead { 13 | font-size: 15px; 14 | width: inherit; 15 | background: #4DBCE9; 16 | color: #FFFFFF; 17 | 18 | th { 19 | padding: 10px 0; 20 | } 21 | 22 | .slug { width: 15%; } 23 | .category { width: 45%; } 24 | .num { width: 15%; } 25 | .operate { width: 25%; } 26 | } 27 | 28 | tbody { 29 | font-size: 13px; 30 | 31 | tr { 32 | line-height: 50px; 33 | } 34 | 35 | img { 36 | width: 90px; 37 | margin: 10px; 38 | } 39 | 40 | a { 41 | background: #57D249!important; 42 | } 43 | } 44 | } 45 | 46 | .click-btn { 47 | background: #57D249; 48 | } 49 | } 50 | 51 | #mask-edit { 52 | 53 | .modal-body { 54 | 55 | span { 56 | display: block; 57 | } 58 | 59 | input { 60 | width: 64%; 61 | line-height: 23px; 62 | height: 24px; 63 | text-align: initial; 64 | border: 1px solid #c8c8c8; 65 | border-radius: 3px; 66 | font-weight: 400; 67 | padding-left: 2%; 68 | color: #777; 69 | margin-top: 10px; 70 | } 71 | } 72 | } -------------------------------------------------------------------------------- /src/main/webapp/resources/less/manage/pic_list.less: -------------------------------------------------------------------------------- 1 | @import "../include/index_man_header"; 2 | @import "../include/global"; 3 | 4 | 5 | .pic-list { 6 | margin-top: 10px; 7 | 8 | table { 9 | width: 99%; 10 | border-collapse: collapse; 11 | text-align: center; 12 | 13 | thead { 14 | font-size: 15px; 15 | width: inherit; 16 | background: #4DBCE9; 17 | color: #FFFFFF; 18 | 19 | th { 20 | padding: 10px 0; 21 | } 22 | } 23 | 24 | tbody { 25 | font-size: 13px; 26 | 27 | img { 28 | width: 90px; 29 | margin: 10px; 30 | } 31 | 32 | a { 33 | background: #57D249!important; 34 | } 35 | } 36 | } 37 | } 38 | 39 | #mask-upload { 40 | 41 | 42 | .upload-wrapper { 43 | position: relative; 44 | height: 31px; 45 | width: 92px; 46 | display: inline-block; 47 | 48 | input { 49 | width: 80px; 50 | opacity: 0; 51 | position: absolute; 52 | z-index: 100; 53 | padding: 5px; 54 | } 55 | 56 | span { 57 | position: absolute; 58 | width: 80px; 59 | text-align: center; 60 | z-index: 11; 61 | background: #EEEEEE; 62 | border: 1px solid #96D2F6; 63 | color: #1784C7; 64 | padding: 5px; 65 | border-radius: 6px; 66 | } 67 | } 68 | 69 | .upload-wrapper:hover { 70 | cursor: pointer; 71 | } 72 | } -------------------------------------------------------------------------------- /src/main/webapp/resources/less/manage/record_list.less: -------------------------------------------------------------------------------- 1 | @import "../include/index_man_header"; 2 | @import "../include/global"; 3 | 4 | 5 | .modal-body { 6 | 7 | .title { 8 | margin-bottom: 15px; 9 | } 10 | 11 | span { 12 | display: inline-block; 13 | margin-right: 8px; 14 | } 15 | 16 | input { 17 | width: calc(65% - 1px); 18 | line-height: 23px; 19 | height: 24px; 20 | text-align: initial; 21 | border: 1px solid #c8c8c8; 22 | border-radius: 3px; 23 | font-weight: 400; 24 | padding-left: 2%; 25 | color: #777; 26 | } 27 | 28 | .record-content { 29 | 30 | span { 31 | float: left; 32 | } 33 | 34 | textarea { 35 | border-color: #CCCCCC #999999 #999999 #CCCCCC; 36 | border-style: solid; 37 | border-width: 1px; 38 | font-family: arial,sans-serif; 39 | font-size: 13px; 40 | height: 160px; 41 | outline-style: none; 42 | outline-width: medium; 43 | padding: 2px; 44 | width: 80%; 45 | float: left; 46 | border-radius: 5px; 47 | color: #777; 48 | margin-left: 5px; 49 | } 50 | } 51 | } 52 | 53 | table { 54 | width: 99%; 55 | margin-top: 13px; 56 | border-collapse: collapse; 57 | text-align: center; 58 | 59 | thead { 60 | font-size: 15px; 61 | width: inherit; 62 | background: #4DBCE9; 63 | color: #FFFFFF; 64 | 65 | th { 66 | padding: 10px 0; 67 | } 68 | } 69 | 70 | tbody { 71 | font-size: 13px; 72 | 73 | img { 74 | width: 90px; 75 | margin: 10px; 76 | } 77 | 78 | a { 79 | background: #57D249!important; 80 | } 81 | } 82 | } -------------------------------------------------------------------------------- /src/main/webapp/resources/less/mobile/about_mobile.less: -------------------------------------------------------------------------------- 1 | @import "../include/index_mobile_global"; 2 | 3 | body { 4 | background: #FFF!important; 5 | } 6 | 7 | #Content { 8 | padding: 0!important; 9 | font-family: Lato, "PingFang SC", "Microsoft YaHei", sans-serif; 10 | font-size: 1.2rem; 11 | margin: 3em 0; 12 | } 13 | 14 | .header-image { 15 | max-width: 100%; 16 | } 17 | 18 | .about-detail { 19 | margin: 0; 20 | padding: 0 5%; 21 | word-break: break-all; 22 | 23 | .spot { 24 | font-size: 1.1rem; 25 | text-align: center; 26 | margin: 1.5em 0; 27 | 28 | a { 29 | font-size: 1.2rem; 30 | position: relative; 31 | width: 14.5em; 32 | display: inline-block; 33 | height: 3em; 34 | border-radius: 5px; 35 | text-decoration: none; 36 | color: #FFF; 37 | background: #DF611A; 38 | 39 | i { 40 | font-size: 1.75rem; 41 | margin-right: .25em; 42 | position: absolute; 43 | left: .8em; 44 | line-height: 2.1em; 45 | } 46 | 47 | span { 48 | position: absolute; 49 | left: 3.5em; 50 | line-height: 3em; 51 | } 52 | } 53 | } 54 | 55 | 56 | .contact, .person, .open-source, .work-experience, .education, .awards, .technical { 57 | margin-top: 1.5em; 58 | 59 | h2 { 60 | font-size: 1.4rem; 61 | color: #424242; 62 | font-family: GothicCustom, 'Arial Narrow', sans-serif; 63 | margin: 0; 64 | } 65 | 66 | a { 67 | margin-left: .2em; 68 | color: #796A66; 69 | } 70 | 71 | ul { 72 | margin-top: .6em; 73 | 74 | li { 75 | margin-top: .3em; 76 | line-height: 1.6; 77 | } 78 | } 79 | } 80 | 81 | .social { 82 | font-size: 1rem; 83 | margin-top: 1.5em; 84 | 85 | a { 86 | margin-left: 5px; 87 | display: inline-block; 88 | } 89 | 90 | img, svg { 91 | width: 4em; 92 | height: 4em; 93 | border-radius: 50%; 94 | } 95 | } 96 | 97 | } -------------------------------------------------------------------------------- /src/main/webapp/resources/less/mobile/article_mobile.less: -------------------------------------------------------------------------------- 1 | @import "../include/index_mobile_global"; 2 | 3 | 4 | #Content { 5 | margin-top: 3.5em; 6 | padding-bottom: .1em; 7 | //font-family: Georgia, Times, "Times New Roman", Helvetica, "Microsoft YaHei", Arial, sans-serif !important; 8 | padding-top: .1em!important; 9 | } 10 | 11 | h1, h2, h3 { 12 | font-family: GothicCustom, 'Arial Narrow', sans-serif; 13 | text-shadow: 1px 1px #CCC; 14 | margin-bottom: 0.5em; 15 | } 16 | 17 | h1 { 18 | font-size: 1.8rem; 19 | } 20 | 21 | h2 { 22 | font-size: 1.6rem; 23 | } 24 | 25 | pre code { 26 | font-size: 1.05rem; 27 | font-family: Menlo, Monaco, Consolas, "Courier New", monospace; 28 | padding-top: .5em; 29 | padding-bottom: .5em; 30 | } 31 | 32 | .article-content { 33 | font-size: 1.2rem; 34 | line-height: 1.6; 35 | text-align: justify; 36 | word-break: break-all; 37 | margin-bottom: 3em; 38 | 39 | ul, ol { 40 | padding: 0; 41 | margin: 0 0 0 2em; 42 | 43 | li { 44 | margin-top: .05em; 45 | } 46 | } 47 | 48 | table { 49 | border: 1px solid silver; 50 | border-collapse: collapse; 51 | text-align: center; 52 | 53 | td { 54 | border: 1px solid silver; 55 | border-collapse: collapse; 56 | padding: 3px 10px; 57 | } 58 | } 59 | 60 | em { 61 | font-style: normal; 62 | color: #5F9F4D; 63 | } 64 | 65 | blockquote { 66 | font-size: 1rem; 67 | border-left: 3px solid #C1272D; 68 | background: #F1F1F1; 69 | padding: 0.2em 0.6em; 70 | margin: 0; 71 | } 72 | 73 | a { 74 | color: #42A5F5; 75 | text-decoration: none; 76 | } 77 | 78 | img { 79 | max-width: 100%; 80 | } 81 | 82 | strong { 83 | display: inline-block!important; 84 | } 85 | } -------------------------------------------------------------------------------- /src/main/webapp/resources/less/mobile/article_mobile_list.less: -------------------------------------------------------------------------------- 1 | @import "../include/index_mobile_global"; 2 | 3 | .article { 4 | margin-top: 1em; 5 | padding-bottom: 1em; 6 | border-bottom: 1px solid #E3F2FD; 7 | 8 | .article-detail { 9 | font-size: 1rem; 10 | margin-top: .6em; 11 | 12 | .time { 13 | color: #BFBFBF; 14 | } 15 | 16 | .category { 17 | margin-left: .7em; 18 | } 19 | } 20 | 21 | .article-description { 22 | font-size: 1.1rem; 23 | color: #424242; 24 | text-indent: 2em; 25 | } 26 | 27 | .continue-read a{ 28 | font-size: 1.1rem; 29 | color: #42A5F5; 30 | } 31 | 32 | &:first-child { 33 | margin-top: 4.5em; 34 | } 35 | 36 | h1 { 37 | font-size: 1.5rem; 38 | font-weight: normal; 39 | margin: 0; 40 | 41 | a { 42 | color: #555; 43 | text-shadow: 1px 1px #CCC; 44 | } 45 | } 46 | 47 | a { 48 | text-decoration: none; 49 | } 50 | } -------------------------------------------------------------------------------- /src/main/webapp/resources/less/mobile/read_mobile.less: -------------------------------------------------------------------------------- 1 | @import "../include/index_mobile_global"; 2 | 3 | body { 4 | background: #F8F9F9!important; 5 | } 6 | 7 | #Content { 8 | padding: 0!important; 9 | margin-top: 3.5em!important; 10 | } 11 | 12 | .read-header { 13 | width: 100%; 14 | margin: 0; 15 | padding: 0.5em 0; 16 | background: #FFF; 17 | color: #535353; 18 | text-align: center; 19 | border-top: 1px solid #E7F3FD; 20 | 21 | i { 22 | margin-right: 0.3em; 23 | } 24 | 25 | span { 26 | color: #F7443D; 27 | } 28 | } 29 | 30 | .read-title { 31 | font-size: 1.2rem; 32 | width: 100%; 33 | background: #F3F3F3; 34 | color: #ACABB0; 35 | padding: 0.4em 0 0.4em 1em; 36 | border-bottom: 1px solid #E4E3E6; 37 | } 38 | 39 | .books-list { 40 | 41 | .book { 42 | padding-bottom: 20px; 43 | border-bottom: 1px solid #ddd; 44 | 45 | .cover { 46 | width: 90px; 47 | float: left; 48 | margin-left: 16px; 49 | margin-top: 15px; 50 | 51 | img { 52 | width: 90px; 53 | } 54 | } 55 | 56 | .info { 57 | float: left; 58 | width: e("calc(100% - 126px)"); 59 | margin-left: 10px; 60 | margin-top: 15px; 61 | padding-right: 10px; 62 | 63 | .title { 64 | font-size: 1.2rem; 65 | margin: 0; 66 | 67 | a { 68 | color: #333; 69 | text-decoration: none; 70 | } 71 | } 72 | 73 | .detail { 74 | font-size: 0.94rem; 75 | color: #676767; 76 | margin-top: 8px; 77 | margin-bottom: 8px; 78 | 79 | a { 80 | text-decoration: none; 81 | } 82 | 83 | a:after { 84 | content: ' \ '; 85 | margin-right: 8px; 86 | } 87 | } 88 | 89 | .intro { 90 | color: #a6a6a6; 91 | font-size: 1rem; 92 | line-height: 1.7; 93 | } 94 | 95 | .actions { 96 | margin-top: 15px; 97 | 98 | a { 99 | background: #77A4B3; 100 | text-decoration: none; 101 | color: #FFF; 102 | font-size: 1.15rem; 103 | padding: 5px 15px; 104 | border-radius: 3px; 105 | display: inline-block; 106 | } 107 | 108 | span { 109 | font-size: 1.05rem; 110 | color: #a6a6a6; 111 | } 112 | } 113 | } 114 | 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /src/main/webapp/resources/less/mobile/read_mobile_detail.less: -------------------------------------------------------------------------------- 1 | @import "../include/index_mobile_global"; 2 | 3 | #Content { 4 | margin-top: 3.5em; 5 | padding-bottom: .1em; 6 | padding-top: .1em!important; 7 | font-family: "Open Sans","Noto Sans","Noto Sans CJK SC","Microsoft Yahei",sans-serif; 8 | } 9 | 10 | h1, h2, h3 { 11 | font-family: GothicCustom, 'Arial Narrow', sans-serif; 12 | color: #333; 13 | } 14 | 15 | h1 { 16 | font-size: 1.6rem; 17 | font-family: Verdana,Geneva,"Open Sans",SimHei,"Noto Sans","Noto Sans CJK SC","Microsoft Yahei",sans-serif; 18 | font-weight: 400; 19 | } 20 | 21 | h2 { 22 | font-size: 1.4rem; 23 | margin-top: 2em; 24 | } 25 | 26 | h3 { 27 | font-size: 1.2rem; 28 | } 29 | 30 | .read-content { 31 | font-size: 1.2rem; 32 | line-height: 1.6; 33 | text-align: justify; 34 | word-break: break-all; 35 | 36 | 37 | ul { 38 | padding: 0; 39 | margin-left: 3em; 40 | 41 | li { 42 | margin-top: .05em; 43 | } 44 | } 45 | 46 | em { 47 | font-style: normal; 48 | color: #5F9F4D; 49 | } 50 | 51 | a { 52 | color: #42A5F5; 53 | text-decoration: none; 54 | } 55 | 56 | p { 57 | text-indent: 2em; 58 | } 59 | } -------------------------------------------------------------------------------- /src/main/webapp/resources/less/mobile/time_line.less: -------------------------------------------------------------------------------- 1 | @import "../include/index_mobile_global"; 2 | 3 | body { 4 | background: #F3F3F3!important; 5 | } 6 | 7 | #Content { 8 | padding: 0!important; 9 | margin-top: 3.5em!important; 10 | } 11 | 12 | .archive-header { 13 | width: 100%; 14 | margin: 0; 15 | padding: 0.5em 0; 16 | background: #FFF; 17 | color: #535353; 18 | text-align: center; 19 | border-top: 1px solid #E7F3FD; 20 | 21 | i { 22 | margin-right: 0.3em; 23 | } 24 | 25 | span { 26 | color: #F7443D; 27 | } 28 | } 29 | 30 | .archive-title { 31 | font-size: 1.2rem; 32 | width: 100%; 33 | background: #EFEEF3; 34 | color: #ACABB0; 35 | padding: 0.4em 0 0.4em 1em; 36 | border-bottom: 1px solid #E4E3E6; 37 | } 38 | 39 | .archive-timeline { 40 | font-size: 1rem; 41 | width: 100%; 42 | margin: 0; 43 | background: #FFF; 44 | padding-top: 1em; 45 | min-height: 10em; 46 | 47 | .timeline-left{ 48 | font-size: 1rem; 49 | width: 33%; 50 | float: left; 51 | margin-left: 1em; 52 | 53 | .left-item{ 54 | position: relative; 55 | height: 10em; 56 | border-right: 1px solid #E4E4E4; 57 | display: none; 58 | 59 | span { 60 | 61 | a { 62 | text-decoration: none; 63 | color: red; 64 | padding-right: 0.3em; 65 | } 66 | } 67 | 68 | .time-point{ 69 | background: #FFF; 70 | border: 2px solid #3AB07C; 71 | width: 0.8em; 72 | height: 0.8em; 73 | -webkit-border-radius: 50%; 74 | -moz-border-radius: 50%; 75 | border-radius: 50%; 76 | position: absolute; 77 | top: .1em; 78 | right: -0.6em; 79 | } 80 | } 81 | } 82 | 83 | .timeline-right{ 84 | font-size: 1.15em; 85 | float: left; 86 | width: 56%; 87 | margin-left: 5%; 88 | 89 | .right-item{ 90 | height: auto; 91 | margin-top: 40px; 92 | padding-bottom: 2.5em; 93 | border-bottom: 1px solid #ECECEC; 94 | display: none; 95 | 96 | &:first-child{ 97 | margin-top: 0; 98 | } 99 | 100 | .article-item{ 101 | color: #555; 102 | margin-top: 2em; 103 | 104 | span { 105 | display: block; 106 | font-weight: 600; 107 | } 108 | 109 | a { 110 | color: #555; 111 | text-decoration: none; 112 | display: block; 113 | margin-top: 0.3em; 114 | } 115 | } 116 | .article-item:first-child{ 117 | margin-top: 0; 118 | } 119 | 120 | } 121 | } 122 | } -------------------------------------------------------------------------------- /src/main/webapp/resources/less/record/night_layout.less: -------------------------------------------------------------------------------- 1 | 2 | #record { 3 | padding-top: 40px; 4 | min-height: 600px; 5 | background: #2F2D2D; 6 | border-bottom: 1px solid #000; 7 | 8 | .record-content { 9 | width: 55%; 10 | margin-left: 30%; 11 | 12 | .record-title { 13 | font-size: 24px; 14 | height: 56px; 15 | line-height: 56px; 16 | padding-left: 60px; 17 | font-weight: 600; 18 | background: url("/resources/image/clock.png") no-repeat; 19 | background-position-y: 3px; 20 | background-size: 50px 50px; 21 | color: #8A8888; 22 | } 23 | 24 | .main { 25 | 26 | .year { 27 | position: relative; 28 | 29 | .time-line { 30 | width: 2px; 31 | position: absolute; 32 | bottom: 0; 33 | top: -5px; 34 | background: #5495BA; 35 | left: 24px; 36 | } 37 | 38 | .year-title { 39 | width: 130px; 40 | font-size: 24px; 41 | color: #BD9662; 42 | margin-left: -132px; 43 | 44 | i { 45 | margin-left: 10px; 46 | } 47 | } 48 | 49 | .daily { 50 | padding-bottom: 40px; 51 | 52 | .daily-title { 53 | font-size: 19px; 54 | 55 | .time { 56 | float: left; 57 | margin-left: -100px; 58 | color: #A9B7C6; 59 | } 60 | 61 | .title { 62 | float: left; 63 | margin-left: 65px; 64 | color: #63d029; 65 | } 66 | } 67 | 68 | .daily-content { 69 | font-size: 14px; 70 | color: #8A8888; 71 | font-family: Microsoft Yahei, serif; 72 | line-height: 24px; 73 | margin: 15px 0 0 65px; 74 | width: 530px; 75 | 76 | p { 77 | margin: 0; 78 | padding: 0; 79 | } 80 | 81 | a { 82 | color: #AAAAAA; 83 | font-family: Consolas, serif; 84 | } 85 | 86 | img { 87 | max-width: 100%; 88 | margin-top: 10px; 89 | } 90 | } 91 | } 92 | 93 | .daily:first-child { 94 | margin-top: 40px; 95 | } 96 | } 97 | } 98 | } 99 | } -------------------------------------------------------------------------------- /src/test/GenerateSlugInfo.java: -------------------------------------------------------------------------------- 1 | import com.google.common.collect.Lists; 2 | import com.pblog.service.archives.ArchivesVO; 3 | import com.pblog.service.article.SimpleArticleInfo; 4 | import com.pblog.service.slug.SlugInfoService; 5 | import junit.framework.TestCase; 6 | import org.springframework.context.support.ClassPathXmlApplicationContext; 7 | 8 | import java.text.ParseException; 9 | import java.text.SimpleDateFormat; 10 | import java.util.Date; 11 | import java.util.List; 12 | 13 | public class GenerateSlugInfo extends TestCase{ 14 | private ClassPathXmlApplicationContext applicationContext; 15 | 16 | protected void setUp(){ 17 | applicationContext = new ClassPathXmlApplicationContext("classpath:application.xml"); 18 | System.out.println(applicationContext); 19 | } 20 | 21 | /*public void testInsertSlug(){ 22 | SlugInfoService slugInfoService = (SlugInfoService) applicationContext.getBean("slugInfoService"); 23 | System.out.println(slugInfoService); 24 | 25 | slugInfoService.insert(); 26 | }*/ 27 | 28 | } 29 | -------------------------------------------------------------------------------- /前台页面功能设计.md: -------------------------------------------------------------------------------- 1 | ##导航 2 | 首页 3 | 归档 4 | 分类 5 | 书评 6 | 记录 7 | 关于 8 | ## 首页 9 | 右侧是最新文章。10条。左侧是作者简介 10 | ## 归档 11 | 右侧是归档。左侧是最新文章、阅读排行各十篇 12 | ## 分类 13 | 右侧是分类。左侧是最新文章、阅读排行各十篇 14 | ## 书评 15 | 右侧是读书。左侧是最新文章、阅读排行各十篇 16 | ## 记录 17 | 右侧是记录。左侧是最新文章、阅读排行各十篇 18 | ## 关于 19 | 右侧是关于。左侧是作者简介。 20 | 21 | 22 | 分类: 23 | 1、数据结构与算法 24 | 2、计算机网络及安全 25 | 3、Spring源码 26 | 4、Java基础巩固 27 | 5、设计模式 28 | 6、数据库分析 29 | 7、Java虚拟机了解 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /数据库设计.md: -------------------------------------------------------------------------------- 1 | article_info(文章表): 2 | id 3 | title 4 | content 5 | slug 6 | createTime 7 | lastModifyTime 8 | categorySlug 9 | tagId 10 | thumb 11 | enabled 12 | 13 | article_read_log(阅读日志表): 14 | id 15 | articleId 16 | ipAddress 17 | createTime 18 | type: 类型,1为阅读,2为点赞 19 | 20 | category_info(分类表): 21 | id 22 | createTime 23 | title 24 | slug 25 | tag_info(标签表): 26 | id 27 | createTime 28 | title 29 | 30 | record_info(日志记录表): 31 | id 32 | title 33 | createTime 34 | content 35 | slug 36 | record_read_log(记录表日志记录): 37 | id 38 | recordId 39 | ipAddress 40 | createTime 41 | 42 | book_info(读书表): 43 | id 44 | title 45 | createTime 46 | slug 47 | banner 48 | thumb 49 | introduction 50 | 51 | book_read_log(读书文章记录表): 52 | id 53 | bookId 54 | ipAddress 55 | createTime 56 | type: 1为阅读,2为点赞 57 | 58 | author_info(作者简介) 59 | id 60 | name 61 | motto 62 | email 63 | address 64 | github 65 | zhihu 66 | csdn 67 | resume_info(简历) 68 | id 69 | content 70 | createTime 71 | 72 | 73 | 74 | --------------------------------------------------------------------------------