├── .gitignore ├── LICENSE ├── README.md ├── my-blog.sh ├── pom.xml ├── sqls └── schema.sql ├── src ├── main │ ├── java │ │ └── com │ │ │ └── my │ │ │ └── blog │ │ │ └── website │ │ │ ├── CoreApplication.java │ │ │ ├── constant │ │ │ └── WebConst.java │ │ │ ├── controller │ │ │ ├── BaseController.java │ │ │ ├── GlobalExceptionHandler.java │ │ │ ├── IndexController.java │ │ │ └── admin │ │ │ │ ├── ArticleController.java │ │ │ │ ├── AttachController.java │ │ │ │ ├── AuthController.java │ │ │ │ ├── CategoryController.java │ │ │ │ ├── CommentController.java │ │ │ │ ├── IndexController.java │ │ │ │ ├── LinksController.java │ │ │ │ ├── PageController.java │ │ │ │ └── SettingController.java │ │ │ ├── dao │ │ │ ├── AttachVoMapper.java │ │ │ ├── CommentVoMapper.java │ │ │ ├── ContentVoMapper.java │ │ │ ├── LogVoMapper.java │ │ │ ├── MetaVoMapper.java │ │ │ ├── OptionVoMapper.java │ │ │ ├── RelationshipVoMapper.java │ │ │ └── UserVoMapper.java │ │ │ ├── dto │ │ │ ├── DataSource.java │ │ │ ├── ErrorCode.java │ │ │ ├── LogActions.java │ │ │ ├── MetaDto.java │ │ │ └── Types.java │ │ │ ├── exception │ │ │ └── TipException.java │ │ │ ├── interceptor │ │ │ ├── BaseInterceptor.java │ │ │ └── WebMvcConfig.java │ │ │ ├── model │ │ │ ├── Bo │ │ │ │ ├── ArchiveBo.java │ │ │ │ ├── BackResponseBo.java │ │ │ │ ├── CommentBo.java │ │ │ │ ├── RestResponseBo.java │ │ │ │ └── StatisticsBo.java │ │ │ └── Vo │ │ │ │ ├── AttachVo.java │ │ │ │ ├── AttachVoExample.java │ │ │ │ ├── CommentVo.java │ │ │ │ ├── CommentVoExample.java │ │ │ │ ├── ContentVo.java │ │ │ │ ├── ContentVoExample.java │ │ │ │ ├── LogVo.java │ │ │ │ ├── LogVoExample.java │ │ │ │ ├── MetaVo.java │ │ │ │ ├── MetaVoExample.java │ │ │ │ ├── OptionVo.java │ │ │ │ ├── OptionVoExample.java │ │ │ │ ├── RelationshipVoExample.java │ │ │ │ ├── RelationshipVoKey.java │ │ │ │ ├── UserVo.java │ │ │ │ └── UserVoExample.java │ │ │ ├── service │ │ │ ├── IAttachService.java │ │ │ ├── ICommentService.java │ │ │ ├── IContentService.java │ │ │ ├── ILogService.java │ │ │ ├── IMetaService.java │ │ │ ├── IOptionService.java │ │ │ ├── IRelationshipService.java │ │ │ ├── ISiteService.java │ │ │ ├── IUserService.java │ │ │ └── impl │ │ │ │ ├── AttachServiceImpl.java │ │ │ │ ├── CommentServiceImpl.java │ │ │ │ ├── ContentServiceImpl.java │ │ │ │ ├── LogServiceImpl.java │ │ │ │ ├── MetaServiceImpl.java │ │ │ │ ├── OptionServiceImpl.java │ │ │ │ ├── RelationshipServiceImpl.java │ │ │ │ ├── SiteServiceImpl.java │ │ │ │ └── UserServiceImpl.java │ │ │ └── utils │ │ │ ├── AdminCommons.java │ │ │ ├── Commons.java │ │ │ ├── DateKit.java │ │ │ ├── GsonUtils.java │ │ │ ├── IPKit.java │ │ │ ├── LogAspect.java │ │ │ ├── MapCache.java │ │ │ ├── PatternKit.java │ │ │ ├── TaleUtils.java │ │ │ ├── Tools.java │ │ │ ├── UUID.java │ │ │ ├── ZipUtils.java │ │ │ └── backup │ │ │ ├── Backup.java │ │ │ ├── Column.java │ │ │ ├── ColumnCollection.java │ │ │ ├── FK.java │ │ │ ├── FKCollection.java │ │ │ ├── Table.java │ │ │ ├── TableCollection.java │ │ │ └── db │ │ │ ├── Column.java │ │ │ ├── ColumnCollection.java │ │ │ ├── DataTable.java │ │ │ └── Row.java │ └── resources │ │ ├── application.yml │ │ ├── log4j2.xml │ │ ├── mapper │ │ ├── AttachVoMapper.xml │ │ ├── CommentVoMapper.xml │ │ ├── ContentVoMapper.xml │ │ ├── LogVoMapper.xml │ │ ├── MetaVoMapper.xml │ │ ├── OptionVoMapper.xml │ │ ├── RelationshipVoMapper.xml │ │ └── UserVoMapper.xml │ │ ├── static │ │ ├── admin │ │ │ ├── css │ │ │ │ └── style.min.css │ │ │ ├── images │ │ │ │ ├── attach.png │ │ │ │ ├── bg │ │ │ │ │ ├── 1.png │ │ │ │ │ ├── 2.png │ │ │ │ │ ├── 3.png │ │ │ │ │ ├── 4.png │ │ │ │ │ └── 5.png │ │ │ │ ├── favicon.png │ │ │ │ ├── loading.gif │ │ │ │ ├── logo.png │ │ │ │ └── small │ │ │ │ │ └── bg.jpg │ │ │ ├── js │ │ │ │ ├── article.js │ │ │ │ ├── base.js │ │ │ │ ├── install.js │ │ │ │ └── jquery.app.js │ │ │ └── plugins │ │ │ │ ├── jquery-multi-select │ │ │ │ ├── img │ │ │ │ │ └── switch.png │ │ │ │ └── jquery.quicksearch.js │ │ │ │ ├── jquery.steps │ │ │ │ └── demo │ │ │ │ │ └── css │ │ │ │ │ └── jquery.steps.css │ │ │ │ ├── md │ │ │ │ ├── css │ │ │ │ │ └── style.css │ │ │ │ ├── img │ │ │ │ │ └── editor.png │ │ │ │ └── js │ │ │ │ │ ├── diff.js │ │ │ │ │ ├── jquery.js │ │ │ │ │ ├── jquery.scrollto.js │ │ │ │ │ ├── md.js │ │ │ │ │ ├── pagedown-extra.js │ │ │ │ │ └── pagedown.js │ │ │ │ ├── select2.dist.css │ │ │ │ ├── select2-bootstrap.css │ │ │ │ ├── select2-spinner.gif │ │ │ │ ├── select2.css │ │ │ │ ├── select2.png │ │ │ │ └── select2x2.png │ │ │ │ ├── tagsinput │ │ │ │ ├── jquery.tagsinput.css │ │ │ │ └── jquery.tagsinput.min.js │ │ │ │ └── toggles │ │ │ │ └── toggles.css │ │ └── user │ │ │ ├── css │ │ │ └── style.min.css │ │ │ └── img │ │ │ ├── apple-touch-icon.png │ │ │ ├── bg-ico.png │ │ │ ├── favicon.png │ │ │ ├── logo.png │ │ │ └── rand │ │ │ ├── 1.jpg │ │ │ ├── 10.jpg │ │ │ ├── 11.jpg │ │ │ ├── 12.jpg │ │ │ ├── 13.jpg │ │ │ ├── 14.jpg │ │ │ ├── 15.jpg │ │ │ ├── 16.jpg │ │ │ ├── 17.jpg │ │ │ ├── 18.jpg │ │ │ ├── 19.jpg │ │ │ ├── 2.jpg │ │ │ ├── 3.jpg │ │ │ ├── 4.jpg │ │ │ ├── 5.jpg │ │ │ ├── 6.jpg │ │ │ ├── 7.jpg │ │ │ ├── 8.jpg │ │ │ └── 9.jpg │ │ └── templates │ │ ├── admin │ │ ├── article_edit.html │ │ ├── article_list.html │ │ ├── attach.html │ │ ├── category.html │ │ ├── comment_list.html │ │ ├── footer.html │ │ ├── header.html │ │ ├── index.html │ │ ├── links.html │ │ ├── login.html │ │ ├── page_edit.html │ │ ├── page_list.html │ │ ├── profile.html │ │ └── setting.html │ │ ├── comm │ │ ├── error_404.html │ │ ├── error_500.html │ │ ├── macros.html │ │ └── tale_comment.html │ │ └── themes │ │ ├── README │ │ └── default │ │ ├── archives.html │ │ ├── comments.html │ │ ├── footer.html │ │ ├── header.html │ │ ├── index.html │ │ ├── links.html │ │ ├── old_comments.html │ │ ├── page-category.html │ │ ├── page.html │ │ └── post.html └── test │ └── java │ └── com │ └── my │ └── blog │ └── website │ ├── AsyncTest.java │ ├── Pwdtest.java │ ├── TranscationTest.java │ └── controller │ └── IndexControllerTest.java └── static └── images ├── 1.png ├── 2.png ├── 3.png ├── 4.png └── 5.png /.gitignore: -------------------------------------------------------------------------------- 1 | ### STS ### 2 | .apt_generated 3 | .classpath 4 | .factorypath 5 | .project 6 | .settings 7 | .springBeans 8 | 9 | ### IntelliJ IDEA ### 10 | .idea 11 | *.iws 12 | *.iml 13 | *.ipr 14 | 15 | ### NetBeans ### 16 | nbproject/private/ 17 | build/ 18 | nbbuild/ 19 | dist/ 20 | nbdist/ 21 | .nb-gradle/ 22 | 23 | ###my own### 24 | logs 25 | upload 26 | target 27 | tale.sql -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Blog 2 | 本blog系统起源于tale的开源博客系统,但是开发框架是blade, 3 | 准备改成springboot版本,又碰巧发现My Blog已经改了并且开源了。于是直接fork,精简了原有的代码,配置,并且加了一些新功能。喜欢的可以直接fork哦。 4 | 5 | #### tips 6 | 演示站点:[https://jsbintask.cn](https://jsbintask.cn) 7 | 8 | #### 联系作者 9 | 10 | 邮箱:```jsbintask@foxmail.com``` 11 | 12 | 13 | # Preview 14 | ![My Blog](https://github.com/jsbintask22/blog/blob/master/static/images/1.png) 15 | ![My Blog](https://github.com/jsbintask22/blog/blob/master/static/images/2.png) 16 | ![登录页](https://github.com/jsbintask22/blog/blob/master/static/images/3.png) 17 | **My Blog后台:** 18 | ![My Blog](https://github.com/jsbintask22/blog/blob/master/static/images/4.png) 19 | **My Blog后台:** 20 | ![My Blog](https://github.com/jsbintask22/blog/blob/master/static/images/5.png) 21 | -------------------------------------------------------------------------------- /my-blog.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # author: 13 3 | # date: 2017-06-30 4 | 5 | 6 | env_args="-Xms128m -Xmx128m" 7 | sleeptime=0 8 | arglen=$# 9 | 10 | # get my-blog pid 11 | get_pid(){ 12 | pname="`find .. -name 'my-blog*.jar'`" 13 | pname=${pname:3} 14 | pid=`ps -ef | grep $pname | grep -v grep | awk '{print $2}'` 15 | echo "$pid" 16 | } 17 | 18 | startup(){ 19 | 20 | #构建并启动 21 | mvn clean install -Dmaven.test.skip=true 22 | pid=$(get_pid) 23 | if [ "$pid" != "" ] 24 | then 25 | echo "Blog already startup!" 26 | else 27 | jar_path=`find .. -name 'my-blog*.jar'` 28 | echo "jarfile=$jar_path" 29 | cmd="java $1 -jar $jar_path > ./my-blog.out < /dev/null &" 30 | echo "cmd: $cmd" 31 | java $1 -jar $jar_path > ./my-blog.out < /dev/null & 32 | show_log 33 | fi 34 | } 35 | 36 | shut_down(){ 37 | pid=$(get_pid) 38 | if [ "$pid" != "" ] 39 | then 40 | kill -9 $pid 41 | echo "Blog is stop!" 42 | else 43 | echo "Blog already stop!" 44 | fi 45 | } 46 | 47 | show_log(){ 48 | tail -f my-blog.out 49 | } 50 | 51 | show_help(){ 52 | echo -e "\r\n\t欢迎使用Blog" 53 | echo -e "\r\nUsage: sh my-blog.sh start|stop|reload|status|log" 54 | exit 55 | } 56 | 57 | show_status(){ 58 | pid=$(get_pid) 59 | if [ "$pid" != "" ] 60 | then 61 | echo "Blog is running with pid: $pid" 62 | else 63 | echo "Blog is stop!" 64 | fi 65 | } 66 | 67 | if [ $arglen -eq 0 ] 68 | then 69 | show_help 70 | else 71 | if [ "$2" != "" ] 72 | then 73 | env_args="$2" 74 | fi 75 | case "$1" in 76 | "start") 77 | startup "$env_args" 78 | ;; 79 | "stop") 80 | shut_down 81 | ;; 82 | "reload") 83 | echo "reload" 84 | ;; 85 | "status") 86 | show_status 87 | ;; 88 | "log") 89 | show_log 90 | ;; 91 | esac 92 | fi -------------------------------------------------------------------------------- /src/main/java/com/my/blog/website/CoreApplication.java: -------------------------------------------------------------------------------- 1 | package com.my.blog.website; 2 | 3 | import org.mybatis.spring.annotation.MapperScan; 4 | import org.springframework.boot.SpringApplication; 5 | import org.springframework.boot.autoconfigure.SpringBootApplication; 6 | import org.springframework.transaction.annotation.EnableTransactionManagement; 7 | 8 | @MapperScan("com.my.blog.website.dao") 9 | @SpringBootApplication 10 | @EnableTransactionManagement 11 | public class CoreApplication { 12 | public static void main(String[] args) { 13 | SpringApplication.run(CoreApplication.class, args); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/com/my/blog/website/constant/WebConst.java: -------------------------------------------------------------------------------- 1 | package com.my.blog.website.constant; 2 | 3 | import org.springframework.stereotype.Component; 4 | 5 | import java.util.HashMap; 6 | import java.util.HashSet; 7 | import java.util.Map; 8 | import java.util.Set; 9 | 10 | /** 11 | * Created by BlueT on 2017/3/3. 12 | */ 13 | @Component 14 | public class WebConst { 15 | public static Map initConfig = new HashMap<>(); 16 | 17 | 18 | public static String LOGIN_SESSION_KEY = "login_user"; 19 | 20 | public static final String USER_IN_COOKIE = "S_L_ID"; 21 | 22 | /** 23 | * aes加密加盐 24 | */ 25 | public static String AES_SALT = "0123456789abcdef"; 26 | 27 | /** 28 | * 最大获取文章条数 29 | */ 30 | public static final int MAX_POSTS = 9999; 31 | 32 | /** 33 | * 最大页码 34 | */ 35 | public static final int MAX_PAGE = 100; 36 | 37 | /** 38 | * 文章最多可以输入的文字数 39 | */ 40 | public static final int MAX_TEXT_COUNT = 200000; 41 | 42 | /** 43 | * 文章标题最多可以输入的文字个数 44 | */ 45 | public static final int MAX_TITLE_COUNT = 200; 46 | 47 | /** 48 | * 点击次数超过多少更新到数据库 49 | */ 50 | public static final int HIT_EXCEED = 10; 51 | 52 | /** 53 | * 上传文件最大1M 54 | */ 55 | public static Integer MAX_FILE_SIZE = 1048576; 56 | 57 | /** 58 | * 成功返回 59 | */ 60 | public static String SUCCESS_RESULT = "SUCCESS"; 61 | 62 | /** 63 | * 同一篇文章在2个小时内无论点击多少次只算一次阅读 64 | */ 65 | public static Integer HITS_LIMIT_TIME = 7200; 66 | } 67 | -------------------------------------------------------------------------------- /src/main/java/com/my/blog/website/controller/BaseController.java: -------------------------------------------------------------------------------- 1 | package com.my.blog.website.controller; 2 | 3 | import com.my.blog.website.model.Vo.UserVo; 4 | import com.my.blog.website.utils.TaleUtils; 5 | import com.my.blog.website.utils.MapCache; 6 | 7 | import javax.servlet.http.HttpServletRequest; 8 | 9 | /** 10 | * Created by 13 on 2017/2/21. 11 | */ 12 | public abstract class BaseController { 13 | 14 | public static String THEME = "themes/default"; 15 | 16 | protected MapCache cache = MapCache.single(); 17 | 18 | /** 19 | * 主页的页面主题 20 | * @param viewName 21 | * @return 22 | */ 23 | public String render(String viewName) { 24 | return THEME + "/" + viewName; 25 | } 26 | 27 | public BaseController title(HttpServletRequest request, String title) { 28 | request.setAttribute("title", title); 29 | return this; 30 | } 31 | 32 | public BaseController keywords(HttpServletRequest request, String keywords) { 33 | request.setAttribute("keywords", keywords); 34 | return this; 35 | } 36 | 37 | /** 38 | * 获取请求绑定的登录对象 39 | * @param request 40 | * @return 41 | */ 42 | public UserVo user(HttpServletRequest request) { 43 | return TaleUtils.getLoginUser(request); 44 | } 45 | 46 | public Integer getUid(HttpServletRequest request){ 47 | return this.user(request).getUid(); 48 | } 49 | 50 | public String render_404() { 51 | return "comm/error_404"; 52 | } 53 | 54 | } 55 | -------------------------------------------------------------------------------- /src/main/java/com/my/blog/website/controller/GlobalExceptionHandler.java: -------------------------------------------------------------------------------- 1 | package com.my.blog.website.controller; 2 | 3 | import com.my.blog.website.exception.TipException; 4 | import org.slf4j.Logger; 5 | import org.slf4j.LoggerFactory; 6 | import org.springframework.web.bind.annotation.ControllerAdvice; 7 | import org.springframework.web.bind.annotation.ExceptionHandler; 8 | 9 | /** 10 | * Created by BlueT on 2017/3/4. 11 | */ 12 | @ControllerAdvice 13 | public class GlobalExceptionHandler { 14 | private static final Logger LOGGER = LoggerFactory.getLogger(GlobalExceptionHandler.class); 15 | 16 | @ExceptionHandler(value = TipException.class) 17 | public String tipException(Exception e) { 18 | LOGGER.error("find exception:e={}",e.getMessage()); 19 | e.printStackTrace(); 20 | return "comm/error_500"; 21 | } 22 | 23 | 24 | @ExceptionHandler(value = Exception.class) 25 | public String exception(Exception e){ 26 | LOGGER.error("find exception:e={}",e.getMessage()); 27 | e.printStackTrace(); 28 | return "comm/error_404"; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/com/my/blog/website/controller/admin/ArticleController.java: -------------------------------------------------------------------------------- 1 | package com.my.blog.website.controller.admin; 2 | 3 | 4 | import com.github.pagehelper.PageInfo; 5 | import com.my.blog.website.constant.WebConst; 6 | import com.my.blog.website.controller.BaseController; 7 | import com.my.blog.website.dto.LogActions; 8 | import com.my.blog.website.dto.Types; 9 | import com.my.blog.website.exception.TipException; 10 | import com.my.blog.website.model.Bo.RestResponseBo; 11 | import com.my.blog.website.model.Vo.ContentVo; 12 | import com.my.blog.website.model.Vo.ContentVoExample; 13 | import com.my.blog.website.model.Vo.MetaVo; 14 | import com.my.blog.website.model.Vo.UserVo; 15 | import com.my.blog.website.service.IContentService; 16 | import com.my.blog.website.service.ILogService; 17 | import com.my.blog.website.service.IMetaService; 18 | import org.apache.commons.lang3.StringUtils; 19 | import org.slf4j.Logger; 20 | import org.slf4j.LoggerFactory; 21 | import org.springframework.stereotype.Controller; 22 | import org.springframework.transaction.annotation.Transactional; 23 | import org.springframework.web.bind.annotation.*; 24 | 25 | import javax.annotation.Resource; 26 | import javax.servlet.http.HttpServletRequest; 27 | import java.util.List; 28 | 29 | /** 30 | * Created by 13 on 2017/2/21. 31 | */ 32 | @Controller 33 | @RequestMapping("/admin/article") 34 | @Transactional(rollbackFor = TipException.class) 35 | public class ArticleController extends BaseController { 36 | 37 | private static final Logger LOGGER = LoggerFactory.getLogger(ArticleController.class); 38 | 39 | @Resource 40 | private IContentService contentsService; 41 | 42 | @Resource 43 | private IMetaService metasService; 44 | 45 | @Resource 46 | private ILogService logService; 47 | 48 | @GetMapping(value = "") 49 | public String index(@RequestParam(value = "page", defaultValue = "1") int page, 50 | @RequestParam(value = "limit", defaultValue = "15") int limit, HttpServletRequest request) { 51 | ContentVoExample contentVoExample = new ContentVoExample(); 52 | contentVoExample.setOrderByClause("created desc"); 53 | contentVoExample.createCriteria().andTypeEqualTo(Types.ARTICLE.getType()); 54 | PageInfo contentsPaginator = contentsService.getArticlesWithpage(contentVoExample, page, limit); 55 | request.setAttribute("articles", contentsPaginator); 56 | return "admin/article_list"; 57 | } 58 | 59 | @GetMapping(value = "/publish") 60 | public String newArticle(HttpServletRequest request) { 61 | List categories = metasService.getMetas(Types.CATEGORY.getType()); 62 | request.setAttribute("categories", categories); 63 | return "admin/article_edit"; 64 | } 65 | 66 | @GetMapping(value = "/{cid}") 67 | public String editArticle(@PathVariable String cid, HttpServletRequest request) { 68 | ContentVo contents = contentsService.getContents(cid); 69 | request.setAttribute("contents", contents); 70 | List categories = metasService.getMetas(Types.CATEGORY.getType()); 71 | request.setAttribute("categories", categories); 72 | request.setAttribute("active", "article"); 73 | return "admin/article_edit"; 74 | } 75 | 76 | @PostMapping(value = "/publish") 77 | @ResponseBody 78 | public RestResponseBo publishArticle(ContentVo contents, HttpServletRequest request) { 79 | UserVo users = this.user(request); 80 | contents.setAuthorId(users.getUid()); 81 | contents.setType(Types.ARTICLE.getType()); 82 | if (StringUtils.isBlank(contents.getCategories())) { 83 | contents.setCategories("默认分类"); 84 | } 85 | String result = contentsService.publish(contents); 86 | if (!WebConst.SUCCESS_RESULT.equals(result)) { 87 | return RestResponseBo.fail(result); 88 | } 89 | return RestResponseBo.ok(); 90 | } 91 | 92 | @PostMapping(value = "/modify") 93 | @ResponseBody 94 | public RestResponseBo modifyArticle(ContentVo contents, HttpServletRequest request) { 95 | UserVo users = this.user(request); 96 | contents.setAuthorId(users.getUid()); 97 | contents.setType(Types.ARTICLE.getType()); 98 | String result = contentsService.updateArticle(contents); 99 | if (!WebConst.SUCCESS_RESULT.equals(result)) { 100 | return RestResponseBo.fail(result); 101 | } 102 | return RestResponseBo.ok(); 103 | } 104 | 105 | @RequestMapping(value = "/delete") 106 | @ResponseBody 107 | public RestResponseBo delete(@RequestParam int cid, HttpServletRequest request) { 108 | String result = contentsService.deleteByCid(cid); 109 | logService.insertLog(LogActions.DEL_ARTICLE.getAction(), cid + "", request.getRemoteAddr(), this.getUid(request)); 110 | if (!WebConst.SUCCESS_RESULT.equals(result)) { 111 | return RestResponseBo.fail(result); 112 | } 113 | return RestResponseBo.ok(); 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /src/main/java/com/my/blog/website/controller/admin/AttachController.java: -------------------------------------------------------------------------------- 1 | package com.my.blog.website.controller.admin; 2 | 3 | import com.github.pagehelper.PageInfo; 4 | import com.my.blog.website.constant.WebConst; 5 | import com.my.blog.website.controller.BaseController; 6 | import com.my.blog.website.dto.LogActions; 7 | import com.my.blog.website.dto.Types; 8 | import com.my.blog.website.model.Bo.RestResponseBo; 9 | import com.my.blog.website.model.Vo.AttachVo; 10 | import com.my.blog.website.model.Vo.UserVo; 11 | import com.my.blog.website.service.IAttachService; 12 | import com.my.blog.website.service.ILogService; 13 | import com.my.blog.website.utils.Commons; 14 | import com.my.blog.website.utils.TaleUtils; 15 | import org.slf4j.Logger; 16 | import org.slf4j.LoggerFactory; 17 | import org.springframework.stereotype.Controller; 18 | import org.springframework.util.FileCopyUtils; 19 | import org.springframework.web.bind.annotation.*; 20 | import org.springframework.web.multipart.MultipartFile; 21 | 22 | import javax.annotation.Resource; 23 | import javax.servlet.http.HttpServletRequest; 24 | import java.io.File; 25 | import java.io.FileOutputStream; 26 | import java.io.IOException; 27 | import java.util.ArrayList; 28 | import java.util.List; 29 | 30 | /** 31 | * 附件管理 32 | *

33 | * Created by 13 on 2017/2/21. 34 | */ 35 | @Controller 36 | @RequestMapping("admin/attach") 37 | public class AttachController extends BaseController { 38 | 39 | private static final Logger LOGGER = LoggerFactory.getLogger(AttachController.class); 40 | 41 | public static final String CLASSPATH = TaleUtils.getUploadFilePath(); 42 | 43 | @Resource 44 | private IAttachService attachService; 45 | 46 | @Resource 47 | private ILogService logService; 48 | 49 | /** 50 | * 附件页面 51 | * 52 | * @param request 53 | * @param page 54 | * @param limit 55 | * @return 56 | */ 57 | @GetMapping(value = "") 58 | public String index(HttpServletRequest request, @RequestParam(value = "page", defaultValue = "1") int page, 59 | @RequestParam(value = "limit", defaultValue = "12") int limit) { 60 | PageInfo attachPaginator = attachService.getAttachs(page, limit); 61 | request.setAttribute("attachs", attachPaginator); 62 | request.setAttribute(Types.ATTACH_URL.getType(), Commons.site_option(Types.ATTACH_URL.getType(), Commons.site_url())); 63 | request.setAttribute("max_file_size", WebConst.MAX_FILE_SIZE / 1024); 64 | return "admin/attach"; 65 | } 66 | 67 | /** 68 | * 上传文件接口 69 | * 70 | * @param request 71 | * @return 72 | */ 73 | @PostMapping(value = "upload") 74 | @ResponseBody 75 | public RestResponseBo upload(HttpServletRequest request, @RequestParam("file") MultipartFile[] multipartFiles) throws IOException { 76 | UserVo users = this.user(request); 77 | Integer uid = users.getUid(); 78 | List errorFiles = new ArrayList<>(); 79 | try { 80 | for (MultipartFile multipartFile : multipartFiles) { 81 | String fname = multipartFile.getOriginalFilename(); 82 | if (multipartFile.getSize() <= WebConst.MAX_FILE_SIZE) { 83 | String fkey = TaleUtils.getFileKey(fname); 84 | String ftype = TaleUtils.isImage(multipartFile.getInputStream()) ? Types.IMAGE.getType() : Types.FILE.getType(); 85 | File file = new File(CLASSPATH + fkey); 86 | try { 87 | FileCopyUtils.copy(multipartFile.getInputStream(), new FileOutputStream(file)); 88 | } catch (IOException e) { 89 | e.printStackTrace(); 90 | } 91 | attachService.save(fname, fkey, ftype, uid); 92 | } else { 93 | errorFiles.add(fname); 94 | } 95 | } 96 | } catch (Exception e) { 97 | return RestResponseBo.fail(); 98 | } 99 | return RestResponseBo.ok(errorFiles); 100 | } 101 | 102 | @RequestMapping(value = "delete") 103 | @ResponseBody 104 | public RestResponseBo delete(@RequestParam Integer id, HttpServletRequest request) { 105 | try { 106 | AttachVo attach = attachService.selectById(id); 107 | if (null == attach) { 108 | return RestResponseBo.fail("不存在该附件"); 109 | } 110 | attachService.deleteById(id); 111 | new File(CLASSPATH + attach.getFkey()).delete(); 112 | logService.insertLog(LogActions.DEL_ARTICLE.getAction(), attach.getFkey(), request.getRemoteAddr(), this.getUid(request)); 113 | } catch (Exception e) { 114 | String msg = "附件删除失败"; 115 | LOGGER.error(msg, e); 116 | return RestResponseBo.fail(msg); 117 | } 118 | return RestResponseBo.ok(); 119 | } 120 | 121 | } 122 | -------------------------------------------------------------------------------- /src/main/java/com/my/blog/website/controller/admin/AuthController.java: -------------------------------------------------------------------------------- 1 | package com.my.blog.website.controller.admin; 2 | 3 | import com.my.blog.website.constant.WebConst; 4 | import com.my.blog.website.controller.BaseController; 5 | import com.my.blog.website.dto.LogActions; 6 | import com.my.blog.website.exception.TipException; 7 | import com.my.blog.website.model.Bo.RestResponseBo; 8 | import com.my.blog.website.model.Vo.UserVo; 9 | import com.my.blog.website.service.ILogService; 10 | import com.my.blog.website.service.IUserService; 11 | import com.my.blog.website.utils.TaleUtils; 12 | import org.apache.catalina.servlet4preview.http.HttpServletRequest; 13 | import org.apache.commons.lang3.StringUtils; 14 | import org.slf4j.Logger; 15 | import org.slf4j.LoggerFactory; 16 | import org.springframework.stereotype.Controller; 17 | import org.springframework.transaction.annotation.Transactional; 18 | import org.springframework.web.bind.annotation.*; 19 | 20 | import javax.annotation.Resource; 21 | import javax.servlet.http.Cookie; 22 | import javax.servlet.http.HttpServletResponse; 23 | import javax.servlet.http.HttpSession; 24 | import java.io.IOException; 25 | 26 | /** 27 | * 用户后台登录/登出 28 | * Created by BlueT on 2017/3/11. 29 | */ 30 | @Controller 31 | @RequestMapping("/admin") 32 | @Transactional(rollbackFor = TipException.class) 33 | public class AuthController extends BaseController { 34 | 35 | private static final Logger LOGGER = LoggerFactory.getLogger(AuthController.class); 36 | 37 | @Resource 38 | private IUserService usersService; 39 | 40 | @Resource 41 | private ILogService logService; 42 | 43 | @GetMapping(value = "/login") 44 | public String login() { 45 | return "admin/login"; 46 | } 47 | 48 | @PostMapping(value = "login") 49 | @ResponseBody 50 | public RestResponseBo doLogin(@RequestParam String username, 51 | @RequestParam String password, 52 | @RequestParam(required = false) String remeber_me, 53 | HttpServletRequest request, 54 | HttpServletResponse response) { 55 | 56 | Integer error_count = cache.get("login_error_count"); 57 | try { 58 | UserVo user = usersService.login(username, password); 59 | request.getSession().setAttribute(WebConst.LOGIN_SESSION_KEY, user); 60 | if (StringUtils.isNotBlank(remeber_me)) { 61 | TaleUtils.setCookie(response, user.getUid()); 62 | } 63 | logService.insertLog(LogActions.LOGIN.getAction(), null, request.getRemoteAddr(), user.getUid()); 64 | } catch (Exception e) { 65 | error_count = null == error_count ? 1 : error_count + 1; 66 | if (error_count > 3) { 67 | return RestResponseBo.fail("您输入密码已经错误超过3次,请10分钟后尝试"); 68 | } 69 | cache.set("login_error_count", error_count, 10 * 60); 70 | String msg = "登录失败"; 71 | if (e instanceof TipException) { 72 | msg = e.getMessage(); 73 | } else { 74 | LOGGER.error(msg, e); 75 | } 76 | return RestResponseBo.fail(msg); 77 | } 78 | return RestResponseBo.ok(); 79 | } 80 | 81 | /** 82 | * 注销 83 | * 84 | * @param session 85 | * @param response 86 | */ 87 | @RequestMapping("/logout") 88 | public void logout(HttpSession session, HttpServletResponse response, HttpServletRequest request) { 89 | session.removeAttribute(WebConst.LOGIN_SESSION_KEY); 90 | Cookie cookie = new Cookie(WebConst.USER_IN_COOKIE, ""); 91 | cookie.setValue(null); 92 | cookie.setMaxAge(0);// 立即销毁cookie 93 | cookie.setPath("/"); 94 | response.addCookie(cookie); 95 | try { 96 | response.sendRedirect("/admin/login"); 97 | } catch (IOException e) { 98 | e.printStackTrace(); 99 | LOGGER.error("注销失败", e); 100 | } 101 | } 102 | 103 | } 104 | -------------------------------------------------------------------------------- /src/main/java/com/my/blog/website/controller/admin/CategoryController.java: -------------------------------------------------------------------------------- 1 | package com.my.blog.website.controller.admin; 2 | 3 | import com.my.blog.website.constant.WebConst; 4 | import com.my.blog.website.controller.BaseController; 5 | import com.my.blog.website.dto.MetaDto; 6 | import com.my.blog.website.dto.Types; 7 | import com.my.blog.website.model.Bo.RestResponseBo; 8 | import com.my.blog.website.service.IMetaService; 9 | import org.slf4j.Logger; 10 | import org.slf4j.LoggerFactory; 11 | import org.springframework.stereotype.Controller; 12 | import org.springframework.web.bind.annotation.*; 13 | 14 | import javax.annotation.Resource; 15 | import javax.servlet.http.HttpServletRequest; 16 | import java.util.List; 17 | 18 | /** 19 | * Created by 13 on 2017/2/21. 20 | */ 21 | @Controller 22 | @RequestMapping("admin/category") 23 | public class CategoryController extends BaseController { 24 | 25 | private static final Logger LOGGER = LoggerFactory.getLogger(CategoryController.class); 26 | 27 | @Resource 28 | private IMetaService metasService; 29 | 30 | @GetMapping(value = "") 31 | public String index(HttpServletRequest request) { 32 | List categories = metasService.getMetaList(Types.CATEGORY.getType(), null, WebConst.MAX_POSTS); 33 | List tags = metasService.getMetaList(Types.TAG.getType(), null, WebConst.MAX_POSTS); 34 | request.setAttribute("categories", categories); 35 | request.setAttribute("tags", tags); 36 | return "admin/category"; 37 | } 38 | 39 | @PostMapping(value = "save") 40 | @ResponseBody 41 | public RestResponseBo saveCategory(@RequestParam String cname, @RequestParam Integer mid) { 42 | try { 43 | metasService.saveMeta(Types.CATEGORY.getType(), cname, mid); 44 | } catch (Exception e) { 45 | String msg = "分类保存失败"; 46 | LOGGER.error(msg, e); 47 | return RestResponseBo.fail(msg); 48 | } 49 | return RestResponseBo.ok(); 50 | } 51 | 52 | @RequestMapping(value = "delete") 53 | @ResponseBody 54 | public RestResponseBo delete(@RequestParam int mid) { 55 | try { 56 | metasService.delete(mid); 57 | } catch (Exception e) { 58 | String msg = "删除失败"; 59 | LOGGER.error(msg, e); 60 | return RestResponseBo.fail(msg); 61 | } 62 | return RestResponseBo.ok(); 63 | } 64 | 65 | } 66 | -------------------------------------------------------------------------------- /src/main/java/com/my/blog/website/controller/admin/CommentController.java: -------------------------------------------------------------------------------- 1 | package com.my.blog.website.controller.admin; 2 | 3 | import com.github.pagehelper.PageInfo; 4 | import com.my.blog.website.controller.BaseController; 5 | import com.my.blog.website.model.Bo.RestResponseBo; 6 | import com.my.blog.website.model.Vo.CommentVo; 7 | import com.my.blog.website.model.Vo.CommentVoExample; 8 | import com.my.blog.website.model.Vo.UserVo; 9 | import com.my.blog.website.service.ICommentService; 10 | import org.slf4j.Logger; 11 | import org.slf4j.LoggerFactory; 12 | import org.springframework.stereotype.Controller; 13 | import org.springframework.web.bind.annotation.*; 14 | 15 | import javax.annotation.Resource; 16 | import javax.servlet.http.HttpServletRequest; 17 | 18 | /** 19 | * Created by 13 on 2017/2/26. 20 | */ 21 | @Controller 22 | @RequestMapping("admin/comments") 23 | public class CommentController extends BaseController { 24 | 25 | private static final Logger LOGGER = LoggerFactory.getLogger(CommentController.class); 26 | 27 | @Resource 28 | private ICommentService commentsService; 29 | 30 | @GetMapping(value = "") 31 | public String index(@RequestParam(value = "page", defaultValue = "1") int page, 32 | @RequestParam(value = "limit", defaultValue = "15") int limit, HttpServletRequest request) { 33 | UserVo users = this.user(request); 34 | CommentVoExample commentVoExample = new CommentVoExample(); 35 | commentVoExample.setOrderByClause("coid desc"); 36 | commentVoExample.createCriteria().andAuthorIdNotEqualTo(users.getUid()); 37 | PageInfo commentsPaginator = commentsService.getCommentsWithPage(commentVoExample, page, limit); 38 | request.setAttribute("comments", commentsPaginator); 39 | return "admin/comment_list"; 40 | } 41 | 42 | /** 43 | * 删除一条评论 44 | * 45 | * @param coid 46 | * @return 47 | */ 48 | @PostMapping(value = "delete") 49 | @ResponseBody 50 | public RestResponseBo delete(@RequestParam Integer coid) { 51 | try { 52 | CommentVo comments = commentsService.getCommentById(coid); 53 | if (null == comments) { 54 | return RestResponseBo.fail("不存在该评论"); 55 | } 56 | commentsService.delete(coid, comments.getCid()); 57 | } catch (Exception e) { 58 | String msg = "评论删除失败"; 59 | LOGGER.error(msg, e); 60 | return RestResponseBo.fail(msg); 61 | } 62 | return RestResponseBo.ok(); 63 | } 64 | 65 | @PostMapping(value = "status") 66 | @ResponseBody 67 | public RestResponseBo delete(@RequestParam Integer coid, @RequestParam String status) { 68 | try { 69 | CommentVo comments = commentsService.getCommentById(coid); 70 | if (comments != null) { 71 | comments.setCoid(coid); 72 | comments.setStatus(status); 73 | commentsService.update(comments); 74 | } else { 75 | return RestResponseBo.fail("操作失败"); 76 | } 77 | } catch (Exception e) { 78 | String msg = "操作失败"; 79 | return RestResponseBo.fail(msg); 80 | } 81 | return RestResponseBo.ok(); 82 | } 83 | 84 | } 85 | -------------------------------------------------------------------------------- /src/main/java/com/my/blog/website/controller/admin/LinksController.java: -------------------------------------------------------------------------------- 1 | package com.my.blog.website.controller.admin; 2 | 3 | import com.my.blog.website.controller.BaseController; 4 | import com.my.blog.website.model.Bo.RestResponseBo; 5 | import com.my.blog.website.service.IMetaService; 6 | import com.my.blog.website.dto.Types; 7 | import com.my.blog.website.model.Vo.MetaVo; 8 | import org.slf4j.Logger; 9 | import org.slf4j.LoggerFactory; 10 | import org.springframework.stereotype.Controller; 11 | import org.springframework.web.bind.annotation.*; 12 | 13 | import javax.annotation.Resource; 14 | import javax.servlet.http.HttpServletRequest; 15 | import java.util.List; 16 | 17 | /** 18 | * Created by 13 on 2017/2/21. 19 | */ 20 | @Controller 21 | @RequestMapping("admin/links") 22 | public class LinksController extends BaseController { 23 | 24 | private static final Logger LOGGER = LoggerFactory.getLogger(LinksController.class); 25 | 26 | @Resource 27 | private IMetaService metasService; 28 | 29 | @GetMapping(value = "") 30 | public String index(HttpServletRequest request) { 31 | List metas = metasService.getMetas(Types.LINK.getType()); 32 | request.setAttribute("links", metas); 33 | return "admin/links"; 34 | } 35 | 36 | @PostMapping(value = "save") 37 | @ResponseBody 38 | public RestResponseBo saveLink(@RequestParam String title, @RequestParam String url, 39 | @RequestParam String logo, @RequestParam Integer mid, 40 | @RequestParam(value = "sort", defaultValue = "0") int sort) { 41 | try { 42 | MetaVo metas = new MetaVo(); 43 | metas.setName(title); 44 | metas.setSlug(url); 45 | metas.setDescription(logo); 46 | metas.setSort(sort); 47 | metas.setType(Types.LINK.getType()); 48 | if (null != mid) { 49 | metas.setMid(mid); 50 | metasService.update(metas); 51 | } else { 52 | metasService.saveMeta(metas); 53 | } 54 | } catch (Exception e) { 55 | String msg = "友链保存失败"; 56 | LOGGER.error(msg, e); 57 | return RestResponseBo.fail(msg); 58 | } 59 | return RestResponseBo.ok(); 60 | } 61 | 62 | @RequestMapping(value = "delete") 63 | @ResponseBody 64 | public RestResponseBo delete(@RequestParam int mid) { 65 | try { 66 | metasService.delete(mid); 67 | } catch (Exception e) { 68 | String msg = "友链删除失败"; 69 | LOGGER.error(msg, e); 70 | return RestResponseBo.fail(msg); 71 | } 72 | return RestResponseBo.ok(); 73 | } 74 | 75 | } 76 | -------------------------------------------------------------------------------- /src/main/java/com/my/blog/website/controller/admin/SettingController.java: -------------------------------------------------------------------------------- 1 | package com.my.blog.website.controller.admin; 2 | 3 | import com.my.blog.website.service.ILogService; 4 | import com.my.blog.website.service.ISiteService; 5 | import com.my.blog.website.constant.WebConst; 6 | import com.my.blog.website.controller.BaseController; 7 | import com.my.blog.website.dto.LogActions; 8 | import com.my.blog.website.exception.TipException; 9 | import com.my.blog.website.model.Bo.BackResponseBo; 10 | import com.my.blog.website.model.Bo.RestResponseBo; 11 | import com.my.blog.website.model.Vo.OptionVo; 12 | import com.my.blog.website.service.IOptionService; 13 | import com.my.blog.website.utils.GsonUtils; 14 | import org.apache.commons.lang3.StringUtils; 15 | import org.slf4j.Logger; 16 | import org.slf4j.LoggerFactory; 17 | import org.springframework.stereotype.Controller; 18 | import org.springframework.web.bind.annotation.*; 19 | 20 | import javax.annotation.Resource; 21 | import javax.servlet.http.HttpServletRequest; 22 | import java.util.HashMap; 23 | import java.util.List; 24 | import java.util.Map; 25 | 26 | /** 27 | * Created by wangq on 2017/3/20. 28 | */ 29 | @Controller 30 | @RequestMapping("/admin/setting") 31 | public class SettingController extends BaseController { 32 | private static final Logger LOGGER = LoggerFactory.getLogger(SettingController.class); 33 | 34 | @Resource 35 | private IOptionService optionService; 36 | 37 | @Resource 38 | private ILogService logService; 39 | 40 | @Resource 41 | private ISiteService siteService; 42 | 43 | /** 44 | * 系统设置 45 | */ 46 | @GetMapping(value = "") 47 | public String setting(HttpServletRequest request) { 48 | List voList = optionService.getOptions(); 49 | Map options = new HashMap<>(); 50 | voList.forEach((option) -> { 51 | options.put(option.getName(), option.getValue()); 52 | }); 53 | if (options.get("site_record") == null) { 54 | options.put("site_record", ""); 55 | } 56 | request.setAttribute("options", options); 57 | return "admin/setting"; 58 | } 59 | 60 | /** 61 | * 保存系统设置 62 | */ 63 | @PostMapping(value = "") 64 | @ResponseBody 65 | public RestResponseBo saveSetting(@RequestParam(required = false) String site_theme, HttpServletRequest request) { 66 | try { 67 | Map parameterMap = request.getParameterMap(); 68 | Map querys = new HashMap<>(); 69 | parameterMap.forEach((key, value) -> { 70 | querys.put(key, join(value)); 71 | }); 72 | optionService.saveOptions(querys); 73 | WebConst.initConfig = querys; 74 | if (StringUtils.isNotBlank(site_theme)) { 75 | BaseController.THEME = "themes/" + site_theme; 76 | } 77 | logService.insertLog(LogActions.SYS_SETTING.getAction(), GsonUtils.toJsonString(querys), request.getRemoteAddr(), this.getUid(request)); 78 | return RestResponseBo.ok(); 79 | } catch (Exception e) { 80 | String msg = "保存设置失败"; 81 | return RestResponseBo.fail(msg); 82 | } 83 | } 84 | 85 | 86 | /** 87 | * 系统备份 88 | * 89 | * @return 90 | */ 91 | @PostMapping(value = "backup") 92 | @ResponseBody 93 | public RestResponseBo backup(@RequestParam String bk_type, @RequestParam String bk_path, 94 | HttpServletRequest request) { 95 | if (StringUtils.isBlank(bk_type)) { 96 | return RestResponseBo.fail("请确认信息输入完整"); 97 | } 98 | try { 99 | BackResponseBo backResponse = siteService.backup(bk_type, bk_path, "yyyyMMddHHmm"); 100 | logService.insertLog(LogActions.SYS_BACKUP.getAction(), null, request.getRemoteAddr(), this.getUid(request)); 101 | return RestResponseBo.ok(backResponse); 102 | } catch (Exception e) { 103 | String msg = "备份失败"; 104 | if (e instanceof TipException) { 105 | msg = e.getMessage(); 106 | } else { 107 | LOGGER.error(msg, e); 108 | } 109 | return RestResponseBo.fail(msg); 110 | } 111 | } 112 | 113 | 114 | /** 115 | * 数组转字符串 116 | * 117 | * @param arr 118 | * @return 119 | */ 120 | private String join(String[] arr) { 121 | StringBuilder ret = new StringBuilder(); 122 | String[] var3 = arr; 123 | int var4 = arr.length; 124 | 125 | for (int var5 = 0; var5 < var4; ++var5) { 126 | String item = var3[var5]; 127 | ret.append(',').append(item); 128 | } 129 | 130 | return ret.length() > 0 ? ret.substring(1) : ret.toString(); 131 | } 132 | 133 | } 134 | -------------------------------------------------------------------------------- /src/main/java/com/my/blog/website/dao/AttachVoMapper.java: -------------------------------------------------------------------------------- 1 | package com.my.blog.website.dao; 2 | 3 | import com.my.blog.website.model.Vo.AttachVo; 4 | import com.my.blog.website.model.Vo.AttachVoExample; 5 | import java.util.List; 6 | import org.apache.ibatis.annotations.Param; 7 | import org.springframework.stereotype.Component; 8 | 9 | @Component 10 | public interface AttachVoMapper { 11 | long countByExample(AttachVoExample example); 12 | 13 | int deleteByExample(AttachVoExample example); 14 | 15 | int deleteByPrimaryKey(Integer id); 16 | 17 | int insert(AttachVo record); 18 | 19 | int insertSelective(AttachVo record); 20 | 21 | List selectByExample(AttachVoExample example); 22 | 23 | AttachVo selectByPrimaryKey(Integer id); 24 | 25 | int updateByExampleSelective(@Param("record") AttachVo record, @Param("example") AttachVoExample example); 26 | 27 | int updateByExample(@Param("record") AttachVo record, @Param("example") AttachVoExample example); 28 | 29 | int updateByPrimaryKeySelective(AttachVo record); 30 | 31 | int updateByPrimaryKey(AttachVo record); 32 | } -------------------------------------------------------------------------------- /src/main/java/com/my/blog/website/dao/CommentVoMapper.java: -------------------------------------------------------------------------------- 1 | package com.my.blog.website.dao; 2 | 3 | import com.my.blog.website.model.Vo.CommentVo; 4 | import com.my.blog.website.model.Vo.CommentVoExample; 5 | 6 | import java.util.List; 7 | import org.apache.ibatis.annotations.Param; 8 | import org.springframework.stereotype.Component; 9 | 10 | @Component 11 | public interface CommentVoMapper { 12 | long countByExample(CommentVoExample example); 13 | 14 | int deleteByExample(CommentVoExample example); 15 | 16 | int deleteByPrimaryKey(Integer coid); 17 | 18 | int insert(CommentVo record); 19 | 20 | int insertSelective(CommentVo record); 21 | 22 | List selectByExampleWithBLOBs(CommentVoExample example); 23 | 24 | List selectByExample(CommentVoExample example); 25 | 26 | CommentVo selectByPrimaryKey(Integer coid); 27 | 28 | int updateByExampleSelective(@Param("record") CommentVo record, @Param("example") CommentVoExample example); 29 | 30 | int updateByExampleWithBLOBs(@Param("record") CommentVo record, @Param("example") CommentVoExample example); 31 | 32 | int updateByExample(@Param("record") CommentVo record, @Param("example") CommentVoExample example); 33 | 34 | int updateByPrimaryKeySelective(CommentVo record); 35 | 36 | int updateByPrimaryKeyWithBLOBs(CommentVo record); 37 | 38 | int updateByPrimaryKey(CommentVo record); 39 | } -------------------------------------------------------------------------------- /src/main/java/com/my/blog/website/dao/ContentVoMapper.java: -------------------------------------------------------------------------------- 1 | package com.my.blog.website.dao; 2 | 3 | import com.my.blog.website.model.Bo.ArchiveBo; 4 | import com.my.blog.website.model.Vo.ContentVo; 5 | import com.my.blog.website.model.Vo.ContentVoExample; 6 | 7 | import java.util.List; 8 | import org.apache.ibatis.annotations.Param; 9 | import org.springframework.stereotype.Component; 10 | 11 | @Component 12 | public interface ContentVoMapper { 13 | long countByExample(ContentVoExample example); 14 | 15 | int deleteByExample(ContentVoExample example); 16 | 17 | int deleteByPrimaryKey(Integer cid); 18 | 19 | int insert(ContentVo record); 20 | 21 | int insertSelective(ContentVo record); 22 | 23 | List selectByExampleWithBLOBs(ContentVoExample example); 24 | 25 | List selectByExample(ContentVoExample example); 26 | 27 | ContentVo selectByPrimaryKey(Integer cid); 28 | 29 | int updateByExampleSelective(@Param("record") ContentVo record, @Param("example") ContentVoExample example); 30 | 31 | int updateByExampleWithBLOBs(@Param("record") ContentVo record, @Param("example") ContentVoExample example); 32 | 33 | int updateByExample(@Param("record") ContentVo record, @Param("example") ContentVoExample example); 34 | 35 | int updateByPrimaryKeySelective(ContentVo record); 36 | 37 | int updateByPrimaryKeyWithBLOBs(ContentVo record); 38 | 39 | int updateByPrimaryKey(ContentVo record); 40 | 41 | List findReturnArchiveBo(); 42 | 43 | List findByCatalog(Integer mid); 44 | } -------------------------------------------------------------------------------- /src/main/java/com/my/blog/website/dao/LogVoMapper.java: -------------------------------------------------------------------------------- 1 | package com.my.blog.website.dao; 2 | 3 | import com.my.blog.website.model.Vo.LogVo; 4 | import com.my.blog.website.model.Vo.LogVoExample; 5 | import java.util.List; 6 | import org.apache.ibatis.annotations.Param; 7 | import org.springframework.stereotype.Component; 8 | 9 | @Component 10 | public interface LogVoMapper { 11 | long countByExample(LogVoExample example); 12 | 13 | int deleteByExample(LogVoExample example); 14 | 15 | int deleteByPrimaryKey(Integer id); 16 | 17 | int insert(LogVo record); 18 | 19 | int insertSelective(LogVo record); 20 | 21 | List selectByExample(LogVoExample example); 22 | 23 | LogVo selectByPrimaryKey(Integer id); 24 | 25 | int updateByExampleSelective(@Param("record") LogVo record, @Param("example") LogVoExample example); 26 | 27 | int updateByExample(@Param("record") LogVo record, @Param("example") LogVoExample example); 28 | 29 | int updateByPrimaryKeySelective(LogVo record); 30 | 31 | int updateByPrimaryKey(LogVo record); 32 | } -------------------------------------------------------------------------------- /src/main/java/com/my/blog/website/dao/MetaVoMapper.java: -------------------------------------------------------------------------------- 1 | package com.my.blog.website.dao; 2 | 3 | import com.my.blog.website.dto.MetaDto; 4 | import com.my.blog.website.model.Vo.MetaVo; 5 | import com.my.blog.website.model.Vo.MetaVoExample; 6 | 7 | import java.util.List; 8 | import java.util.Map; 9 | 10 | import org.apache.ibatis.annotations.Param; 11 | import org.springframework.stereotype.Component; 12 | 13 | @Component 14 | public interface MetaVoMapper { 15 | long countByExample(MetaVoExample example); 16 | 17 | int deleteByExample(MetaVoExample example); 18 | 19 | int deleteByPrimaryKey(Integer mid); 20 | 21 | int insert(MetaVo record); 22 | 23 | int insertSelective(MetaVo record); 24 | 25 | List selectByExample(MetaVoExample example); 26 | 27 | MetaVo selectByPrimaryKey(Integer mid); 28 | 29 | int updateByExampleSelective(@Param("record") MetaVo record, @Param("example") MetaVoExample example); 30 | 31 | int updateByExample(@Param("record") MetaVo record, @Param("example") MetaVoExample example); 32 | 33 | int updateByPrimaryKeySelective(MetaVo record); 34 | 35 | int updateByPrimaryKey(MetaVo record); 36 | 37 | List selectFromSql(Map paraMap); 38 | 39 | MetaDto selectDtoByNameAndType(@Param("name") String name,@Param("type") String type); 40 | 41 | Integer countWithSql(Integer mid); 42 | } -------------------------------------------------------------------------------- /src/main/java/com/my/blog/website/dao/OptionVoMapper.java: -------------------------------------------------------------------------------- 1 | package com.my.blog.website.dao; 2 | 3 | import com.my.blog.website.model.Vo.OptionVo; 4 | import com.my.blog.website.model.Vo.OptionVoExample; 5 | 6 | import java.util.List; 7 | 8 | import org.apache.ibatis.annotations.Param; 9 | import org.springframework.stereotype.Component; 10 | 11 | @Component 12 | public interface OptionVoMapper { 13 | long countByExample(OptionVoExample example); 14 | 15 | int deleteByExample(OptionVoExample example); 16 | 17 | int deleteByPrimaryKey(String name); 18 | 19 | int insert(OptionVo record); 20 | 21 | int insertSelective(OptionVo record); 22 | 23 | List selectByExample(OptionVoExample example); 24 | 25 | OptionVo selectByPrimaryKey(String name); 26 | 27 | int updateByExampleSelective(@Param("record") OptionVo record, @Param("example") OptionVoExample example); 28 | 29 | int updateByExample(@Param("record") OptionVo record, @Param("example") OptionVoExample example); 30 | 31 | int updateByPrimaryKeySelective(OptionVo record); 32 | 33 | int updateByPrimaryKey(OptionVo record); 34 | 35 | /** 36 | * 批量保存 37 | * @param optionVos list 38 | * @return 保存的个数 39 | */ 40 | int insertOptions(List optionVos); 41 | } -------------------------------------------------------------------------------- /src/main/java/com/my/blog/website/dao/RelationshipVoMapper.java: -------------------------------------------------------------------------------- 1 | package com.my.blog.website.dao; 2 | 3 | import com.my.blog.website.model.Vo.RelationshipVoExample; 4 | import com.my.blog.website.model.Vo.RelationshipVoKey; 5 | 6 | import java.util.List; 7 | import org.apache.ibatis.annotations.Param; 8 | import org.springframework.stereotype.Component; 9 | 10 | @Component 11 | public interface RelationshipVoMapper { 12 | long countByExample(RelationshipVoExample example); 13 | 14 | int deleteByExample(RelationshipVoExample example); 15 | 16 | int deleteByPrimaryKey(RelationshipVoKey key); 17 | 18 | int insert(RelationshipVoKey record); 19 | 20 | int insertSelective(RelationshipVoKey record); 21 | 22 | List selectByExample(RelationshipVoExample example); 23 | 24 | int updateByExampleSelective(@Param("record") RelationshipVoKey record, @Param("example") RelationshipVoExample example); 25 | 26 | int updateByExample(@Param("record") RelationshipVoKey record, @Param("example") RelationshipVoExample example); 27 | } -------------------------------------------------------------------------------- /src/main/java/com/my/blog/website/dao/UserVoMapper.java: -------------------------------------------------------------------------------- 1 | package com.my.blog.website.dao; 2 | 3 | import com.my.blog.website.model.Vo.UserVo; 4 | import com.my.blog.website.model.Vo.UserVoExample; 5 | import java.util.List; 6 | import org.apache.ibatis.annotations.Param; 7 | import org.springframework.stereotype.Component; 8 | 9 | @Component 10 | public interface UserVoMapper { 11 | long countByExample(UserVoExample example); 12 | 13 | int deleteByExample(UserVoExample example); 14 | 15 | int deleteByPrimaryKey(Integer uid); 16 | 17 | int insert(UserVo record); 18 | 19 | int insertSelective(UserVo record); 20 | 21 | List selectByExample(UserVoExample example); 22 | 23 | UserVo selectByPrimaryKey(Integer uid); 24 | 25 | int updateByExampleSelective(@Param("record") UserVo record, @Param("example") UserVoExample example); 26 | 27 | int updateByExample(@Param("record") UserVo record, @Param("example") UserVoExample example); 28 | 29 | int updateByPrimaryKeySelective(UserVo record); 30 | 31 | int updateByPrimaryKey(UserVo record); 32 | } -------------------------------------------------------------------------------- /src/main/java/com/my/blog/website/dto/DataSource.java: -------------------------------------------------------------------------------- 1 | package com.my.blog.website.dto; 2 | 3 | /** 4 | * 建立数据库连接的参数对象 5 | * Created by BlueT on 2017/3/4. 6 | */ 7 | public class DataSource { 8 | 9 | /** 10 | * 数据库url 11 | */ 12 | private String url; 13 | 14 | /** 15 | * 数据库用户名 16 | */ 17 | private String username; 18 | 19 | /** 20 | * 数据库密码 21 | */ 22 | private String password; 23 | 24 | /** 25 | * 数据库驱动名称 26 | */ 27 | private String drivercClassName; 28 | 29 | /** 30 | * 数据库名字 31 | */ 32 | private String dbName; 33 | 34 | public String getDbName() { 35 | return dbName; 36 | } 37 | 38 | public void setDbName(String dbName) { 39 | this.dbName = dbName; 40 | } 41 | 42 | public String getUrl() { 43 | return url; 44 | } 45 | 46 | public String getUsername() { 47 | return username; 48 | } 49 | 50 | public String getPassword() { 51 | return password; 52 | } 53 | 54 | public String getDrivercClassName() { 55 | return drivercClassName; 56 | } 57 | 58 | public void setUrl(String url) { 59 | this.url = url; 60 | } 61 | 62 | public void setUsername(String username) { 63 | this.username = username; 64 | } 65 | 66 | public void setPassword(String password) { 67 | this.password = password; 68 | } 69 | 70 | public void setDrivercClassName(String drivercClassName) { 71 | this.drivercClassName = drivercClassName; 72 | } 73 | 74 | @Override 75 | public String toString() { 76 | return "DataSource{" + 77 | "url='" + url + '\'' + 78 | ", username='" + username + '\'' + 79 | ", password='" + password + '\'' + 80 | ", drivercClassName='" + drivercClassName + '\'' + 81 | ", dbName='" + dbName + '\'' + 82 | '}'; 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /src/main/java/com/my/blog/website/dto/ErrorCode.java: -------------------------------------------------------------------------------- 1 | package com.my.blog.website.dto; 2 | 3 | /** 4 | * 错误提示 5 | * Created by 13 on 2017/2/26. 6 | */ 7 | public interface ErrorCode { 8 | 9 | /** 10 | * 非法请求 11 | */ 12 | String BAD_REQUEST = "BAD REQUEST"; 13 | 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/com/my/blog/website/dto/LogActions.java: -------------------------------------------------------------------------------- 1 | package com.my.blog.website.dto; 2 | 3 | /** 4 | * 日志表的action字段 5 | * Created by BlueT on 2017/3/4. 6 | */ 7 | public enum LogActions { 8 | 9 | LOGIN("登录后台"), UP_PWD("修改密码"), UP_INFO("修改个人信息"), 10 | DEL_ARTICLE("删除文章"), DEL_PAGE("删除页面"), SYS_BACKUP("系统备份"), 11 | SYS_SETTING("保存系统设置"), INIT_SITE("初始化站点"); 12 | 13 | private String action; 14 | 15 | public String getAction() { 16 | return action; 17 | } 18 | 19 | public void setAction(String action) { 20 | this.action = action; 21 | } 22 | 23 | LogActions(String action) { 24 | this.action = action; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/com/my/blog/website/dto/MetaDto.java: -------------------------------------------------------------------------------- 1 | package com.my.blog.website.dto; 2 | 3 | import com.my.blog.website.model.Vo.MetaVo; 4 | 5 | public class MetaDto extends MetaVo { 6 | 7 | private int count; 8 | 9 | public int getCount() { 10 | return count; 11 | } 12 | 13 | public void setCount(int count) { 14 | this.count = count; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/com/my/blog/website/dto/Types.java: -------------------------------------------------------------------------------- 1 | package com.my.blog.website.dto; 2 | 3 | public enum Types { 4 | TAG("tag"), 5 | CATEGORY("category"), 6 | ARTICLE("post"), 7 | PUBLISH("publish"), 8 | PAGE("page"), 9 | DRAFT("draft"), 10 | LINK("link"), 11 | IMAGE("image"), 12 | FILE("file"), 13 | CSRF_TOKEN("csrf_token"), 14 | COMMENTS_FREQUENCY("comments:frequency"), 15 | HITS_FREQUENCY("hits:frequency"), 16 | 17 | /** 18 | * 附件存放的URL,默认为网站地址,如集成第三方则为第三方CDN域名 19 | */ 20 | ATTACH_URL("attach_url"), 21 | 22 | /** 23 | * 网站要过滤,禁止访问的ip列表 24 | */ 25 | BLOCK_IPS("site_block_ips"); 26 | 27 | 28 | private String type; 29 | 30 | public java.lang.String getType() { 31 | return type; 32 | } 33 | 34 | public void setType(java.lang.String type) { 35 | this.type = type; 36 | } 37 | 38 | Types(java.lang.String type) { 39 | this.type = type; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/com/my/blog/website/exception/TipException.java: -------------------------------------------------------------------------------- 1 | package com.my.blog.website.exception; 2 | 3 | public class TipException extends RuntimeException { 4 | 5 | public TipException() { 6 | } 7 | 8 | public TipException(String message) { 9 | super(message); 10 | } 11 | 12 | public TipException(String message, Throwable cause) { 13 | super(message, cause); 14 | } 15 | 16 | public TipException(Throwable cause) { 17 | super(cause); 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/com/my/blog/website/interceptor/BaseInterceptor.java: -------------------------------------------------------------------------------- 1 | package com.my.blog.website.interceptor; 2 | 3 | import com.my.blog.website.model.Vo.OptionVo; 4 | import com.my.blog.website.model.Vo.UserVo; 5 | import com.my.blog.website.service.IOptionService; 6 | import com.my.blog.website.service.IUserService; 7 | import com.my.blog.website.utils.*; 8 | import com.my.blog.website.constant.WebConst; 9 | import com.my.blog.website.dto.Types; 10 | import org.slf4j.Logger; 11 | import org.slf4j.LoggerFactory; 12 | import org.springframework.stereotype.Component; 13 | import org.springframework.web.servlet.HandlerInterceptor; 14 | import org.springframework.web.servlet.ModelAndView; 15 | 16 | import javax.annotation.Resource; 17 | import javax.servlet.http.HttpServletRequest; 18 | import javax.servlet.http.HttpServletResponse; 19 | 20 | /** 21 | * 自定义拦截器 22 | * Created by BlueT on 2017/3/9. 23 | */ 24 | @Component 25 | public class BaseInterceptor implements HandlerInterceptor { 26 | private static final Logger LOGGE = LoggerFactory.getLogger(BaseInterceptor.class); 27 | private static final String USER_AGENT = "user-agent"; 28 | 29 | @Resource 30 | private IUserService userService; 31 | 32 | @Resource 33 | private IOptionService optionService; 34 | 35 | private MapCache cache = MapCache.single(); 36 | 37 | @Resource 38 | private Commons commons; 39 | 40 | @Resource 41 | private AdminCommons adminCommons; 42 | 43 | @Override 44 | public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object o) throws Exception { 45 | String contextPath = request.getContextPath(); 46 | // System.out.println(contextPath); 47 | String uri = request.getRequestURI(); 48 | 49 | LOGGE.info("UserAgent: {}", request.getHeader(USER_AGENT)); 50 | LOGGE.info("用户访问地址: {}, 来路地址: {}", uri, IPKit.getIpAddrByRequest(request)); 51 | 52 | 53 | //请求拦截处理 54 | UserVo user = TaleUtils.getLoginUser(request); 55 | if (null == user) { 56 | Integer uid = TaleUtils.getCookieUid(request); 57 | if (null != uid) { 58 | //这里还是有安全隐患,cookie是可以伪造的 59 | user = userService.queryUserById(uid); 60 | request.getSession().setAttribute(WebConst.LOGIN_SESSION_KEY, user); 61 | } 62 | } 63 | if (uri.startsWith(contextPath + "/admin") && !uri.startsWith(contextPath + "/admin/login") && null == user) { 64 | response.sendRedirect(request.getContextPath() + "/admin/login"); 65 | return false; 66 | } 67 | //设置get请求的token 68 | if (request.getMethod().equals("GET")) { 69 | String csrf_token = UUID.UU64(); 70 | // 默认存储30分钟 71 | cache.hset(Types.CSRF_TOKEN.getType(), csrf_token, uri, 30 * 60); 72 | request.setAttribute("_csrf_token", csrf_token); 73 | } 74 | return true; 75 | } 76 | 77 | @Override 78 | public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception { 79 | OptionVo ov = optionService.getOptionByName("site_record"); 80 | //一些工具类和公共方法 81 | httpServletRequest.setAttribute("commons", commons); 82 | httpServletRequest.setAttribute("option", ov); 83 | httpServletRequest.setAttribute("adminCommons", adminCommons); 84 | } 85 | 86 | @Override 87 | public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception { 88 | 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /src/main/java/com/my/blog/website/interceptor/WebMvcConfig.java: -------------------------------------------------------------------------------- 1 | package com.my.blog.website.interceptor; 2 | 3 | 4 | import com.my.blog.website.utils.TaleUtils; 5 | import org.springframework.stereotype.Component; 6 | import org.springframework.web.servlet.config.annotation.InterceptorRegistry; 7 | import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; 8 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; 9 | 10 | import javax.annotation.Resource; 11 | 12 | /** 13 | * 向mvc中添加自定义组件 14 | * Created by BlueT on 2017/3/9. 15 | */ 16 | @Component 17 | public class WebMvcConfig extends WebMvcConfigurerAdapter { 18 | @Resource 19 | private BaseInterceptor baseInterceptor; 20 | @Override 21 | public void addInterceptors(InterceptorRegistry registry) { 22 | registry.addInterceptor(baseInterceptor); 23 | } 24 | 25 | /** 26 | * 添加静态资源文件,外部可以直接访问地址 27 | * @param registry 28 | */ 29 | @Override 30 | public void addResourceHandlers(ResourceHandlerRegistry registry) { 31 | registry.addResourceHandler("/upload/**").addResourceLocations("file:"+ TaleUtils.getUploadFilePath()+"upload/"); 32 | super.addResourceHandlers(registry); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/com/my/blog/website/model/Bo/ArchiveBo.java: -------------------------------------------------------------------------------- 1 | package com.my.blog.website.model.Bo; 2 | 3 | import com.my.blog.website.model.Vo.ContentVo; 4 | 5 | import java.io.Serializable; 6 | import java.util.List; 7 | 8 | /** 9 | * Created by 13 on 2017/2/23. 10 | */ 11 | public class ArchiveBo implements Serializable { 12 | 13 | private String date; 14 | private String count; 15 | private List articles; 16 | 17 | public String getDate() { 18 | return date; 19 | } 20 | 21 | public void setDate(String date) { 22 | this.date = date; 23 | } 24 | 25 | public String getCount() { 26 | return count; 27 | } 28 | 29 | public void setCount(String count) { 30 | this.count = count; 31 | } 32 | 33 | public List getArticles() { 34 | return articles; 35 | } 36 | 37 | public void setArticles(List articles) { 38 | this.articles = articles; 39 | } 40 | 41 | @Override 42 | public String toString() { 43 | return "Archive [" + 44 | "date='" + date + '\'' + 45 | ", count='" + count + '\'' + 46 | ", articles=" + articles + 47 | ']'; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/com/my/blog/website/model/Bo/BackResponseBo.java: -------------------------------------------------------------------------------- 1 | package com.my.blog.website.model.Bo; 2 | 3 | import java.io.Serializable; 4 | 5 | /** 6 | * Created by 13 on 2017/2/25. 7 | */ 8 | public class BackResponseBo implements Serializable { 9 | 10 | private String attachPath; 11 | private String themePath; 12 | private String sqlPath; 13 | 14 | public String getAttachPath() { 15 | return attachPath; 16 | } 17 | 18 | public void setAttachPath(String attachPath) { 19 | this.attachPath = attachPath; 20 | } 21 | 22 | public String getThemePath() { 23 | return themePath; 24 | } 25 | 26 | public void setThemePath(String themePath) { 27 | this.themePath = themePath; 28 | } 29 | 30 | public String getSqlPath() { 31 | return sqlPath; 32 | } 33 | 34 | public void setSqlPath(String sqlPath) { 35 | this.sqlPath = sqlPath; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/com/my/blog/website/model/Bo/CommentBo.java: -------------------------------------------------------------------------------- 1 | package com.my.blog.website.model.Bo; 2 | 3 | import com.my.blog.website.model.Vo.CommentVo; 4 | 5 | import java.util.List; 6 | 7 | /** 8 | * 返回页面的评论,包含父子评论内容 9 | * Created by 13 on 2017/2/24. 10 | */ 11 | public class CommentBo extends CommentVo { 12 | 13 | private int levels; 14 | private List children; 15 | 16 | public CommentBo(CommentVo comments) { 17 | setAuthor(comments.getAuthor()); 18 | setMail(comments.getMail()); 19 | setCoid(comments.getCoid()); 20 | setAuthorId(comments.getAuthorId()); 21 | setUrl(comments.getUrl()); 22 | setCreated(comments.getCreated()); 23 | setAgent(comments.getAgent()); 24 | setIp(comments.getIp()); 25 | setContent(comments.getContent()); 26 | setOwnerId(comments.getOwnerId()); 27 | setCid(comments.getCid()); 28 | } 29 | 30 | public int getLevels() { 31 | return levels; 32 | } 33 | 34 | public void setLevels(int levels) { 35 | this.levels = levels; 36 | } 37 | 38 | public List getChildren() { 39 | return children; 40 | } 41 | 42 | public void setChildren(List children) { 43 | this.children = children; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/com/my/blog/website/model/Bo/RestResponseBo.java: -------------------------------------------------------------------------------- 1 | package com.my.blog.website.model.Bo; 2 | 3 | /** 4 | * rest返回对象 5 | *^ 6 | * @param 7 | */ 8 | public class RestResponseBo { 9 | 10 | /** 11 | * 服务器响应数据 12 | */ 13 | private T payload; 14 | 15 | /** 16 | * 请求是否成功 17 | */ 18 | private boolean success; 19 | 20 | /** 21 | * 错误信息 22 | */ 23 | private String msg; 24 | 25 | /** 26 | * 状态码 27 | */ 28 | private int code = -1; 29 | 30 | /** 31 | * 服务器响应时间 32 | */ 33 | private long timestamp; 34 | 35 | public RestResponseBo() { 36 | this.timestamp = System.currentTimeMillis() / 1000; 37 | } 38 | 39 | public RestResponseBo(boolean success) { 40 | this.timestamp = System.currentTimeMillis() / 1000; 41 | this.success = success; 42 | } 43 | 44 | public RestResponseBo(boolean success, T payload) { 45 | this.timestamp = System.currentTimeMillis() / 1000; 46 | this.success = success; 47 | this.payload = payload; 48 | } 49 | 50 | public RestResponseBo(boolean success, T payload, int code) { 51 | this.timestamp = System.currentTimeMillis() / 1000; 52 | this.success = success; 53 | this.payload = payload; 54 | this.code = code; 55 | } 56 | 57 | public RestResponseBo(boolean success, String msg) { 58 | this.timestamp = System.currentTimeMillis() / 1000; 59 | this.success = success; 60 | this.msg = msg; 61 | } 62 | 63 | public RestResponseBo(boolean success, String msg, int code) { 64 | this.timestamp = System.currentTimeMillis() / 1000; 65 | this.success = success; 66 | this.msg = msg; 67 | this.code = code; 68 | } 69 | 70 | public T getPayload() { 71 | return payload; 72 | } 73 | 74 | public void setPayload(T payload) { 75 | this.payload = payload; 76 | } 77 | 78 | public boolean isSuccess() { 79 | return success; 80 | } 81 | 82 | public void setSuccess(boolean success) { 83 | this.success = success; 84 | } 85 | 86 | public String getMsg() { 87 | return msg; 88 | } 89 | 90 | public void setMsg(String msg) { 91 | this.msg = msg; 92 | } 93 | 94 | public int getCode() { 95 | return code; 96 | } 97 | 98 | public void setCode(int code) { 99 | this.code = code; 100 | } 101 | 102 | public long getTimestamp() { 103 | return timestamp; 104 | } 105 | 106 | public void setTimestamp(long timestamp) { 107 | this.timestamp = timestamp; 108 | } 109 | 110 | public static RestResponseBo ok() { 111 | return new RestResponseBo(true); 112 | } 113 | 114 | public static RestResponseBo ok(T payload) { 115 | return new RestResponseBo(true, payload); 116 | } 117 | 118 | public static RestResponseBo ok(int code) { 119 | return new RestResponseBo(true, null, code); 120 | } 121 | 122 | public static RestResponseBo ok(T payload, int code) { 123 | return new RestResponseBo(true, payload, code); 124 | } 125 | 126 | public static RestResponseBo fail() { 127 | return new RestResponseBo(false); 128 | } 129 | 130 | public static RestResponseBo fail(String msg) { 131 | return new RestResponseBo(false, msg); 132 | } 133 | 134 | public static RestResponseBo fail(int code) { 135 | return new RestResponseBo(false, null, code); 136 | } 137 | 138 | public static RestResponseBo fail(int code, String msg) { 139 | return new RestResponseBo(false, msg, code); 140 | } 141 | 142 | } -------------------------------------------------------------------------------- /src/main/java/com/my/blog/website/model/Bo/StatisticsBo.java: -------------------------------------------------------------------------------- 1 | package com.my.blog.website.model.Bo; 2 | 3 | import java.io.Serializable; 4 | 5 | /** 6 | * 后台统计对象 7 | */ 8 | public class StatisticsBo implements Serializable { 9 | 10 | private Long articles; 11 | private Long comments; 12 | private Long links; 13 | private Long attachs; 14 | 15 | public Long getArticles() { 16 | return articles; 17 | } 18 | 19 | public void setArticles(Long articles) { 20 | this.articles = articles; 21 | } 22 | 23 | public Long getComments() { 24 | return comments; 25 | } 26 | 27 | public void setComments(Long comments) { 28 | this.comments = comments; 29 | } 30 | 31 | public Long getLinks() { 32 | return links; 33 | } 34 | 35 | public void setLinks(Long links) { 36 | this.links = links; 37 | } 38 | 39 | public Long getAttachs() { 40 | return attachs; 41 | } 42 | 43 | public void setAttachs(Long attachs) { 44 | this.attachs = attachs; 45 | } 46 | 47 | @Override 48 | public String toString() { 49 | return "StatisticsBo{" + 50 | "articles=" + articles + 51 | ", comments=" + comments + 52 | ", links=" + links + 53 | ", attachs=" + attachs + 54 | '}'; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/main/java/com/my/blog/website/model/Vo/AttachVo.java: -------------------------------------------------------------------------------- 1 | package com.my.blog.website.model.Vo; 2 | 3 | import java.io.Serializable; 4 | 5 | /** 6 | * @author 7 | */ 8 | public class AttachVo implements Serializable { 9 | private Integer id; 10 | 11 | private String fname; 12 | 13 | private String ftype; 14 | 15 | private String fkey; 16 | 17 | private Integer authorId; 18 | 19 | private Integer created; 20 | 21 | private static final long serialVersionUID = 1L; 22 | 23 | public Integer getId() { 24 | return id; 25 | } 26 | 27 | public void setId(Integer id) { 28 | this.id = id; 29 | } 30 | 31 | public String getFname() { 32 | return fname; 33 | } 34 | 35 | public void setFname(String fname) { 36 | this.fname = fname; 37 | } 38 | 39 | public String getFtype() { 40 | return ftype; 41 | } 42 | 43 | public void setFtype(String ftype) { 44 | this.ftype = ftype; 45 | } 46 | 47 | public String getFkey() { 48 | return fkey; 49 | } 50 | 51 | public void setFkey(String fkey) { 52 | this.fkey = fkey; 53 | } 54 | 55 | public Integer getAuthorId() { 56 | return authorId; 57 | } 58 | 59 | public void setAuthorId(Integer authorId) { 60 | this.authorId = authorId; 61 | } 62 | 63 | public Integer getCreated() { 64 | return created; 65 | } 66 | 67 | public void setCreated(Integer created) { 68 | this.created = created; 69 | } 70 | } -------------------------------------------------------------------------------- /src/main/java/com/my/blog/website/model/Vo/CommentVo.java: -------------------------------------------------------------------------------- 1 | package com.my.blog.website.model.Vo; 2 | 3 | import java.io.Serializable; 4 | 5 | /** 6 | * @author 7 | */ 8 | public class CommentVo implements Serializable { 9 | /** 10 | * comment表主键 11 | */ 12 | private Integer coid; 13 | 14 | /** 15 | * post表主键,关联字段 16 | */ 17 | private Integer cid; 18 | 19 | /** 20 | * 评论生成时的GMT unix时间戳 21 | */ 22 | private Integer created; 23 | 24 | /** 25 | * 评论作者 26 | */ 27 | private String author; 28 | 29 | /** 30 | * 评论所属用户id 31 | */ 32 | private Integer authorId; 33 | 34 | /** 35 | * 评论所属内容作者id 36 | */ 37 | private Integer ownerId; 38 | 39 | /** 40 | * 评论者邮件 41 | */ 42 | private String mail; 43 | 44 | /** 45 | * 评论者网址 46 | */ 47 | private String url; 48 | 49 | /** 50 | * 评论者ip地址 51 | */ 52 | private String ip; 53 | 54 | /** 55 | * 评论者客户端 56 | */ 57 | private String agent; 58 | 59 | /** 60 | * 评论类型 61 | */ 62 | private String type; 63 | 64 | /** 65 | * 评论状态 66 | */ 67 | private String status; 68 | 69 | /** 70 | * 父级评论 71 | */ 72 | private Integer parent; 73 | 74 | /** 75 | * 评论内容 76 | */ 77 | private String content; 78 | 79 | private static final long serialVersionUID = 1L; 80 | 81 | public Integer getCoid() { 82 | return coid; 83 | } 84 | 85 | public void setCoid(Integer coid) { 86 | this.coid = coid; 87 | } 88 | 89 | public Integer getCid() { 90 | return cid; 91 | } 92 | 93 | public void setCid(Integer cid) { 94 | this.cid = cid; 95 | } 96 | 97 | public Integer getCreated() { 98 | return created; 99 | } 100 | 101 | public void setCreated(Integer created) { 102 | this.created = created; 103 | } 104 | 105 | public String getAuthor() { 106 | return author; 107 | } 108 | 109 | public void setAuthor(String author) { 110 | this.author = author; 111 | } 112 | 113 | public Integer getAuthorId() { 114 | return authorId; 115 | } 116 | 117 | public void setAuthorId(Integer authorId) { 118 | this.authorId = authorId; 119 | } 120 | 121 | public Integer getOwnerId() { 122 | return ownerId; 123 | } 124 | 125 | public void setOwnerId(Integer ownerId) { 126 | this.ownerId = ownerId; 127 | } 128 | 129 | public String getMail() { 130 | return mail; 131 | } 132 | 133 | public void setMail(String mail) { 134 | this.mail = mail; 135 | } 136 | 137 | public String getUrl() { 138 | return url; 139 | } 140 | 141 | public void setUrl(String url) { 142 | this.url = url; 143 | } 144 | 145 | public String getIp() { 146 | return ip; 147 | } 148 | 149 | public void setIp(String ip) { 150 | this.ip = ip; 151 | } 152 | 153 | public String getAgent() { 154 | return agent; 155 | } 156 | 157 | public void setAgent(String agent) { 158 | this.agent = agent; 159 | } 160 | 161 | public String getType() { 162 | return type; 163 | } 164 | 165 | public void setType(String type) { 166 | this.type = type; 167 | } 168 | 169 | public String getStatus() { 170 | return status; 171 | } 172 | 173 | public void setStatus(String status) { 174 | this.status = status; 175 | } 176 | 177 | public Integer getParent() { 178 | return parent; 179 | } 180 | 181 | public void setParent(Integer parent) { 182 | this.parent = parent; 183 | } 184 | 185 | public String getContent() { 186 | return content; 187 | } 188 | 189 | public void setContent(String content) { 190 | this.content = content; 191 | } 192 | } -------------------------------------------------------------------------------- /src/main/java/com/my/blog/website/model/Vo/ContentVo.java: -------------------------------------------------------------------------------- 1 | package com.my.blog.website.model.Vo; 2 | 3 | import java.io.Serializable; 4 | 5 | /** 6 | * @author 7 | */ 8 | public class ContentVo implements Serializable { 9 | /** 10 | * post表主键 11 | */ 12 | private Integer cid; 13 | 14 | /** 15 | * 内容标题 16 | */ 17 | private String title; 18 | 19 | /** 20 | * 内容缩略名 21 | */ 22 | private String slug; 23 | 24 | /** 25 | * 内容生成时的GMT unix时间戳 26 | */ 27 | private Integer created; 28 | 29 | /** 30 | * 内容更改时的GMT unix时间戳 31 | */ 32 | private Integer modified; 33 | 34 | /** 35 | * 内容所属用户id 36 | */ 37 | private Integer authorId; 38 | 39 | /** 40 | * 内容类别 41 | */ 42 | private String type; 43 | 44 | /** 45 | * 内容状态 46 | */ 47 | private String status; 48 | 49 | /** 50 | * 标签列表 51 | */ 52 | private String tags; 53 | 54 | /** 55 | * 分类列表 56 | */ 57 | private String categories; 58 | 59 | /** 60 | * 点击次数 61 | */ 62 | private Integer hits; 63 | 64 | /** 65 | * 内容所属评论数 66 | */ 67 | private Integer commentsNum; 68 | 69 | /** 70 | * 是否允许评论 71 | */ 72 | private Boolean allowComment; 73 | 74 | /** 75 | * 是否允许ping 76 | */ 77 | private Boolean allowPing; 78 | 79 | /** 80 | * 允许出现在聚合中 81 | */ 82 | private Boolean allowFeed; 83 | 84 | /** 85 | * 内容文字 86 | */ 87 | private String content; 88 | 89 | private static final long serialVersionUID = 1L; 90 | 91 | public Integer getCid() { 92 | return cid; 93 | } 94 | 95 | public void setCid(Integer cid) { 96 | this.cid = cid; 97 | } 98 | 99 | public String getTitle() { 100 | return title; 101 | } 102 | 103 | public void setTitle(String title) { 104 | this.title = title; 105 | } 106 | 107 | public String getSlug() { 108 | return slug; 109 | } 110 | 111 | public void setSlug(String slug) { 112 | this.slug = slug; 113 | } 114 | 115 | public Integer getCreated() { 116 | return created; 117 | } 118 | 119 | public void setCreated(Integer created) { 120 | this.created = created; 121 | } 122 | 123 | public Integer getModified() { 124 | return modified; 125 | } 126 | 127 | public void setModified(Integer modified) { 128 | this.modified = modified; 129 | } 130 | 131 | public Integer getAuthorId() { 132 | return authorId; 133 | } 134 | 135 | public void setAuthorId(Integer authorId) { 136 | this.authorId = authorId; 137 | } 138 | 139 | public String getType() { 140 | return type; 141 | } 142 | 143 | public void setType(String type) { 144 | this.type = type; 145 | } 146 | 147 | public String getStatus() { 148 | return status; 149 | } 150 | 151 | public void setStatus(String status) { 152 | this.status = status; 153 | } 154 | 155 | public String getTags() { 156 | return tags; 157 | } 158 | 159 | public void setTags(String tags) { 160 | this.tags = tags; 161 | } 162 | 163 | public String getCategories() { 164 | return categories; 165 | } 166 | 167 | public void setCategories(String categories) { 168 | this.categories = categories; 169 | } 170 | 171 | public Integer getHits() { 172 | return hits; 173 | } 174 | 175 | public void setHits(Integer hits) { 176 | this.hits = hits; 177 | } 178 | 179 | public Integer getCommentsNum() { 180 | return commentsNum; 181 | } 182 | 183 | public void setCommentsNum(Integer commentsNum) { 184 | this.commentsNum = commentsNum; 185 | } 186 | 187 | public Boolean getAllowComment() { 188 | return allowComment; 189 | } 190 | 191 | public void setAllowComment(Boolean allowComment) { 192 | this.allowComment = allowComment; 193 | } 194 | 195 | public Boolean getAllowPing() { 196 | return allowPing; 197 | } 198 | 199 | public void setAllowPing(Boolean allowPing) { 200 | this.allowPing = allowPing; 201 | } 202 | 203 | public Boolean getAllowFeed() { 204 | return allowFeed; 205 | } 206 | 207 | public void setAllowFeed(Boolean allowFeed) { 208 | this.allowFeed = allowFeed; 209 | } 210 | 211 | public String getContent() { 212 | return content; 213 | } 214 | 215 | public void setContent(String content) { 216 | this.content = content; 217 | } 218 | } -------------------------------------------------------------------------------- /src/main/java/com/my/blog/website/model/Vo/LogVo.java: -------------------------------------------------------------------------------- 1 | package com.my.blog.website.model.Vo; 2 | 3 | import java.io.Serializable; 4 | 5 | /** 6 | * @author 7 | */ 8 | public class LogVo implements Serializable { 9 | /** 10 | * 日志主键 11 | */ 12 | private Integer id; 13 | 14 | /** 15 | * 产生的动作 16 | */ 17 | private String action; 18 | 19 | /** 20 | * 产生的数据 21 | */ 22 | private String data; 23 | 24 | /** 25 | * 发生人id 26 | */ 27 | private Integer authorId; 28 | 29 | /** 30 | * 日志产生的ip 31 | */ 32 | private String ip; 33 | 34 | /** 35 | * 日志创建时间 36 | */ 37 | private Integer created; 38 | 39 | 40 | 41 | private static final long serialVersionUID = 1L; 42 | 43 | public Integer getId() { 44 | return id; 45 | } 46 | 47 | public void setId(Integer id) { 48 | this.id = id; 49 | } 50 | 51 | public String getAction() { 52 | return action; 53 | } 54 | 55 | public void setAction(String action) { 56 | this.action = action; 57 | } 58 | 59 | public String getData() { 60 | return data; 61 | } 62 | 63 | public void setData(String data) { 64 | this.data = data; 65 | } 66 | 67 | public Integer getAuthorId() { 68 | return authorId; 69 | } 70 | 71 | public void setAuthorId(Integer authorId) { 72 | this.authorId = authorId; 73 | } 74 | 75 | public String getIp() { 76 | return ip; 77 | } 78 | 79 | public void setIp(String ip) { 80 | this.ip = ip; 81 | } 82 | 83 | public Integer getCreated() { 84 | return created; 85 | } 86 | 87 | public void setCreated(Integer created) { 88 | this.created = created; 89 | } 90 | } -------------------------------------------------------------------------------- /src/main/java/com/my/blog/website/model/Vo/MetaVo.java: -------------------------------------------------------------------------------- 1 | package com.my.blog.website.model.Vo; 2 | 3 | import java.io.Serializable; 4 | 5 | /** 6 | * @author 7 | */ 8 | public class MetaVo implements Serializable { 9 | /** 10 | * 项目主键 11 | */ 12 | private Integer mid; 13 | 14 | /** 15 | * 名称 16 | */ 17 | private String name; 18 | 19 | /** 20 | * 项目缩略名 21 | */ 22 | private String slug; 23 | 24 | /** 25 | * 项目类型 26 | */ 27 | private String type; 28 | 29 | /** 30 | * 选项描述 31 | */ 32 | private String description; 33 | 34 | /** 35 | * 项目排序 36 | */ 37 | private Integer sort; 38 | 39 | private Integer parent; 40 | 41 | private static final long serialVersionUID = 1L; 42 | 43 | public Integer getMid() { 44 | return mid; 45 | } 46 | 47 | public void setMid(Integer mid) { 48 | this.mid = mid; 49 | } 50 | 51 | public String getName() { 52 | return name; 53 | } 54 | 55 | public void setName(String name) { 56 | this.name = name; 57 | } 58 | 59 | public String getSlug() { 60 | return slug; 61 | } 62 | 63 | public void setSlug(String slug) { 64 | this.slug = slug; 65 | } 66 | 67 | public String getType() { 68 | return type; 69 | } 70 | 71 | public void setType(String type) { 72 | this.type = type; 73 | } 74 | 75 | public String getDescription() { 76 | return description; 77 | } 78 | 79 | public void setDescription(String description) { 80 | this.description = description; 81 | } 82 | 83 | public Integer getSort() { 84 | return sort; 85 | } 86 | 87 | public void setSort(Integer sort) { 88 | this.sort = sort; 89 | } 90 | 91 | public Integer getParent() { 92 | return parent; 93 | } 94 | 95 | public void setParent(Integer parent) { 96 | this.parent = parent; 97 | } 98 | } -------------------------------------------------------------------------------- /src/main/java/com/my/blog/website/model/Vo/OptionVo.java: -------------------------------------------------------------------------------- 1 | package com.my.blog.website.model.Vo; 2 | 3 | import java.io.Serializable; 4 | 5 | /** 6 | * @author 7 | */ 8 | public class OptionVo implements Serializable { 9 | /** 10 | * 配置名称 11 | */ 12 | private String name; 13 | 14 | /** 15 | * 配置值 16 | */ 17 | private String value; 18 | 19 | private String description; 20 | 21 | private static final long serialVersionUID = 1L; 22 | 23 | public String getName() { 24 | return name; 25 | } 26 | 27 | public void setName(String name) { 28 | this.name = name; 29 | } 30 | 31 | public String getValue() { 32 | return value; 33 | } 34 | 35 | public void setValue(String value) { 36 | this.value = value; 37 | } 38 | 39 | public String getDescription() { 40 | return description; 41 | } 42 | 43 | public void setDescription(String description) { 44 | this.description = description; 45 | } 46 | } -------------------------------------------------------------------------------- /src/main/java/com/my/blog/website/model/Vo/RelationshipVoKey.java: -------------------------------------------------------------------------------- 1 | package com.my.blog.website.model.Vo; 2 | 3 | import java.io.Serializable; 4 | 5 | /** 6 | * @author 7 | */ 8 | public class RelationshipVoKey implements Serializable { 9 | /** 10 | * 内容主键 11 | */ 12 | private Integer cid; 13 | 14 | /** 15 | * 项目主键 16 | */ 17 | private Integer mid; 18 | 19 | private static final long serialVersionUID = 1L; 20 | 21 | public Integer getCid() { 22 | return cid; 23 | } 24 | 25 | public void setCid(Integer cid) { 26 | this.cid = cid; 27 | } 28 | 29 | public Integer getMid() { 30 | return mid; 31 | } 32 | 33 | public void setMid(Integer mid) { 34 | this.mid = mid; 35 | } 36 | } -------------------------------------------------------------------------------- /src/main/java/com/my/blog/website/model/Vo/UserVo.java: -------------------------------------------------------------------------------- 1 | package com.my.blog.website.model.Vo; 2 | 3 | import java.io.Serializable; 4 | 5 | /** 6 | * @author 7 | */ 8 | public class UserVo implements Serializable { 9 | /** 10 | * user表主键 11 | */ 12 | private Integer uid; 13 | 14 | /** 15 | * 用户名称 16 | */ 17 | private String username; 18 | 19 | /** 20 | * 用户密码 21 | */ 22 | private String password; 23 | 24 | /** 25 | * 用户的邮箱 26 | */ 27 | private String email; 28 | 29 | /** 30 | * 用户的主页 31 | */ 32 | private String homeUrl; 33 | 34 | /** 35 | * 用户显示的名称 36 | */ 37 | private String screenName; 38 | 39 | /** 40 | * 用户注册时的GMT unix时间戳 41 | */ 42 | private Integer created; 43 | 44 | /** 45 | * 最后活动时间 46 | */ 47 | private Integer activated; 48 | 49 | /** 50 | * 上次登录最后活跃时间 51 | */ 52 | private Integer logged; 53 | 54 | /** 55 | * 用户组 56 | */ 57 | private String groupName; 58 | 59 | private static final long serialVersionUID = 1L; 60 | 61 | public Integer getUid() { 62 | return uid; 63 | } 64 | 65 | public void setUid(Integer uid) { 66 | this.uid = uid; 67 | } 68 | 69 | public String getUsername() { 70 | return username; 71 | } 72 | 73 | public void setUsername(String username) { 74 | this.username = username; 75 | } 76 | 77 | public String getPassword() { 78 | return password; 79 | } 80 | 81 | public void setPassword(String password) { 82 | this.password = password; 83 | } 84 | 85 | public String getEmail() { 86 | return email; 87 | } 88 | 89 | public void setEmail(String email) { 90 | this.email = email; 91 | } 92 | 93 | public String getHomeUrl() { 94 | return homeUrl; 95 | } 96 | 97 | public void setHomeUrl(String homeUrl) { 98 | this.homeUrl = homeUrl; 99 | } 100 | 101 | public String getScreenName() { 102 | return screenName; 103 | } 104 | 105 | public void setScreenName(String screenName) { 106 | this.screenName = screenName; 107 | } 108 | 109 | public Integer getCreated() { 110 | return created; 111 | } 112 | 113 | public void setCreated(Integer created) { 114 | this.created = created; 115 | } 116 | 117 | public Integer getActivated() { 118 | return activated; 119 | } 120 | 121 | public void setActivated(Integer activated) { 122 | this.activated = activated; 123 | } 124 | 125 | public Integer getLogged() { 126 | return logged; 127 | } 128 | 129 | public void setLogged(Integer logged) { 130 | this.logged = logged; 131 | } 132 | 133 | public String getGroupName() { 134 | return groupName; 135 | } 136 | 137 | public void setGroupName(String groupName) { 138 | this.groupName = groupName; 139 | } 140 | } -------------------------------------------------------------------------------- /src/main/java/com/my/blog/website/service/IAttachService.java: -------------------------------------------------------------------------------- 1 | package com.my.blog.website.service; 2 | 3 | import com.github.pagehelper.PageInfo; 4 | import com.my.blog.website.model.Vo.AttachVo; 5 | 6 | /** 7 | * Created by wangq on 2017/3/20. 8 | */ 9 | public interface IAttachService { 10 | /** 11 | * 分页查询附件 12 | * @param page 13 | * @param limit 14 | * @return 15 | */ 16 | PageInfo getAttachs(Integer page,Integer limit); 17 | 18 | /** 19 | * 保存附件 20 | * 21 | * @param fname 22 | * @param fkey 23 | * @param ftype 24 | * @param author 25 | */ 26 | void save(String fname, String fkey, String ftype, Integer author); 27 | 28 | /** 29 | * 根据附件id查询附件 30 | * @param id 31 | * @return 32 | */ 33 | AttachVo selectById(Integer id); 34 | 35 | /** 36 | * 删除附件 37 | * @param id 38 | */ 39 | void deleteById(Integer id); 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/com/my/blog/website/service/ICommentService.java: -------------------------------------------------------------------------------- 1 | package com.my.blog.website.service; 2 | 3 | import com.github.pagehelper.PageInfo; 4 | import com.my.blog.website.model.Vo.CommentVo; 5 | import com.my.blog.website.model.Vo.CommentVoExample; 6 | import com.my.blog.website.model.Bo.CommentBo; 7 | 8 | /** 9 | * Created by BlueT on 2017/3/16. 10 | */ 11 | public interface ICommentService { 12 | 13 | /** 14 | * 保存对象 15 | * @param commentVo 16 | */ 17 | String insertComment(CommentVo commentVo); 18 | 19 | /** 20 | * 获取文章下的评论 21 | * @param cid 22 | * @param page 23 | * @param limit 24 | * @return CommentBo 25 | */ 26 | PageInfo getComments(Integer cid, int page, int limit); 27 | 28 | /** 29 | * 获取文章下的评论 30 | * @param commentVoExample 31 | * @param page 32 | * @param limit 33 | * @return CommentVo 34 | */ 35 | PageInfo getCommentsWithPage(CommentVoExample commentVoExample, int page, int limit); 36 | 37 | 38 | /** 39 | * 根据主键查询评论 40 | * @param coid 41 | * @return 42 | */ 43 | CommentVo getCommentById(Integer coid); 44 | 45 | 46 | /** 47 | * 删除评论,暂时没用 48 | * @param coid 49 | * @param cid 50 | * @throws Exception 51 | */ 52 | void delete(Integer coid, Integer cid); 53 | 54 | /** 55 | * 更新评论状态 56 | * @param comments 57 | */ 58 | void update(CommentVo comments); 59 | 60 | } 61 | -------------------------------------------------------------------------------- /src/main/java/com/my/blog/website/service/IContentService.java: -------------------------------------------------------------------------------- 1 | package com.my.blog.website.service; 2 | 3 | import com.github.pagehelper.PageInfo; 4 | import com.my.blog.website.model.Vo.ContentVoExample; 5 | import com.my.blog.website.model.Vo.ContentVo; 6 | 7 | /** 8 | * Created by Administrator on 2017/3/13 013. 9 | */ 10 | public interface IContentService { 11 | 12 | // /** 13 | // * 保存文章 14 | // * @param contentVo contentVo 15 | // */ 16 | // void insertContent(ContentVo contentVo); 17 | 18 | /** 19 | * 发布文章 20 | * @param contents 21 | */ 22 | String publish(ContentVo contents); 23 | 24 | /** 25 | *查询文章返回多条数据 26 | * @param p 当前页 27 | * @param limit 每页条数 28 | * @return ContentVo 29 | */ 30 | PageInfo getContents(Integer p, Integer limit); 31 | 32 | 33 | /** 34 | * 根据id或slug获取文章 35 | * 36 | * @param id id 37 | * @return ContentVo 38 | */ 39 | ContentVo getContents(String id); 40 | 41 | /** 42 | * 根据主键更新 43 | * @param contentVo contentVo 44 | */ 45 | void updateContentByCid(ContentVo contentVo); 46 | 47 | 48 | /** 49 | * 查询分类/标签下的文章归档 50 | * @param mid mid 51 | * @param page page 52 | * @param limit limit 53 | * @return ContentVo 54 | */ 55 | PageInfo getArticles(Integer mid, int page, int limit); 56 | 57 | /** 58 | * 搜索、分页 59 | * @param keyword keyword 60 | * @param page page 61 | * @param limit limit 62 | * @return ContentVo 63 | */ 64 | PageInfo getArticles(String keyword,Integer page,Integer limit); 65 | 66 | 67 | /** 68 | * @param commentVoExample 69 | * @param page 70 | * @param limit 71 | * @return 72 | */ 73 | PageInfo getArticlesWithpage(ContentVoExample commentVoExample, Integer page, Integer limit); 74 | /** 75 | * 根据文章id删除 76 | * @param cid 77 | */ 78 | String deleteByCid(Integer cid); 79 | 80 | /** 81 | * 编辑文章 82 | * @param contents 83 | */ 84 | String updateArticle(ContentVo contents); 85 | 86 | 87 | /** 88 | * 更新原有文章的category 89 | * @param ordinal 90 | * @param newCatefory 91 | */ 92 | void updateCategory(String ordinal,String newCatefory); 93 | } 94 | -------------------------------------------------------------------------------- /src/main/java/com/my/blog/website/service/ILogService.java: -------------------------------------------------------------------------------- 1 | package com.my.blog.website.service; 2 | 3 | import com.my.blog.website.model.Vo.LogVo; 4 | 5 | import java.util.List; 6 | 7 | /** 8 | * Created by BlueT on 2017/3/4. 9 | */ 10 | public interface ILogService { 11 | 12 | /** 13 | * 保存操作日志 14 | * 15 | * @param logVo 16 | */ 17 | void insertLog(LogVo logVo); 18 | 19 | /** 20 | * 保存 21 | * @param action 22 | * @param data 23 | * @param ip 24 | * @param authorId 25 | */ 26 | void insertLog(String action, String data, String ip, Integer authorId); 27 | 28 | /** 29 | * 获取日志分页 30 | * @param page 当前页 31 | * @param limit 每页条数 32 | * @return 日志 33 | */ 34 | List getLogs(int page,int limit); 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/com/my/blog/website/service/IMetaService.java: -------------------------------------------------------------------------------- 1 | package com.my.blog.website.service; 2 | 3 | import com.my.blog.website.dto.MetaDto; 4 | import com.my.blog.website.model.Vo.MetaVo; 5 | 6 | import java.util.List; 7 | 8 | /** 9 | * 分类信息service接口 10 | * Created by BlueT on 2017/3/17. 11 | */ 12 | public interface IMetaService { 13 | /** 14 | * 根据类型和名字查询项 15 | * 16 | * @param type 17 | * @param name 18 | * @return 19 | */ 20 | MetaDto getMeta(String type, String name); 21 | 22 | /** 23 | * 根据文章id获取项目个数 24 | * @param mid 25 | * @return 26 | */ 27 | Integer countMeta(Integer mid); 28 | 29 | /** 30 | * 根据类型查询项目列表 31 | * @param types 32 | * @return 33 | */ 34 | List getMetas(String types); 35 | 36 | 37 | /** 38 | * 保存多个项目 39 | * @param cid 40 | * @param names 41 | * @param type 42 | */ 43 | void saveMetas(Integer cid, String names, String type); 44 | 45 | /** 46 | * 保存项目 47 | * @param type 48 | * @param name 49 | * @param mid 50 | */ 51 | void saveMeta(String type, String name, Integer mid); 52 | 53 | /** 54 | * 根据类型查询项目列表,带项目下面的文章数 55 | * @return 56 | */ 57 | List getMetaList(String type, String orderby, int limit); 58 | 59 | /** 60 | * 删除项目 61 | * @param mid 62 | */ 63 | void delete(int mid); 64 | 65 | /** 66 | * 保存项目 67 | * @param metas 68 | */ 69 | void saveMeta(MetaVo metas); 70 | 71 | /** 72 | * 更新项目 73 | * @param metas 74 | */ 75 | void update(MetaVo metas); 76 | } 77 | -------------------------------------------------------------------------------- /src/main/java/com/my/blog/website/service/IOptionService.java: -------------------------------------------------------------------------------- 1 | package com.my.blog.website.service; 2 | 3 | import com.my.blog.website.model.Vo.OptionVo; 4 | 5 | import java.util.List; 6 | import java.util.Map; 7 | 8 | /** 9 | * options的接口 10 | * Created by BlueT on 2017/3/7. 11 | */ 12 | public interface IOptionService { 13 | 14 | void insertOption(OptionVo optionVo); 15 | 16 | void insertOption(String name, String value); 17 | 18 | List getOptions(); 19 | 20 | 21 | /** 22 | * 保存一组配置 23 | * 24 | * @param options 25 | */ 26 | void saveOptions(Map options); 27 | 28 | OptionVo getOptionByName(String name); 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/com/my/blog/website/service/IRelationshipService.java: -------------------------------------------------------------------------------- 1 | package com.my.blog.website.service; 2 | 3 | import com.my.blog.website.model.Vo.RelationshipVoKey; 4 | 5 | import java.util.List; 6 | 7 | /** 8 | * Created by BlueT on 2017/3/18. 9 | */ 10 | public interface IRelationshipService { 11 | /** 12 | * 按住键删除 13 | * @param cid 14 | * @param mid 15 | */ 16 | void deleteById(Integer cid, Integer mid); 17 | 18 | /** 19 | * 按主键统计条数 20 | * @param cid 21 | * @param mid 22 | * @return 条数 23 | */ 24 | Long countById(Integer cid, Integer mid); 25 | 26 | 27 | /** 28 | * 保存對象 29 | * @param relationshipVoKey 30 | */ 31 | void insertVo(RelationshipVoKey relationshipVoKey); 32 | 33 | /** 34 | * 根据id搜索 35 | * @param cid 36 | * @param mid 37 | * @return 38 | */ 39 | List getRelationshipById(Integer cid, Integer mid); 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/com/my/blog/website/service/ISiteService.java: -------------------------------------------------------------------------------- 1 | package com.my.blog.website.service; 2 | 3 | import com.my.blog.website.dto.MetaDto; 4 | import com.my.blog.website.model.Bo.ArchiveBo; 5 | import com.my.blog.website.model.Bo.BackResponseBo; 6 | import com.my.blog.website.model.Bo.StatisticsBo; 7 | import com.my.blog.website.model.Vo.CommentVo; 8 | import com.my.blog.website.model.Vo.ContentVo; 9 | 10 | import java.util.List; 11 | 12 | /** 13 | * 站点服务 14 | * 15 | * Created by 13 on 2017/2/23. 16 | */ 17 | public interface ISiteService { 18 | 19 | 20 | /** 21 | * 最新收到的评论 22 | * 23 | * @param limit 24 | * @return 25 | */ 26 | List recentComments(int limit); 27 | 28 | /** 29 | * 最新发表的文章 30 | * 31 | * @param limit 32 | * @return 33 | */ 34 | List recentContents(int limit); 35 | 36 | /** 37 | * 查询一条评论 38 | * @param coid 39 | * @return 40 | */ 41 | CommentVo getComment(Integer coid); 42 | 43 | /** 44 | * 系统备份 45 | * @param bk_type 46 | * @param bk_path 47 | * @param fmt 48 | * @return 49 | */ 50 | BackResponseBo backup(String bk_type, String bk_path, String fmt) throws Exception; 51 | 52 | 53 | /** 54 | * 获取后台统计数据 55 | * 56 | * @return 57 | */ 58 | StatisticsBo getStatistics(); 59 | 60 | /** 61 | * 查询文章归档 62 | * 63 | * @return 64 | */ 65 | List getArchives(); 66 | 67 | /** 68 | * 获取分类/标签列表 69 | * @return 70 | */ 71 | List metas(String type, String orderBy, int limit); 72 | 73 | } 74 | -------------------------------------------------------------------------------- /src/main/java/com/my/blog/website/service/IUserService.java: -------------------------------------------------------------------------------- 1 | package com.my.blog.website.service; 2 | 3 | import com.my.blog.website.model.Vo.UserVo; 4 | 5 | /** 6 | * Created by BlueT on 2017/3/3. 7 | */ 8 | public interface IUserService { 9 | 10 | /** 11 | * 保存用户数据 12 | * 13 | * @param userVo 用户数据 14 | * @return 主键 15 | */ 16 | 17 | Integer insertUser(UserVo userVo); 18 | 19 | /** 20 | * 通过uid查找对象 21 | * @param uid 22 | * @return 23 | */ 24 | UserVo queryUserById(Integer uid); 25 | 26 | /** 27 | * 用戶登录 28 | * @param username 29 | * @param password 30 | * @return 31 | */ 32 | UserVo login(String username, String password); 33 | 34 | /** 35 | * 根据主键更新user对象 36 | * @param userVo 37 | * @return 38 | */ 39 | void updateByUid(UserVo userVo); 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/com/my/blog/website/service/impl/AttachServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.my.blog.website.service.impl; 2 | 3 | import com.github.pagehelper.PageHelper; 4 | import com.github.pagehelper.PageInfo; 5 | import com.my.blog.website.dao.AttachVoMapper; 6 | import com.my.blog.website.utils.DateKit; 7 | import com.my.blog.website.model.Vo.AttachVo; 8 | import com.my.blog.website.model.Vo.AttachVoExample; 9 | import com.my.blog.website.service.IAttachService; 10 | import org.slf4j.Logger; 11 | import org.slf4j.LoggerFactory; 12 | import org.springframework.stereotype.Service; 13 | import org.springframework.transaction.annotation.Transactional; 14 | 15 | import javax.annotation.Resource; 16 | import java.util.List; 17 | 18 | /** 19 | * Created by wangq on 2017/3/20. 20 | */ 21 | @Service 22 | public class AttachServiceImpl implements IAttachService { 23 | private static final Logger LOGGER = LoggerFactory.getLogger(AttachServiceImpl.class); 24 | 25 | @Resource 26 | private AttachVoMapper attachDao; 27 | 28 | @Override 29 | public PageInfo getAttachs(Integer page, Integer limit) { 30 | PageHelper.startPage(page, limit); 31 | AttachVoExample attachVoExample = new AttachVoExample(); 32 | attachVoExample.setOrderByClause("id desc"); 33 | List attachVos = attachDao.selectByExample(attachVoExample); 34 | return new PageInfo<>(attachVos); 35 | } 36 | 37 | @Override 38 | public AttachVo selectById(Integer id) { 39 | if(null != id){ 40 | return attachDao.selectByPrimaryKey(id); 41 | } 42 | return null; 43 | } 44 | 45 | @Override 46 | @Transactional 47 | public void save(String fname, String fkey, String ftype, Integer author) { 48 | AttachVo attach = new AttachVo(); 49 | attach.setFname(fname); 50 | attach.setAuthorId(author); 51 | attach.setFkey(fkey); 52 | attach.setFtype(ftype); 53 | attach.setCreated(DateKit.getCurrentUnixTime()); 54 | attachDao.insertSelective(attach); 55 | } 56 | 57 | @Override 58 | @Transactional 59 | public void deleteById(Integer id) { 60 | if (null != id) { 61 | attachDao.deleteByPrimaryKey( id); 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/main/java/com/my/blog/website/service/impl/LogServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.my.blog.website.service.impl; 2 | 3 | import com.github.pagehelper.PageHelper; 4 | import com.my.blog.website.dao.LogVoMapper; 5 | import com.my.blog.website.service.ILogService; 6 | import com.my.blog.website.utils.DateKit; 7 | import com.my.blog.website.constant.WebConst; 8 | import com.my.blog.website.model.Vo.LogVo; 9 | import com.my.blog.website.model.Vo.LogVoExample; 10 | import org.slf4j.Logger; 11 | import org.slf4j.LoggerFactory; 12 | import org.springframework.stereotype.Service; 13 | 14 | import javax.annotation.Resource; 15 | import java.util.List; 16 | 17 | /** 18 | * Created by BlueT on 2017/3/4. 19 | */ 20 | @Service 21 | public class LogServiceImpl implements ILogService { 22 | 23 | private static final Logger LOGGER = LoggerFactory.getLogger(LogServiceImpl.class); 24 | 25 | @Resource 26 | private LogVoMapper logDao; 27 | 28 | @Override 29 | public void insertLog(LogVo logVo) { 30 | logDao.insert(logVo); 31 | } 32 | 33 | @Override 34 | public void insertLog(String action, String data, String ip, Integer authorId) { 35 | LogVo logs = new LogVo(); 36 | logs.setAction(action); 37 | logs.setData(data); 38 | logs.setIp(ip); 39 | logs.setAuthorId(authorId); 40 | logs.setCreated(DateKit.getCurrentUnixTime()); 41 | logDao.insert(logs); 42 | } 43 | 44 | @Override 45 | public List getLogs(int page, int limit) { 46 | LOGGER.debug("Enter getLogs method:page={},linit={}",page,limit); 47 | if (page <= 0) { 48 | page = 1; 49 | } 50 | if (limit < 1 || limit > WebConst.MAX_POSTS) { 51 | limit = 10; 52 | } 53 | LogVoExample logVoExample = new LogVoExample(); 54 | logVoExample.setOrderByClause("id desc"); 55 | PageHelper.startPage((page - 1) * limit, limit); 56 | List logVos = logDao.selectByExample(logVoExample); 57 | LOGGER.debug("Exit getLogs method"); 58 | return logVos; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/main/java/com/my/blog/website/service/impl/OptionServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.my.blog.website.service.impl; 2 | 3 | import com.my.blog.website.dao.OptionVoMapper; 4 | import com.my.blog.website.model.Vo.OptionVo; 5 | import com.my.blog.website.model.Vo.OptionVoExample; 6 | import com.my.blog.website.service.IOptionService; 7 | import org.slf4j.Logger; 8 | import org.slf4j.LoggerFactory; 9 | import org.springframework.stereotype.Service; 10 | import org.springframework.transaction.annotation.Transactional; 11 | 12 | import javax.annotation.Resource; 13 | import java.util.List; 14 | import java.util.Map; 15 | 16 | /** 17 | * options表的service 18 | * Created by BlueT on 2017/3/7. 19 | */ 20 | @Service 21 | public class OptionServiceImpl implements IOptionService { 22 | 23 | private static final Logger LOGGER = LoggerFactory.getLogger(OptionServiceImpl.class); 24 | 25 | @Resource 26 | private OptionVoMapper optionDao; 27 | 28 | @Override 29 | public void insertOption(OptionVo optionVo) { 30 | LOGGER.debug("Enter insertOption method:optionVo={}", optionVo); 31 | optionDao.insertSelective(optionVo); 32 | LOGGER.debug("Exit insertOption method."); 33 | } 34 | 35 | @Override 36 | @Transactional 37 | public void insertOption(String name, String value) { 38 | LOGGER.debug("Enter insertOption method:name={},value={}", name, value); 39 | OptionVo optionVo = new OptionVo(); 40 | optionVo.setName(name); 41 | optionVo.setValue(value); 42 | if (optionDao.selectByPrimaryKey(name) == null) { 43 | optionDao.insertSelective(optionVo); 44 | } else { 45 | optionDao.updateByPrimaryKeySelective(optionVo); 46 | } 47 | LOGGER.debug("Exit insertOption method."); 48 | } 49 | 50 | @Override 51 | @Transactional 52 | public void saveOptions(Map options) { 53 | if (null != options && !options.isEmpty()) { 54 | options.forEach(this::insertOption); 55 | } 56 | } 57 | 58 | @Override 59 | public OptionVo getOptionByName(String name) { 60 | return optionDao.selectByPrimaryKey(name); 61 | } 62 | 63 | @Override 64 | public List getOptions() { 65 | return optionDao.selectByExample(new OptionVoExample()); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/main/java/com/my/blog/website/service/impl/RelationshipServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.my.blog.website.service.impl; 2 | 3 | import com.my.blog.website.model.Vo.RelationshipVoExample; 4 | import com.my.blog.website.model.Vo.RelationshipVoKey; 5 | import com.my.blog.website.service.IRelationshipService; 6 | import com.my.blog.website.dao.RelationshipVoMapper; 7 | import org.slf4j.Logger; 8 | import org.slf4j.LoggerFactory; 9 | import org.springframework.stereotype.Service; 10 | 11 | import javax.annotation.Resource; 12 | import java.util.List; 13 | 14 | /** 15 | * Created by BlueT on 2017/3/18. 16 | */ 17 | @Service 18 | public class RelationshipServiceImpl implements IRelationshipService { 19 | private static final Logger LOGGER = LoggerFactory.getLogger(RelationshipServiceImpl.class); 20 | 21 | @Resource 22 | private RelationshipVoMapper relationshipVoMapper; 23 | 24 | @Override 25 | public void deleteById(Integer cid, Integer mid) { 26 | RelationshipVoExample relationshipVoExample = new RelationshipVoExample(); 27 | RelationshipVoExample.Criteria criteria = relationshipVoExample.createCriteria(); 28 | if (cid != null) { 29 | criteria.andCidEqualTo(cid); 30 | } 31 | if (mid != null) { 32 | criteria.andMidEqualTo(mid); 33 | } 34 | relationshipVoMapper.deleteByExample(relationshipVoExample); 35 | } 36 | 37 | @Override 38 | public List getRelationshipById(Integer cid, Integer mid) { 39 | RelationshipVoExample relationshipVoExample = new RelationshipVoExample(); 40 | RelationshipVoExample.Criteria criteria = relationshipVoExample.createCriteria(); 41 | if (cid != null) { 42 | criteria.andCidEqualTo(cid); 43 | } 44 | if (mid != null) { 45 | criteria.andMidEqualTo(mid); 46 | } 47 | return relationshipVoMapper.selectByExample(relationshipVoExample); 48 | } 49 | 50 | @Override 51 | public void insertVo(RelationshipVoKey relationshipVoKey) { 52 | relationshipVoMapper.insert(relationshipVoKey); 53 | } 54 | 55 | @Override 56 | public Long countById(Integer cid, Integer mid) { 57 | LOGGER.debug("Enter countById method:cid={},mid={}",cid,mid); 58 | RelationshipVoExample relationshipVoExample = new RelationshipVoExample(); 59 | RelationshipVoExample.Criteria criteria = relationshipVoExample.createCriteria(); 60 | if (cid != null) { 61 | criteria.andCidEqualTo(cid); 62 | } 63 | if (mid != null) { 64 | criteria.andMidEqualTo(mid); 65 | } 66 | long num = relationshipVoMapper.countByExample(relationshipVoExample); 67 | LOGGER.debug("Exit countById method return num={}",num); 68 | return num; 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/main/java/com/my/blog/website/service/impl/UserServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.my.blog.website.service.impl; 2 | 3 | import com.my.blog.website.dao.UserVoMapper; 4 | import com.my.blog.website.exception.TipException; 5 | import com.my.blog.website.model.Vo.UserVo; 6 | import com.my.blog.website.service.IUserService; 7 | import com.my.blog.website.utils.TaleUtils; 8 | import com.my.blog.website.model.Vo.UserVoExample; 9 | import org.apache.commons.lang3.StringUtils; 10 | import org.slf4j.Logger; 11 | import org.slf4j.LoggerFactory; 12 | import org.springframework.stereotype.Service; 13 | import org.springframework.transaction.annotation.Transactional; 14 | 15 | import javax.annotation.Resource; 16 | import java.util.List; 17 | 18 | /** 19 | * Created by BlueT on 2017/3/3. 20 | */ 21 | @Service 22 | public class UserServiceImpl implements IUserService { 23 | private static final Logger LOGGER = LoggerFactory.getLogger(UserServiceImpl.class); 24 | 25 | @Resource 26 | private UserVoMapper userDao; 27 | 28 | @Override 29 | @Transactional 30 | public Integer insertUser(UserVo userVo) { 31 | Integer uid = null; 32 | if (StringUtils.isNotBlank(userVo.getUsername()) && StringUtils.isNotBlank(userVo.getEmail())) { 33 | // 用户密码加密 34 | String encodePwd = TaleUtils.MD5encode(userVo.getUsername() + userVo.getPassword()); 35 | userVo.setPassword(encodePwd); 36 | userDao.insertSelective(userVo); 37 | } 38 | return userVo.getUid(); 39 | } 40 | 41 | @Override 42 | public UserVo queryUserById(Integer uid) { 43 | UserVo userVo = null; 44 | if (uid != null) { 45 | userVo = userDao.selectByPrimaryKey(uid); 46 | } 47 | return userVo; 48 | } 49 | 50 | @Override 51 | public UserVo login(String username, String password) { 52 | if (StringUtils.isBlank(username) || StringUtils.isBlank(password)) { 53 | throw new TipException("用户名和密码不能为空"); 54 | } 55 | UserVoExample example = new UserVoExample(); 56 | UserVoExample.Criteria criteria = example.createCriteria(); 57 | criteria.andUsernameEqualTo(username); 58 | long count = userDao.countByExample(example); 59 | if (count < 1) { 60 | throw new TipException("不存在该用户"); 61 | } 62 | String pwd = TaleUtils.MD5encode(username + password); 63 | criteria.andPasswordEqualTo(pwd); 64 | List userVos = userDao.selectByExample(example); 65 | if (userVos.size() != 1) { 66 | throw new TipException("用户名或密码错误"); 67 | } 68 | return userVos.get(0); 69 | } 70 | 71 | @Override 72 | @Transactional 73 | public void updateByUid(UserVo userVo) { 74 | if (null == userVo || null == userVo.getUid()) { 75 | throw new TipException("userVo is null"); 76 | } 77 | int i = userDao.updateByPrimaryKeySelective(userVo); 78 | if (i != 1) { 79 | throw new TipException("update user by uid and retrun is not one"); 80 | } 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/main/java/com/my/blog/website/utils/AdminCommons.java: -------------------------------------------------------------------------------- 1 | package com.my.blog.website.utils; 2 | 3 | 4 | import com.my.blog.website.model.Vo.MetaVo; 5 | import org.apache.commons.lang3.StringUtils; 6 | import org.springframework.stereotype.Component; 7 | 8 | /** 9 | * 后台公共函数 10 | *

11 | * Created by 13 on 2017/2/21. 12 | */ 13 | @Component 14 | public final class AdminCommons { 15 | 16 | /** 17 | * 判断category和cat的交集 18 | * 19 | * @param cats 20 | * @return 21 | */ 22 | public static boolean exist_cat(MetaVo category, String cats) { 23 | String[] arr = StringUtils.split(cats, ","); 24 | if (null != arr && arr.length > 0) { 25 | for (String c : arr) { 26 | if (c.trim().equals(category.getName())) { 27 | return true; 28 | } 29 | } 30 | } 31 | return false; 32 | } 33 | 34 | private static final String[] COLORS = {"default", "primary", "success", "info", "warning", "danger", "inverse", "purple", "pink"}; 35 | 36 | public static String rand_color() { 37 | int r = Tools.rand(0, COLORS.length - 1); 38 | return COLORS[r]; 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/com/my/blog/website/utils/GsonUtils.java: -------------------------------------------------------------------------------- 1 | package com.my.blog.website.utils; 2 | 3 | import com.google.gson.Gson; 4 | 5 | /** 6 | * json转换工具 7 | * Created by Administrator on 2017/3/13 013. 8 | */ 9 | public class GsonUtils { 10 | 11 | private static final Gson gson = new Gson(); 12 | 13 | public static String toJsonString(Object object){ 14 | return object==null?null:gson.toJson(object); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/com/my/blog/website/utils/IPKit.java: -------------------------------------------------------------------------------- 1 | package com.my.blog.website.utils; 2 | 3 | import javax.servlet.http.HttpServletRequest; 4 | import java.net.InetAddress; 5 | import java.net.NetworkInterface; 6 | import java.net.SocketException; 7 | import java.util.Enumeration; 8 | 9 | /** 10 | * ip工具类 11 | * Created by BlueT on 2017/3/9. 12 | */ 13 | public class IPKit { 14 | /** 15 | * @param request 请求 16 | * @return IP Address 17 | */ 18 | public static String getIpAddrByRequest(HttpServletRequest request) { 19 | String ip = request.getHeader("x-forwarded-for"); 20 | if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { 21 | ip = request.getHeader("Proxy-Client-IP"); 22 | } 23 | if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { 24 | ip = request.getHeader("WL-Proxy-Client-IP"); 25 | } 26 | if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { 27 | ip = request.getRemoteAddr(); 28 | } 29 | return ip; 30 | } 31 | 32 | /** 33 | * @return 本机IPSocketException 34 | * @throws SocketException 35 | */ 36 | public static String getRealIp() throws SocketException { 37 | String localip = null;// 本地IP,如果没有配置外网IP则返回它 38 | String netip = null;// 外网IP 39 | 40 | Enumeration netInterfaces = NetworkInterface.getNetworkInterfaces(); 41 | InetAddress ip = null; 42 | boolean finded = false;// 是否找到外网IP 43 | while (netInterfaces.hasMoreElements() && !finded) { 44 | NetworkInterface ni = netInterfaces.nextElement(); 45 | Enumeration address = ni.getInetAddresses(); 46 | while (address.hasMoreElements()) { 47 | ip = address.nextElement(); 48 | if (!ip.isSiteLocalAddress() && !ip.isLoopbackAddress() && !ip.getHostAddress().contains(":")) {// 外网IP 49 | netip = ip.getHostAddress(); 50 | finded = true; 51 | break; 52 | } else if (ip.isSiteLocalAddress() && !ip.isLoopbackAddress() && !ip.getHostAddress().contains(":")) {// 内网IP 53 | localip = ip.getHostAddress(); 54 | } 55 | } 56 | } 57 | 58 | if (netip != null && !"".equals(netip)) { 59 | return netip; 60 | } else { 61 | return localip; 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/main/java/com/my/blog/website/utils/LogAspect.java: -------------------------------------------------------------------------------- 1 | package com.my.blog.website.utils; 2 | 3 | import org.aspectj.lang.JoinPoint; 4 | import org.aspectj.lang.annotation.AfterReturning; 5 | import org.aspectj.lang.annotation.Aspect; 6 | import org.aspectj.lang.annotation.Before; 7 | import org.aspectj.lang.annotation.Pointcut; 8 | import org.slf4j.Logger; 9 | import org.slf4j.LoggerFactory; 10 | import org.springframework.stereotype.Component; 11 | import org.springframework.web.context.request.RequestContextHolder; 12 | import org.springframework.web.context.request.ServletRequestAttributes; 13 | 14 | import javax.servlet.http.HttpServletRequest; 15 | import java.util.Arrays; 16 | 17 | @Aspect 18 | @Component 19 | public class LogAspect { 20 | private static final Logger LOGGER = LoggerFactory.getLogger(LogAspect.class); 21 | 22 | @Pointcut("execution(public * com.my.blog.website.controller..*.*(..))") 23 | public void webLog() { 24 | } 25 | 26 | @Before("webLog()") 27 | public void doBefore(JoinPoint joinPoint) { 28 | // 接收到请求,记录请求内容 29 | ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); 30 | HttpServletRequest request = attributes.getRequest(); 31 | // 记录下请求内容 32 | LOGGER.info("URL : " + request.getRequestURL().toString() + ",IP : " + request.getRemoteAddr() + ",CLASS_METHOD : " + joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName() + ",ARGS : " + Arrays.toString(joinPoint.getArgs())); 33 | } 34 | 35 | @AfterReturning(returning = "object", pointcut = "webLog()") 36 | public void doAfterReturning(Object object) { 37 | // 处理完请求,返回内容 38 | LOGGER.info("RESPONSE : " + object); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/com/my/blog/website/utils/MapCache.java: -------------------------------------------------------------------------------- 1 | package com.my.blog.website.utils; 2 | 3 | import java.util.Map; 4 | import java.util.concurrent.ConcurrentHashMap; 5 | 6 | /** 7 | * map缓存实现 8 | *

9 | * Created by 13 on 2017/2/7. 10 | */ 11 | public class MapCache { 12 | 13 | /** 14 | * 默认存储1024个缓存 15 | */ 16 | private static final int DEFAULT_CACHES = 1024; 17 | 18 | private static final MapCache INS = new MapCache(); 19 | 20 | public static MapCache single() { 21 | return INS; 22 | } 23 | 24 | /** 25 | * 缓存容器 26 | */ 27 | private Map cachePool; 28 | 29 | public MapCache() { 30 | this(DEFAULT_CACHES); 31 | } 32 | 33 | public MapCache(int cacheCount) { 34 | cachePool = new ConcurrentHashMap<>(cacheCount); 35 | } 36 | 37 | /** 38 | * 读取一个缓存 39 | * 40 | * @param key 缓存key 41 | * @param 42 | * @return 43 | */ 44 | public T get(String key) { 45 | CacheObject cacheObject = cachePool.get(key); 46 | if (null != cacheObject) { 47 | long cur = System.currentTimeMillis() / 1000; 48 | //未过期直接返回 49 | if (cacheObject.getExpired() <= 0 || cacheObject.getExpired() > cur) { 50 | Object result = cacheObject.getValue(); 51 | return (T) result; 52 | } 53 | //已过期直接删除 54 | if (cur > cacheObject.getExpired()) { 55 | cachePool.remove(key); 56 | } 57 | } 58 | return null; 59 | } 60 | 61 | /** 62 | * 读取一个hash类型缓存 63 | * 64 | * @param key 缓存key 65 | * @param field 缓存field 66 | * @param 67 | * @return 68 | */ 69 | public T hget(String key, String field) { 70 | key = key + ":" + field; 71 | return this.get(key); 72 | } 73 | 74 | /** 75 | * 设置一个缓存 76 | * 77 | * @param key 缓存key 78 | * @param value 缓存value 79 | */ 80 | public void set(String key, Object value) { 81 | this.set(key, value, -1); 82 | } 83 | 84 | /** 85 | * 设置一个缓存并带过期时间 86 | * 87 | * @param key 缓存key 88 | * @param value 缓存value 89 | * @param expired 过期时间,单位为秒 90 | */ 91 | public void set(String key, Object value, long expired) { 92 | expired = expired > 0 ? System.currentTimeMillis() / 1000 + expired : expired; 93 | //cachePool大于800时,强制清空缓存池,这个操作有些粗暴会导致误删问题,后期考虑用redis替代MapCache优化 94 | if (cachePool.size() > 800) { 95 | cachePool.clear(); 96 | } 97 | CacheObject cacheObject = new CacheObject(key, value, expired); 98 | cachePool.put(key, cacheObject); 99 | } 100 | 101 | /** 102 | * 设置一个hash缓存 103 | * 104 | * @param key 缓存key 105 | * @param field 缓存field 106 | * @param value 缓存value 107 | */ 108 | public void hset(String key, String field, Object value) { 109 | this.hset(key, field, value, -1); 110 | } 111 | 112 | /** 113 | * 设置一个hash缓存并带过期时间 114 | * 115 | * @param key 缓存key 116 | * @param field 缓存field 117 | * @param value 缓存value 118 | * @param expired 过期时间,单位为秒 119 | */ 120 | public void hset(String key, String field, Object value, long expired) { 121 | key = key + ":" + field; 122 | expired = expired > 0 ? System.currentTimeMillis() / 1000 + expired : expired; 123 | CacheObject cacheObject = new CacheObject(key, value, expired); 124 | cachePool.put(key, cacheObject); 125 | } 126 | 127 | /** 128 | * 根据key删除缓存 129 | * 130 | * @param key 缓存key 131 | */ 132 | public void del(String key) { 133 | cachePool.remove(key); 134 | } 135 | 136 | /** 137 | * 根据key和field删除缓存 138 | * 139 | * @param key 缓存key 140 | * @param field 缓存field 141 | */ 142 | public void hdel(String key, String field) { 143 | key = key + ":" + field; 144 | this.del(key); 145 | } 146 | 147 | /** 148 | * 清空缓存 149 | */ 150 | public void clean() { 151 | cachePool.clear(); 152 | } 153 | 154 | static class CacheObject { 155 | private String key; 156 | private Object value; 157 | private long expired; 158 | 159 | public CacheObject(String key, Object value, long expired) { 160 | this.key = key; 161 | this.value = value; 162 | this.expired = expired; 163 | } 164 | 165 | public String getKey() { 166 | return key; 167 | } 168 | 169 | public Object getValue() { 170 | return value; 171 | } 172 | 173 | public long getExpired() { 174 | return expired; 175 | } 176 | } 177 | } -------------------------------------------------------------------------------- /src/main/java/com/my/blog/website/utils/Tools.java: -------------------------------------------------------------------------------- 1 | package com.my.blog.website.utils; 2 | 3 | import java.io.File; 4 | import java.io.FileInputStream; 5 | import java.io.FileOutputStream; 6 | import java.io.IOException; 7 | import java.nio.channels.FileChannel; 8 | import java.util.Random; 9 | import javax.crypto.Cipher; 10 | import javax.crypto.spec.SecretKeySpec; 11 | 12 | import sun.misc.BASE64Decoder; 13 | import sun.misc.BASE64Encoder; 14 | 15 | /** 16 | * 工具类 17 | * Created by BlueT on 2017/3/9. 18 | */ 19 | public class Tools { 20 | private static final Random random = new Random(); 21 | 22 | public static void copyFileUsingFileChannels(File source, File dest) throws IOException { 23 | FileChannel inputChannel = null; 24 | FileChannel outputChannel = null; 25 | try { 26 | inputChannel = new FileInputStream(source).getChannel(); 27 | outputChannel = new FileOutputStream(dest).getChannel(); 28 | outputChannel.transferFrom(inputChannel, 0, inputChannel.size()); 29 | } finally { 30 | assert inputChannel != null; 31 | inputChannel.close(); 32 | assert outputChannel != null; 33 | outputChannel.close(); 34 | } 35 | } 36 | 37 | public static int rand(int min, int max) { 38 | return random.nextInt(max) % (max - min + 1) + min; 39 | } 40 | 41 | public static String flowAutoShow(double value) { 42 | // Math.round 方法接收 float 和 double 类型,如果参数是 int 的话,会强转为 float,这个时候调用该方法无意义 43 | int kb = 1024; 44 | int mb = 1048576; 45 | int gb = 1073741824; 46 | double abs = Math.abs(value); 47 | if (abs > gb) { 48 | return Math.round(value / gb) + "GB"; 49 | } else if (abs > mb) { 50 | return Math.round(value / mb) + "MB"; 51 | } else if (abs > kb) { 52 | return Math.round(value / kb) + "KB"; 53 | } 54 | return Math.round(value) + ""; 55 | } 56 | 57 | public static String enAes(String data, String key) throws Exception { 58 | Cipher cipher = Cipher.getInstance("AES"); 59 | SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes("UTF-8"), "AES"); 60 | cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec); 61 | byte[] encryptedBytes = cipher.doFinal(data.getBytes()); 62 | return new BASE64Encoder().encode(encryptedBytes); 63 | } 64 | 65 | public static String deAes(String data, String key) throws Exception { 66 | Cipher cipher = Cipher.getInstance("AES"); 67 | SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes("UTF-8"), "AES"); 68 | cipher.init(Cipher.DECRYPT_MODE, secretKeySpec); 69 | byte[] cipherTextBytes = new BASE64Decoder().decodeBuffer(data); 70 | byte[] decValue = cipher.doFinal(cipherTextBytes); 71 | return new String(decValue); 72 | } 73 | 74 | /** 75 | * 判断字符串是否为数字和有正确的值 76 | * 77 | * @param str 78 | * @return 79 | */ 80 | public static boolean isNumber(String str) { 81 | // Pattern pattern=Pattern.compile("[0-9]*"); 82 | // return pattern.matcher(str).matches(); 83 | if (null != str && 0 != str.trim().length() && str.matches("\\d*")) { 84 | return true; 85 | } 86 | 87 | return false; 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /src/main/java/com/my/blog/website/utils/ZipUtils.java: -------------------------------------------------------------------------------- 1 | package com.my.blog.website.utils; 2 | 3 | import java.io.File; 4 | import java.io.FileInputStream; 5 | import java.io.FileOutputStream; 6 | import java.util.zip.ZipEntry; 7 | import java.util.zip.ZipOutputStream; 8 | 9 | /** 10 | * zip压缩工具类 11 | */ 12 | public class ZipUtils { 13 | 14 | public static void zipFolder(String srcFolder, String destZipFile) throws Exception { 15 | ZipOutputStream zip = null; 16 | FileOutputStream fileWriter = null; 17 | 18 | fileWriter = new FileOutputStream(destZipFile); 19 | zip = new ZipOutputStream(fileWriter); 20 | 21 | addFolderToZip("", srcFolder, zip); 22 | zip.flush(); 23 | zip.close(); 24 | } 25 | 26 | public static void zipFile(String filePath, String zipPath) throws Exception{ 27 | byte[] buffer = new byte[1024]; 28 | FileOutputStream fos = new FileOutputStream(zipPath); 29 | ZipOutputStream zos = new ZipOutputStream(fos); 30 | ZipEntry ze= new ZipEntry("spy.log"); 31 | zos.putNextEntry(ze); 32 | FileInputStream in = new FileInputStream(filePath); 33 | int len; 34 | while ((len = in.read(buffer)) > 0) { 35 | zos.write(buffer, 0, len); 36 | } 37 | in.close(); 38 | zos.closeEntry(); 39 | //remember close it 40 | zos.close(); 41 | } 42 | 43 | public static void addFileToZip(String path, String srcFile, ZipOutputStream zip) 44 | throws Exception { 45 | 46 | File folder = new File(srcFile); 47 | if (folder.isDirectory()) { 48 | addFolderToZip(path, srcFile, zip); 49 | } else { 50 | byte[] buf = new byte[1024]; 51 | int len; 52 | FileInputStream in = new FileInputStream(srcFile); 53 | zip.putNextEntry(new ZipEntry(path + "/" + folder.getName())); 54 | while ((len = in.read(buf)) > 0) { 55 | zip.write(buf, 0, len); 56 | } 57 | } 58 | } 59 | 60 | public static void addFolderToZip(String path, String srcFolder, ZipOutputStream zip) throws Exception { 61 | File folder = new File(srcFolder); 62 | if (null != path && folder.isDirectory()) { 63 | String[] fileList = folder.list(); 64 | if (fileList != null) { 65 | for (String fileName : fileList) { 66 | if (path.equals("")) { 67 | addFileToZip(folder.getName(), srcFolder + "/" + fileName, zip); 68 | } else { 69 | addFileToZip(path + "/" + folder.getName(), srcFolder + "/" + fileName, zip); 70 | } 71 | } 72 | } 73 | } 74 | } 75 | 76 | } -------------------------------------------------------------------------------- /src/main/java/com/my/blog/website/utils/backup/Column.java: -------------------------------------------------------------------------------- 1 | package com.my.blog.website.utils.backup; 2 | 3 | public class Column { 4 | private String name; 5 | private String typeName; 6 | private int dataType; 7 | 8 | public String getName() { 9 | return name; 10 | } 11 | 12 | public int getDataType() { 13 | return dataType; 14 | } 15 | 16 | public Column(String name, String typeName, int dataType) { 17 | super(); 18 | this.name = name; 19 | this.typeName = typeName; 20 | this.dataType = dataType; 21 | } 22 | 23 | @Override 24 | public String toString() { 25 | return "Column [name=" + name + ", typeName=" + typeName 26 | + ", dataType=" + dataType + "]"; 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/com/my/blog/website/utils/backup/ColumnCollection.java: -------------------------------------------------------------------------------- 1 | package com.my.blog.website.utils.backup; 2 | 3 | import java.util.ArrayList; 4 | 5 | public class ColumnCollection extends ArrayList{ 6 | 7 | /** 8 | * 9 | */ 10 | private static final long serialVersionUID = -4983492395879238027L; 11 | 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/com/my/blog/website/utils/backup/FK.java: -------------------------------------------------------------------------------- 1 | package com.my.blog.website.utils.backup; 2 | 3 | public class FK { 4 | private String column; 5 | private Table referenceTable; 6 | private String referencePK; 7 | 8 | public Table getReferenceTable() { 9 | return referenceTable; 10 | } 11 | 12 | public FK(String column, Table referenceTable, String referencePK) { 13 | this.column = column; 14 | this.referenceTable = referenceTable; 15 | this.referencePK = referencePK; 16 | } 17 | 18 | @Override 19 | public String toString() { 20 | return "FK [column=" + column + ", referenceTable=" + referenceTable 21 | + ", referencePK=" + referencePK + "]"; 22 | } 23 | 24 | 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/com/my/blog/website/utils/backup/FKCollection.java: -------------------------------------------------------------------------------- 1 | package com.my.blog.website.utils.backup; 2 | 3 | import java.util.ArrayList; 4 | 5 | public class FKCollection extends ArrayList{ 6 | 7 | /** 8 | * 9 | */ 10 | private static final long serialVersionUID = -972085209611643212L; 11 | 12 | public boolean isReferenced(Table referenceTable){ 13 | for(FK fk : this){ 14 | if(fk.getReferenceTable().equals(referenceTable)){ 15 | return true; 16 | } 17 | } 18 | return false; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/com/my/blog/website/utils/backup/Table.java: -------------------------------------------------------------------------------- 1 | package com.my.blog.website.utils.backup; 2 | 3 | 4 | public class Table { 5 | private String name; 6 | private ColumnCollection columns; 7 | private FKCollection constraints; 8 | 9 | public String getName() { 10 | return name; 11 | } 12 | 13 | public Table(String name) { 14 | this.name = name; 15 | this.columns = new ColumnCollection(); 16 | this.constraints = new FKCollection(); 17 | } 18 | 19 | public ColumnCollection getColumns() { 20 | return columns; 21 | } 22 | 23 | public FKCollection getConstraints() { 24 | return constraints; 25 | } 26 | 27 | @Override 28 | public String toString() { 29 | return "Table [name=" + name + "]"; 30 | } 31 | 32 | public boolean isReferenced(Table referenceTable){ 33 | return constraints.isReferenced(referenceTable); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/com/my/blog/website/utils/backup/TableCollection.java: -------------------------------------------------------------------------------- 1 | package com.my.blog.website.utils.backup; 2 | 3 | import java.util.ArrayList; 4 | 5 | public class TableCollection extends ArrayList { 6 | 7 | /** 8 | * 9 | */ 10 | private static final long serialVersionUID = -5824322959198795936L; 11 | 12 | /** 13 | * Sort tables according to constraints 14 | */ 15 | public void sort(){ 16 | for(int i = 0 ; i < size(); ){ 17 | boolean corrupted = false; 18 | for(int j = i + 1; j < size(); j++){ 19 | if(get(i).isReferenced(get(j))){ 20 | Table table = get(i); 21 | remove(table); 22 | add(table); 23 | corrupted = true; 24 | break; 25 | } 26 | } 27 | if(!corrupted){ 28 | i++; 29 | } 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/com/my/blog/website/utils/backup/db/Column.java: -------------------------------------------------------------------------------- 1 | package com.my.blog.website.utils.backup.db; 2 | 3 | public class Column { 4 | private String catalogName; 5 | private String schemaName; 6 | private String tableName; 7 | private String name; 8 | private String label; 9 | private int type; 10 | private String typeName; 11 | private String columnClassName; 12 | private int displaySize; 13 | private int precision; 14 | private int scale; 15 | 16 | public String getName() { 17 | return name; 18 | } 19 | 20 | public String getLabel() { 21 | return label; 22 | } 23 | 24 | public int getType() { 25 | return type; 26 | } 27 | 28 | public void setCatalogName(String catalogName) { 29 | this.catalogName = catalogName; 30 | } 31 | 32 | public void setSchemaName(String schemaName) { 33 | this.schemaName = schemaName; 34 | } 35 | 36 | public void setTableName(String tableName) { 37 | this.tableName = tableName; 38 | } 39 | 40 | public void setName(String name) { 41 | this.name = name; 42 | } 43 | 44 | public void setLabel(String label) { 45 | this.label = label; 46 | } 47 | 48 | public void setType(int type) { 49 | this.type = type; 50 | } 51 | 52 | public void setTypeName(String typeName) { 53 | this.typeName = typeName; 54 | } 55 | 56 | public void setColumnClassName(String columnClassName) { 57 | this.columnClassName = columnClassName; 58 | } 59 | 60 | public void setDisplaySize(int displaySize) { 61 | this.displaySize = displaySize; 62 | } 63 | 64 | public void setPrecision(int precision) { 65 | this.precision = precision; 66 | } 67 | 68 | public void setScale(int scale) { 69 | this.scale = scale; 70 | } 71 | 72 | @Override 73 | public String toString() { 74 | return "Column [catalogName=" + catalogName + ", schemaName=" 75 | + schemaName + ", tableName=" + tableName + ", name=" + name 76 | + ", label=" + label + ", type=" + type + ", typeName=" 77 | + typeName + ", columnClassName=" + columnClassName 78 | + ", displaySize=" + displaySize + ", precision=" + precision 79 | + ", scale=" + scale + "]"; 80 | } 81 | 82 | 83 | } 84 | -------------------------------------------------------------------------------- /src/main/java/com/my/blog/website/utils/backup/db/ColumnCollection.java: -------------------------------------------------------------------------------- 1 | package com.my.blog.website.utils.backup.db; 2 | 3 | import java.util.ArrayList; 4 | 5 | public class ColumnCollection extends ArrayList{ 6 | 7 | private static final long serialVersionUID = -3399188477563370223L; 8 | 9 | public int indexByLabel(String label){ 10 | for(int i = 0; i < this.size(); i++){ 11 | if(get(i).getLabel().equals(label)){ 12 | return i; 13 | } 14 | } 15 | return -1; 16 | } 17 | 18 | @Override 19 | public String toString() { 20 | if(size() == 0){ 21 | return "Columns is empty"; 22 | } 23 | String s = "Columns : {" + String.valueOf(get(0).getLabel()); 24 | for(int i = 1; i < size(); i++){ 25 | s += ", " + String.valueOf(get(i).getLabel()); 26 | } 27 | s += "}"; 28 | return s; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/com/my/blog/website/utils/backup/db/DataTable.java: -------------------------------------------------------------------------------- 1 | package com.my.blog.website.utils.backup.db; 2 | 3 | import java.sql.Connection; 4 | import java.sql.ResultSet; 5 | import java.sql.ResultSetMetaData; 6 | import java.sql.SQLException; 7 | import java.util.ArrayList; 8 | 9 | public class DataTable extends ArrayList { 10 | /** 11 | * 12 | */ 13 | private static final long serialVersionUID = -3057968190529400383L; 14 | 15 | public static DataTable execute(Connection connection, String query) 16 | throws SQLException { 17 | return parse(connection.prepareStatement(query).executeQuery()); 18 | } 19 | 20 | public static DataTable parse(ResultSet resultSet) throws SQLException { 21 | ResultSetMetaData metaData = resultSet.getMetaData(); 22 | DataTable dataTable = new DataTable(); 23 | dataTable.columns = new ColumnCollection(); 24 | 25 | int colCount = metaData.getColumnCount(); 26 | for (int i = 1; i <= colCount; i++) { 27 | Column column = new Column(); 28 | column.setCatalogName(metaData.getCatalogName(i)); 29 | column.setColumnClassName(metaData.getColumnClassName(i)); 30 | column.setDisplaySize(metaData.getColumnDisplaySize(i)); 31 | column.setLabel(metaData.getColumnLabel(i)); 32 | column.setName(metaData.getColumnName(i)); 33 | column.setPrecision(metaData.getPrecision(i)); 34 | column.setScale(metaData.getScale(i)); 35 | column.setSchemaName(metaData.getSchemaName(i)); 36 | column.setTableName(metaData.getTableName(i)); 37 | column.setType(metaData.getColumnType(i)); 38 | column.setTypeName(metaData.getColumnTypeName(i)); 39 | dataTable.columns.add(column); 40 | } 41 | 42 | while (resultSet.next()) { 43 | Object[] data = new Object[colCount]; 44 | for (int i = 1; i <= data.length; i++) { 45 | data[i - 1] = resultSet.getObject(i); 46 | } 47 | dataTable.add(new Row(dataTable, data)); 48 | } 49 | resultSet.close(); 50 | return dataTable; 51 | } 52 | 53 | private ColumnCollection columns; 54 | 55 | public ColumnCollection getColumns() { 56 | return columns; 57 | } 58 | 59 | @Override 60 | public String toString() { 61 | String s = columns.toString() + "\n"; 62 | if (size() == 0) { 63 | s += "Rows is empty\n"; 64 | } else { 65 | s += "Rows : {" + String.valueOf(get(0)); 66 | for (int i = 1; i < size(); i++) { 67 | s += "\n" + String.valueOf(get(i)); 68 | } 69 | s += "}\n"; 70 | } 71 | return s; 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /src/main/java/com/my/blog/website/utils/backup/db/Row.java: -------------------------------------------------------------------------------- 1 | package com.my.blog.website.utils.backup.db; 2 | 3 | import java.util.Date; 4 | 5 | public class Row { 6 | private Object[] data; 7 | private DataTable dataTable; 8 | 9 | public Row(DataTable dataTable, Object[] data) { 10 | this.dataTable = dataTable; 11 | this.data = data; 12 | } 13 | 14 | public Object get(String columnLabel) { 15 | return get(dataTable.getColumns().indexByLabel(columnLabel)); 16 | } 17 | 18 | public Object get(int index) { 19 | return data[index]; 20 | } 21 | 22 | public String getString(int index) { 23 | return String.valueOf(get(index)); 24 | } 25 | 26 | public String getString(String label) { 27 | return String.valueOf(get(label)); 28 | } 29 | 30 | public Integer getInteger(String label) { 31 | return (Integer) (get(label)); 32 | } 33 | 34 | public Date getDate(int index) { 35 | return (Date) get(index); 36 | } 37 | 38 | @Override 39 | public String toString() { 40 | if (data == null || data.length == 0) { 41 | return "{}"; 42 | } 43 | String s = "{" + String.valueOf(data[0]); 44 | for (int i = 1; i < data.length; i++) { 45 | s += ", " + String.valueOf(data[i]); 46 | } 47 | s += "}"; 48 | return s; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 8080 3 | 4 | spring: 5 | datasource: 6 | driverClassName: com.mysql.jdbc.Driver 7 | maxActive: 80 8 | minIdle: 5 9 | username: root 10 | password: jason 11 | url: jdbc:mysql://127.0.0.1:3306/tale?useSSL=false&useUnicode=true&characterEncoding=utf-8 12 | 13 | 14 | thymeleaf: 15 | cache: false 16 | check-template-location: true 17 | content-type: text/html 18 | encoding: UTF-8 19 | mode: HTML5 20 | prefix: classpath:/templates/ 21 | suffix: .html 22 | 23 | 24 | mybatis: 25 | mapper-locations: classpath:mapper/*.xml 26 | type-aliases-package: com.my.blog.website.dto, com.my.blog.website.model 27 | configuration: 28 | map-underscore-to-camel-case: true 29 | 30 | 31 | pagehelper: 32 | helperDialect: mysql 33 | params: count=countSql 34 | reasonable: true 35 | support-methods-arguments: true -------------------------------------------------------------------------------- /src/main/resources/log4j2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | ./logs 11 | %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /src/main/resources/static/admin/images/attach.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jsbintask22/blog/dfa376cf15e7b556baf7a90db1f59d6a364fe5bc/src/main/resources/static/admin/images/attach.png -------------------------------------------------------------------------------- /src/main/resources/static/admin/images/bg/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jsbintask22/blog/dfa376cf15e7b556baf7a90db1f59d6a364fe5bc/src/main/resources/static/admin/images/bg/1.png -------------------------------------------------------------------------------- /src/main/resources/static/admin/images/bg/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jsbintask22/blog/dfa376cf15e7b556baf7a90db1f59d6a364fe5bc/src/main/resources/static/admin/images/bg/2.png -------------------------------------------------------------------------------- /src/main/resources/static/admin/images/bg/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jsbintask22/blog/dfa376cf15e7b556baf7a90db1f59d6a364fe5bc/src/main/resources/static/admin/images/bg/3.png -------------------------------------------------------------------------------- /src/main/resources/static/admin/images/bg/4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jsbintask22/blog/dfa376cf15e7b556baf7a90db1f59d6a364fe5bc/src/main/resources/static/admin/images/bg/4.png -------------------------------------------------------------------------------- /src/main/resources/static/admin/images/bg/5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jsbintask22/blog/dfa376cf15e7b556baf7a90db1f59d6a364fe5bc/src/main/resources/static/admin/images/bg/5.png -------------------------------------------------------------------------------- /src/main/resources/static/admin/images/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jsbintask22/blog/dfa376cf15e7b556baf7a90db1f59d6a364fe5bc/src/main/resources/static/admin/images/favicon.png -------------------------------------------------------------------------------- /src/main/resources/static/admin/images/loading.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jsbintask22/blog/dfa376cf15e7b556baf7a90db1f59d6a364fe5bc/src/main/resources/static/admin/images/loading.gif -------------------------------------------------------------------------------- /src/main/resources/static/admin/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jsbintask22/blog/dfa376cf15e7b556baf7a90db1f59d6a364fe5bc/src/main/resources/static/admin/images/logo.png -------------------------------------------------------------------------------- /src/main/resources/static/admin/images/small/bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jsbintask22/blog/dfa376cf15e7b556baf7a90db1f59d6a364fe5bc/src/main/resources/static/admin/images/small/bg.jpg -------------------------------------------------------------------------------- /src/main/resources/static/admin/js/article.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by 13 on 2017/2/22. 3 | */ 4 | // Tags Input 5 | $('#tags').tagsInput({ 6 | width: '100%', 7 | height: '35px', 8 | defaultText: '请输入文章标签' 9 | }); 10 | 11 | $('.toggle').toggles({ 12 | on: true, 13 | text: { 14 | on: '开启', 15 | off: '关闭' 16 | } 17 | }); 18 | 19 | $(".select2").select2({ 20 | width: '100%' 21 | }); 22 | 23 | var tale = new $.tale(); 24 | 25 | /** 26 | * 保存文章 27 | * @param status 28 | */ 29 | function subArticle(status) { 30 | var title = $('#articleForm input[name=title]').val(); 31 | var content = $('#text').val(); 32 | if (title == '') { 33 | tale.alertWarn('请输入文章标题'); 34 | return; 35 | } 36 | if (content == '') { 37 | tale.alertWarn('请输入文章内容'); 38 | return; 39 | } 40 | $('#content-editor').val(content); 41 | $("#articleForm #status").val(status); 42 | $("#articleForm #categories").val($('#multiple-sel').val()); 43 | var params = $("#articleForm").serialize(); 44 | var url = $('#articleForm #cid').val() != '' ? '/admin/article/modify' : '/admin/article/publish'; 45 | tale.post({ 46 | url:url, 47 | data:params, 48 | success: function (result) { 49 | if (result && result.success) { 50 | tale.alertOk({ 51 | text:'文章保存成功', 52 | then: function () { 53 | setTimeout(function () { 54 | window.location.href = '/admin/article'; 55 | }, 500); 56 | } 57 | }); 58 | } else { 59 | tale.alertError(result.msg || '保存文章失败'); 60 | } 61 | } 62 | }); 63 | } 64 | 65 | var textarea = $('#text'), 66 | toolbar = $('
').insertBefore(textarea.parent()) 67 | preview = $('
').insertAfter('.markdown-editor'); 68 | 69 | markdown(textarea, toolbar, preview); 70 | 71 | 72 | function allow_comment(obj) { 73 | var this_ = $(obj); 74 | var on = this_.find('.toggle-on.active').length; 75 | var off = this_.find('.toggle-off.active').length; 76 | if (on == 1) { 77 | $('#allow_comment').val(false); 78 | } 79 | if (off == 1) { 80 | $('#allow_comment').val(true); 81 | } 82 | } 83 | 84 | function allow_ping(obj) { 85 | var this_ = $(obj); 86 | var on = this_.find('.toggle-on.active').length; 87 | var off = this_.find('.toggle-off.active').length; 88 | if (on == 1) { 89 | $('#allow_ping').val(false); 90 | } 91 | if (off == 1) { 92 | $('#allow_ping').val(true); 93 | } 94 | } 95 | 96 | 97 | function allow_feed(obj) { 98 | var this_ = $(obj); 99 | var on = this_.find('.toggle-on.active').length; 100 | var off = this_.find('.toggle-off.active').length; 101 | if (on == 1) { 102 | $('#allow_feed').val(false); 103 | } 104 | if (off == 1) { 105 | $('#allow_feed').val(true); 106 | } 107 | } 108 | 109 | $('div.allow-false').toggles({ 110 | off: true, 111 | text: { 112 | on: '开启', 113 | off: '关闭' 114 | } 115 | }); -------------------------------------------------------------------------------- /src/main/resources/static/admin/js/base.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Tale全局函数对象 var tale = new $.tale(); 3 | */ 4 | $.extend({ 5 | tale: function () { 6 | } 7 | }); 8 | 9 | /** 10 | * tale alert删除 // todo: 减少耦合度,链式操作替代 2017-02-27 11 | * @param options 12 | */ 13 | // $.tale.prototype.alert_del = function (options) { 14 | // swal({ 15 | // title: options.title || '警告信息', 16 | // text: options.text || "确定删除吗?", 17 | // type: 'warning', 18 | // showCancelButton: true, 19 | // confirmButtonColor: '#3085d6', 20 | // cancelButtonColor: '#d33', 21 | // confirmButtonText: '确定', 22 | // cancelButtonText: '取消' 23 | // }).then(function () { 24 | // $.post(options.url, options.parame, function (result) { 25 | // if (result && result.success) { 26 | // swal('提示信息', '删除成功', 'success'); 27 | // setTimeout(function () { 28 | // window.location.reload(); 29 | // }, 2000); 30 | // } else { 31 | // swal("提示消息", result.msg, 'error'); 32 | // } 33 | // }); 34 | // }).catch(swal.noop); 35 | // }; 36 | 37 | /** 38 | * 成功弹框 39 | * @param options 40 | */ 41 | $.tale.prototype.alertOk = function (options) { 42 | options = options.length ? {text:options} : ( options || {} ); 43 | options.title = options.title || '操作成功'; 44 | options.text = options.text; 45 | options.showCancelButton = false; 46 | options.showCloseButton = false; 47 | options.type = 'success'; 48 | this.alertBox(options); 49 | }; 50 | 51 | /** 52 | * 弹出成功,并在500毫秒后刷新页面 53 | * @param text 54 | */ 55 | $.tale.prototype.alertOkAndReload = function (text) { 56 | this.alertOk({text:text, then:function () { 57 | setTimeout(function () { 58 | window.location.reload(); 59 | }, 500); 60 | }}); 61 | }; 62 | 63 | /** 64 | * 警告弹框 65 | * @param options 66 | */ 67 | $.tale.prototype.alertWarn = function (options) { 68 | options = options.length ? {text:options} : ( options || {} ); 69 | options.title = options.title || '警告信息'; 70 | options.text = options.text; 71 | options.timer = 3000; 72 | options.type = 'warning'; 73 | this.alertBox(options); 74 | }; 75 | 76 | /** 77 | * 询问确认弹框,这里会传入then函数进来 78 | * @param options 79 | */ 80 | $.tale.prototype.alertConfirm = function (options) { 81 | options = options || {}; 82 | options.title = options.title || '确定要删除吗?'; 83 | options.text = options.text; 84 | options.showCancelButton = true; 85 | options.type = 'question'; 86 | this.alertBox(options); 87 | }; 88 | 89 | /** 90 | * 错误提示 91 | * @param options 92 | */ 93 | $.tale.prototype.alertError = function (options) { 94 | options = options.length ? {text:options} : ( options || {} ); 95 | options.title = options.title || '错误信息'; 96 | options.text = options.text; 97 | options.type = 'error'; 98 | this.alertBox(options); 99 | }; 100 | 101 | /** 102 | * 公共弹框 103 | * @param options 104 | */ 105 | $.tale.prototype.alertBox = function (options) { 106 | swal({ 107 | title: options.title, 108 | text: options.text, 109 | type: options.type, 110 | timer: options.timer || 9999, 111 | showCloseButton: options.showCloseButton, 112 | showCancelButton: options.showCancelButton, 113 | showLoaderOnConfirm: options.showLoaderOnConfirm || false, 114 | confirmButtonColor: options.confirmButtonColor || '#3085d6', 115 | cancelButtonColor: options.cancelButtonColor || '#d33', 116 | confirmButtonText: options.confirmButtonText || '确定', 117 | cancelButtonText: options.cancelButtonText || '取消' 118 | }).then(function (e) { 119 | options.then && options.then(e); 120 | }).catch(swal.noop); 121 | }; 122 | 123 | /** 124 | * 全局post函数 125 | * 126 | * @param options 参数 127 | */ 128 | $.tale.prototype.post = function (options) { 129 | var self = this; 130 | $.ajax({ 131 | type: 'POST', 132 | url: options.url, 133 | data: options.data || {}, 134 | async: options.async || false, 135 | dataType: 'json', 136 | success: function (result) { 137 | self.hideLoading(); 138 | options.success && options.success(result); 139 | }, 140 | error: function () { 141 | // 142 | } 143 | }); 144 | }; 145 | 146 | /** 147 | * 显示动画 148 | */ 149 | $.tale.prototype.showLoading = function () { 150 | if ($('#tale-loading').length == 0) { 151 | $('body').append('
'); 152 | } 153 | $('#tale-loading').show(); 154 | }; 155 | 156 | /** 157 | * 隐藏动画 158 | */ 159 | $.tale.prototype.hideLoading = function () { 160 | $('#tale-loading') && $('#tale-loading').hide(); 161 | }; -------------------------------------------------------------------------------- /src/main/resources/static/admin/js/install.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by 13 on 2017/2/23. 3 | */ 4 | !function ($) { 5 | "use strict"; 6 | var tale = new $.tale(); 7 | var FormWizard = function () { 8 | }; 9 | //creates form with validation 10 | FormWizard.prototype.init = function () { 11 | var $form_container = $("#wizard-validation-form"); 12 | $form_container.validate({ 13 | errorPlacement: function errorPlacement(error, element) { 14 | element.after(error); 15 | } 16 | }); 17 | $("#steps").steps({ 18 | headerTag: "h3", 19 | bodyTag: "section", 20 | transitionEffect: "fade", 21 | labels: { 22 | previous: "上一步", 23 | next: "下一步", 24 | finish: "登录后台", 25 | loading: '加载中...', 26 | current: '当前位置' 27 | }, 28 | onStepChanging: function (event, currentIndex, newIndex) { 29 | tale.showLoading(); 30 | $form_container.validate().settings.ignore = ":disabled,:hidden"; 31 | var isValid=true; 32 | if(newIndex!=0){ 33 | isValid = $form_container.valid(); 34 | if(!isValid){ 35 | tale.hideLoading(); 36 | } 37 | } 38 | if (isValid && currentIndex == 1&&newIndex==2) { 39 | isValid = false; 40 | var params = $form_container.serialize(); 41 | tale.post({ 42 | url: '/install/testCon', 43 | data: params, 44 | success: function (result) { 45 | if (result && result.success) { 46 | tale.showLoading(); 47 | tale.post({ 48 | url: '/install', 49 | data: params, 50 | success: function (result) { 51 | if (result && result.success) { 52 | isValid = true; 53 | } else { 54 | if (result.msg) { 55 | tale.alertError(result.msg || '安装失败'); 56 | } 57 | } 58 | } 59 | }); 60 | } else { 61 | tale.alertError(result.msg || '测试连接失败'); 62 | } 63 | } 64 | }); 65 | return isValid; 66 | } else { 67 | tale.hideLoading(); 68 | return isValid; 69 | } 70 | }, 71 | onStepChanged: function (event, currentIndex) { 72 | tale.hideLoading(); 73 | }, 74 | onFinishing: function (event, currentIndex) { 75 | $form_container.validate().settings.ignore = ":disabled"; 76 | var isValid = $form_container.valid(); 77 | window.location.href = "/admin/login"; 78 | return isValid; 79 | }, 80 | onFinished: function (event, currentIndex) { 81 | window.location.href = "/admin/login"; 82 | } 83 | }); 84 | return $form_container; 85 | }, 86 | //init 87 | $.FormWizard = new FormWizard, $.FormWizard.Constructor = FormWizard 88 | }(window.jQuery), $.FormWizard.init(); -------------------------------------------------------------------------------- /src/main/resources/static/admin/plugins/jquery-multi-select/img/switch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jsbintask22/blog/dfa376cf15e7b556baf7a90db1f59d6a364fe5bc/src/main/resources/static/admin/plugins/jquery-multi-select/img/switch.png -------------------------------------------------------------------------------- /src/main/resources/static/admin/plugins/jquery-multi-select/jquery.quicksearch.js: -------------------------------------------------------------------------------- 1 | (function($, window, document, undefined) { 2 | $.fn.quicksearch = function (target, opt) { 3 | 4 | var timeout, cache, rowcache, jq_results, val = '', e = this, options = $.extend({ 5 | delay: 100, 6 | selector: null, 7 | stripeRows: null, 8 | loader: null, 9 | noResults: '', 10 | matchedResultsCount: 0, 11 | bind: 'keyup', 12 | onBefore: function () { 13 | return; 14 | }, 15 | onAfter: function () { 16 | return; 17 | }, 18 | show: function () { 19 | this.style.display = ""; 20 | }, 21 | hide: function () { 22 | this.style.display = "none"; 23 | }, 24 | prepareQuery: function (val) { 25 | return val.toLowerCase().split(' '); 26 | }, 27 | testQuery: function (query, txt, _row) { 28 | for (var i = 0; i < query.length; i += 1) { 29 | if (txt.indexOf(query[i]) === -1) { 30 | return false; 31 | } 32 | } 33 | return true; 34 | } 35 | }, opt); 36 | 37 | this.go = function () { 38 | 39 | var i = 0, 40 | numMatchedRows = 0, 41 | noresults = true, 42 | query = options.prepareQuery(val), 43 | val_empty = (val.replace(' ', '').length === 0); 44 | 45 | for (var i = 0, len = rowcache.length; i < len; i++) { 46 | if (val_empty || options.testQuery(query, cache[i], rowcache[i])) { 47 | options.show.apply(rowcache[i]); 48 | noresults = false; 49 | numMatchedRows++; 50 | } else { 51 | options.hide.apply(rowcache[i]); 52 | } 53 | } 54 | 55 | if (noresults) { 56 | this.results(false); 57 | } else { 58 | this.results(true); 59 | this.stripe(); 60 | } 61 | 62 | this.matchedResultsCount = numMatchedRows; 63 | this.loader(false); 64 | options.onAfter(); 65 | 66 | return this; 67 | }; 68 | 69 | /* 70 | * External API so that users can perform search programatically. 71 | * */ 72 | this.search = function (submittedVal) { 73 | val = submittedVal; 74 | e.trigger(); 75 | }; 76 | 77 | /* 78 | * External API to get the number of matched results as seen in 79 | * https://github.com/ruiz107/quicksearch/commit/f78dc440b42d95ce9caed1d087174dd4359982d6 80 | * */ 81 | this.currentMatchedResults = function() { 82 | return this.matchedResultsCount; 83 | }; 84 | 85 | this.stripe = function () { 86 | 87 | if (typeof options.stripeRows === "object" && options.stripeRows !== null) 88 | { 89 | var joined = options.stripeRows.join(' '); 90 | var stripeRows_length = options.stripeRows.length; 91 | 92 | jq_results.not(':hidden').each(function (i) { 93 | $(this).removeClass(joined).addClass(options.stripeRows[i % stripeRows_length]); 94 | }); 95 | } 96 | 97 | return this; 98 | }; 99 | 100 | this.strip_html = function (input) { 101 | var output = input.replace(new RegExp('<[^<]+\>', 'g'), ""); 102 | output = $.trim(output.toLowerCase()); 103 | return output; 104 | }; 105 | 106 | this.results = function (bool) { 107 | if (typeof options.noResults === "string" && options.noResults !== "") { 108 | if (bool) { 109 | $(options.noResults).hide(); 110 | } else { 111 | $(options.noResults).show(); 112 | } 113 | } 114 | return this; 115 | }; 116 | 117 | this.loader = function (bool) { 118 | if (typeof options.loader === "string" && options.loader !== "") { 119 | (bool) ? $(options.loader).show() : $(options.loader).hide(); 120 | } 121 | return this; 122 | }; 123 | 124 | this.cache = function () { 125 | 126 | jq_results = $(target); 127 | 128 | if (typeof options.noResults === "string" && options.noResults !== "") { 129 | jq_results = jq_results.not(options.noResults); 130 | } 131 | 132 | var t = (typeof options.selector === "string") ? jq_results.find(options.selector) : $(target).not(options.noResults); 133 | cache = t.map(function () { 134 | return e.strip_html(this.innerHTML); 135 | }); 136 | 137 | rowcache = jq_results.map(function () { 138 | return this; 139 | }); 140 | 141 | /* 142 | * Modified fix for sync-ing "val". 143 | * Original fix https://github.com/michaellwest/quicksearch/commit/4ace4008d079298a01f97f885ba8fa956a9703d1 144 | * */ 145 | val = val || this.val() || ""; 146 | 147 | return this.go(); 148 | }; 149 | 150 | this.trigger = function () { 151 | this.loader(true); 152 | options.onBefore(); 153 | 154 | window.clearTimeout(timeout); 155 | timeout = window.setTimeout(function () { 156 | e.go(); 157 | }, options.delay); 158 | 159 | return this; 160 | }; 161 | 162 | this.cache(); 163 | this.results(true); 164 | this.stripe(); 165 | this.loader(false); 166 | 167 | return this.each(function () { 168 | 169 | /* 170 | * Changed from .bind to .on. 171 | * */ 172 | $(this).on(options.bind, function () { 173 | 174 | val = $(this).val(); 175 | e.trigger(); 176 | }); 177 | }); 178 | 179 | }; 180 | 181 | }(jQuery, this, document)); 182 | -------------------------------------------------------------------------------- /src/main/resources/static/admin/plugins/md/css/style.css: -------------------------------------------------------------------------------- 1 | body{font-family:"Arial";} 2 | .markdown-editor textarea{resize:vertical;line-height:1.5;} 3 | .markdown-textarea{width:100%;font-family:"Arial";resize: none;background-color: #fafafa;} 4 | .markdown-editor{line-height: 1.5em;} 5 | .md-prompt-dialog p{font-size:12px;color:#999;line-height: 1.2em;} 6 | .md-prompt-dialog b{font-size:12px;color:#333;padding-bottom:6px;display: block;} 7 | .md-prompt-dialog input,.markdown-textarea{background:#FFF;border:1px solid #D9D9D6;padding:10px;border-radius:2px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;} 8 | .md-prompt-dialog button{border:none;background-color:#e9e9e6;cursor:pointer;-webkit-border-radius:2px;-moz-border-radius:2px;-ms-border-radius:2px;-o-border-radius:2px;border-radius:2px;display:inline-block;padding:0 12px;height:32px;color:#666;vertical-align:middle;zoom:1;} 9 | .md-prompt-dialog button:hover{-webkit-transition-duration:.4s;-moz-transition-duration:.4s;-o-transition-duration:.4s;transition-duration:.4s;background-color:#dbdbd6;} 10 | .md-prompt-dialog button:active,.md-prompt-dialog button.active{background-color:#d6d6d0;} 11 | .md-prompt-dialog .primary{border:none;background-color:#467b96;cursor:pointer;-webkit-border-radius:2px;-moz-border-radius:2px;-ms-border-radius:2px;-o-border-radius:2px;border-radius:2px;color:#FFF;} 12 | .md-prompt-dialog .primary:hover{-webkit-transition-duration:.4s;-moz-transition-duration:.4s;-o-transition-duration:.4s;transition-duration:.4s;background-color:#3c6a81;} 13 | .md-prompt-dialog .primary:active,.primary.active{background-color:#39647a;} 14 | .md-button-row{list-style:none;margin:0;padding:0;height:26px;line-height:1;} 15 | .md-button-row li{display:inline-block;margin-right:4px;padding:3px;cursor:pointer;-webkit-border-radius:2px;-moz-border-radius:2px;-ms-border-radius:2px;-o-border-radius:2px;border-radius:2px;} 16 | .md-button-row li:hover{background-color:#E9E9E6;} 17 | .md-button-row li.md-spacer{height:20px;margin:0 10px 0 6px;padding:3px 0;width:1px;background:#E9E9E6;cursor:default;} 18 | #md-button-row span{display:block;width:20px;height:20px;background:transparent url(../img/editor.png) no-repeat;} 19 | .md-edittab{float:right;margin-top:3px;font-size:.92857em;} 20 | .md-edittab a{display:inline-block;padding:0 8px;margin-left:5px;height:20px;line-height:20px;} 21 | .md-edittab a:hover{text-decoration:none;} 22 | .md-edittab a.active{background:#E9E9E6;color:#999;} 23 | .md-hidetab{display:none;} 24 | .md-visualhide{visibility:hidden;} 25 | .md-prompt-background{background-color:#000;} 26 | .md-prompt-dialog{position:fixed;z-index:1001;top:50%;left:50%;margin-top:-95px;margin-left:-200px;padding:20px;width:360px;background:#F6F6F3;} 27 | .md-prompt-dialog p{margin:0 0 5px;} 28 | .md-prompt-dialog form{margin-top:10px;} 29 | .md-prompt-dialog input[type="text"]{margin-bottom:10px;width:100%;} 30 | .md-prompt-dialog button{margin-right:10px;} 31 | #md-preview{background:#fff;padding: 10px 15px 0; 32 | word-wrap:break-word;overflow:auto;-webkit-border-radius:2px;-moz-border-radius:2px;-ms-border-radius:2px;-o-border-radius:2px;border-radius:2px;} 33 | #md-preview img{max-width:100%;} 34 | #md-preview code,#md-preview pre{padding:2px 4px;background:#F3F3F0;font-size:.92857em;} 35 | #md-preview code{color:#B94A48;} 36 | #md-preview pre{padding:1em;} 37 | #md-preview pre code{padding:0;color:#444;} 38 | #md-preview blockquote{margin:1em 1.5em;padding-left:1.5em;border-left:4px solid #E9E9E6;color:#777;} 39 | #md-preview hr{margin:0.5em auto;border:1px solid #E9E9E6;border-width:2px 0 0 0;} 40 | #md-preview .summary:after{display:block;margin:2em 0;background:#FFF9E8;color:#ce9900;font-size:.85714em;text-align:center;content:"- more -";} 41 | .fullscreen #md-button-bar,.fullscreen #text,.fullscreen #md-preview,.fullscreen .submit{position:absolute;top:0;width:50%;background:#FFF;z-index:999;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;-webkit-border-radius:0;-moz-border-radius:0;-ms-border-radius:0;-o-border-radius:0;border-radius:0;} 42 | .fullscreen #md-button-bar{left:0;padding:13px 20px;border-bottom:1px solid #F3F3F0;z-index:1000;} 43 | .fullscreen #text{top:53px;left:0;padding:20px;border:none;outline:none;} 44 | .fullscreen #md-preview{top:52px;right:0;margin:0;padding:5px 20px;border:none;border-left:1px solid #F3F3F0;border-top:1px solid #F3F3F0;background:#F6F6F3;overflow:auto;} 45 | .fullscreen #md-preview code,.fullscreen #md-preview pre{background:#F0F0EC;} 46 | .fullscreen .submit{right:0;margin:0;padding:10px 20px;border-bottom:1px solid #F3F3F0;} 47 | .fullscreen .md-edittab,.fullscreen .typecho-post-option,.fullscreen .title,.fullscreen .url-slug,.fullscreen .typecho-page-title,.fullscreen .typecho-head-nav,.fullscreen .message,.fullscreen #upload-panel{display:none;} 48 | .fullscreen .md-hidetab{display:block;} 49 | .fullscreen .md-visualhide{visibility:visible;} 50 | .md-edittab{float:right;margin-top:3px;font-size:.92857em;} 51 | .md-edittab a{font-size:12px;text-decoration: none;color:#999; display:inline-block;padding:0 8px;margin-left:5px;height:24px;line-height:24px;border-radius: 2px;} 52 | .md-edittab a:hover{text-decoration:none;} 53 | .md-edittab a.active{background:#3c6a81;color:#fff;} 54 | .md-hidetab{display:none;} 55 | .md-visualhide{visibility:hidden;} 56 | .md-prompt-background{background-color:#000;}. 57 | -------------------------------------------------------------------------------- /src/main/resources/static/admin/plugins/md/img/editor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jsbintask22/blog/dfa376cf15e7b556baf7a90db1f59d6a364fe5bc/src/main/resources/static/admin/plugins/md/img/editor.png -------------------------------------------------------------------------------- /src/main/resources/static/admin/plugins/md/js/jquery.scrollto.js: -------------------------------------------------------------------------------- 1 | (function(c){var a=c.scrollTo=function(f,e,d){c(window).scrollTo(f,e,d)};a.defaults={axis:"xy",duration:parseFloat(c.fn.jquery)>=1.3?0:1,limit:true};a.window=function(d){return c(window)._scrollable()};c.fn._scrollable=function(){return this.map(function(){var e=this,d=!e.nodeName||c.inArray(e.nodeName.toLowerCase(),["iframe","#document","html","body"])!=-1;if(!d){return e}var f=(e.contentWindow||e).document||e.ownerDocument||e;return/webkit/i.test(navigator.userAgent)||f.compatMode=="BackCompat"?f.body:f.documentElement})};c.fn.scrollTo=function(f,e,d){if(typeof e=="object"){d=e;e=0}if(typeof d=="function"){d={onAfter:d}}if(f=="max"){f=9000000000}d=c.extend({},a.defaults,d);e=e||d.duration;d.queue=d.queue&&d.axis.length>1;if(d.queue){e/=2}d.offset=b(d.offset);d.over=b(d.over);return this._scrollable().each(function(){if(f==null){return}var l=this,j=c(l),k=f,i,g={},m=j.is("html,body");switch(typeof k){case"number":case"string":if(/^([+-]=)?\d+(\.\d+)?(px|%)?$/.test(k)){k=b(k);break}k=c(k,this);if(!k.length){return}case"object":if(k.is||k.style){i=(k=c(k)).offset()}}c.each(d.axis.split(""),function(q,r){var s=r=="x"?"Left":"Top",u=s.toLowerCase(),p="scroll"+s,o=l[p],n=a.max(l,r);if(i){g[p]=i[u]+(m?0:o-j.offset()[u]);if(d.margin){g[p]-=parseInt(k.css("margin"+s))||0;g[p]-=parseInt(k.css("border"+s+"Width"))||0}g[p]+=d.offset[u]||0;if(d.over[u]){g[p]+=k[r=="x"?"width":"height"]()*d.over[u]}}else{var t=k[u];g[p]=t.slice&&t.slice(-1)=="%"?parseFloat(t)/100*n:t}if(d.limit&&/^\d+$/.test(g[p])){g[p]=g[p]<=0?0:Math.min(g[p],n)}if(!q&&d.queue){if(o!=g[p]){h(d.onAfterFirst)}delete g[p]}});h(d.onAfter);function h(n){j.animate(g,e,d.easing,n&&function(){n.call(this,f,d)})}}).end()};a.max=function(j,i){var h=i=="x"?"Width":"Height",e="scroll"+h;if(!c(j).is("html,body")){return j[e]-c(j)[h.toLowerCase()]()}var g="client"+h,f=j.ownerDocument.documentElement,d=j.ownerDocument.body;return Math.max(f[e],d[e])-Math.min(f[g],d[g])};function b(d){return typeof d=="object"?d:{top:d,left:d}}})(jQuery); -------------------------------------------------------------------------------- /src/main/resources/static/admin/plugins/select2.dist.css/select2-bootstrap.css: -------------------------------------------------------------------------------- 1 | .form-control .select2-choice { 2 | border: 0; 3 | border-radius: 2px; 4 | } 5 | 6 | .form-control .select2-choice .select2-arrow { 7 | border-radius: 0 2px 2px 0; 8 | } 9 | 10 | .form-control.select2-container { 11 | height: auto !important; 12 | padding: 0; 13 | } 14 | 15 | .form-control.select2-container.select2-dropdown-open { 16 | border-color: #5897FB; 17 | border-radius: 3px 3px 0 0; 18 | } 19 | 20 | .form-control .select2-container.select2-dropdown-open .select2-choices { 21 | border-radius: 3px 3px 0 0; 22 | } 23 | 24 | .form-control.select2-container .select2-choices { 25 | border: 0 !important; 26 | border-radius: 3px; 27 | } 28 | 29 | .control-group.warning .select2-container .select2-choice, 30 | .control-group.warning .select2-container .select2-choices, 31 | .control-group.warning .select2-container-active .select2-choice, 32 | .control-group.warning .select2-container-active .select2-choices, 33 | .control-group.warning .select2-dropdown-open.select2-drop-above .select2-choice, 34 | .control-group.warning .select2-dropdown-open.select2-drop-above .select2-choices, 35 | .control-group.warning .select2-container-multi.select2-container-active .select2-choices { 36 | border: 1px solid #C09853 !important; 37 | } 38 | 39 | .control-group.warning .select2-container .select2-choice div { 40 | border-left: 1px solid #C09853 !important; 41 | background: #FCF8E3 !important; 42 | } 43 | 44 | .control-group.error .select2-container .select2-choice, 45 | .control-group.error .select2-container .select2-choices, 46 | .control-group.error .select2-container-active .select2-choice, 47 | .control-group.error .select2-container-active .select2-choices, 48 | .control-group.error .select2-dropdown-open.select2-drop-above .select2-choice, 49 | .control-group.error .select2-dropdown-open.select2-drop-above .select2-choices, 50 | .control-group.error .select2-container-multi.select2-container-active .select2-choices { 51 | border: 1px solid #B94A48 !important; 52 | } 53 | 54 | .control-group.error .select2-container .select2-choice div { 55 | border-left: 1px solid #B94A48 !important; 56 | background: #F2DEDE !important; 57 | } 58 | 59 | .control-group.info .select2-container .select2-choice, 60 | .control-group.info .select2-container .select2-choices, 61 | .control-group.info .select2-container-active .select2-choice, 62 | .control-group.info .select2-container-active .select2-choices, 63 | .control-group.info .select2-dropdown-open.select2-drop-above .select2-choice, 64 | .control-group.info .select2-dropdown-open.select2-drop-above .select2-choices, 65 | .control-group.info .select2-container-multi.select2-container-active .select2-choices { 66 | border: 1px solid #3A87AD !important; 67 | } 68 | 69 | .control-group.info .select2-container .select2-choice div { 70 | border-left: 1px solid #3A87AD !important; 71 | background: #D9EDF7 !important; 72 | } 73 | 74 | .control-group.success .select2-container .select2-choice, 75 | .control-group.success .select2-container .select2-choices, 76 | .control-group.success .select2-container-active .select2-choice, 77 | .control-group.success .select2-container-active .select2-choices, 78 | .control-group.success .select2-dropdown-open.select2-drop-above .select2-choice, 79 | .control-group.success .select2-dropdown-open.select2-drop-above .select2-choices, 80 | .control-group.success .select2-container-multi.select2-container-active .select2-choices { 81 | border: 1px solid #468847 !important; 82 | } 83 | 84 | .control-group.success .select2-container .select2-choice div { 85 | border-left: 1px solid #468847 !important; 86 | background: #DFF0D8 !important; 87 | } 88 | -------------------------------------------------------------------------------- /src/main/resources/static/admin/plugins/select2.dist.css/select2-spinner.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jsbintask22/blog/dfa376cf15e7b556baf7a90db1f59d6a364fe5bc/src/main/resources/static/admin/plugins/select2.dist.css/select2-spinner.gif -------------------------------------------------------------------------------- /src/main/resources/static/admin/plugins/select2.dist.css/select2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jsbintask22/blog/dfa376cf15e7b556baf7a90db1f59d6a364fe5bc/src/main/resources/static/admin/plugins/select2.dist.css/select2.png -------------------------------------------------------------------------------- /src/main/resources/static/admin/plugins/select2.dist.css/select2x2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jsbintask22/blog/dfa376cf15e7b556baf7a90db1f59d6a364fe5bc/src/main/resources/static/admin/plugins/select2.dist.css/select2x2.png -------------------------------------------------------------------------------- /src/main/resources/static/admin/plugins/tagsinput/jquery.tagsinput.css: -------------------------------------------------------------------------------- 1 | div.tagsinput { 2 | border:1px solid #ccc; 3 | background: #FFF; 4 | padding:5px; 5 | width:300px; 6 | height:100px; 7 | overflow-y: auto; 8 | -moz-border-radius: 2px; 9 | -webkit-border-radius: 2px; 10 | border-radius: 2px; 11 | } 12 | 13 | div.tagsinput span.tag { 14 | display: block; 15 | float: left; 16 | padding: 2px 5px; 17 | text-decoration:none; 18 | background: #317eeb; 19 | color: #fff; 20 | margin-right: 5px; 21 | margin-bottom:5px; 22 | font-size:13px; 23 | -moz-border-radius: 2px; 24 | -webkit-border-radius: 2px; 25 | border-radius: 2px; 26 | } 27 | 28 | div.tagsinput span.tag a { 29 | font-weight: bold; 30 | color: #fff; 31 | opacity: 0.5; 32 | text-decoration: none; 33 | font-size: 11px; 34 | } 35 | 36 | div.tagsinput span.tag a:hover { 37 | opacity: 1; 38 | } 39 | 40 | div.tagsinput input { 41 | width: 80px; 42 | margin: 0px; 43 | font-size: 13px; 44 | border: 1px solid transparent; 45 | padding: 5px; 46 | background: transparent; 47 | color: #000; 48 | outline: 0px; 49 | margin-right: 5px; 50 | margin-bottom: 5px; 51 | } 52 | 53 | div.tagsinput div { 54 | display: block; 55 | float: left; 56 | } 57 | 58 | .tags_clear { 59 | clear: both; 60 | width: 100%; 61 | height: 0px; 62 | } 63 | 64 | .not_valid { 65 | background: #FBD8DB !important; 66 | color: #90111A !important; 67 | } 68 | -------------------------------------------------------------------------------- /src/main/resources/static/user/img/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jsbintask22/blog/dfa376cf15e7b556baf7a90db1f59d6a364fe5bc/src/main/resources/static/user/img/apple-touch-icon.png -------------------------------------------------------------------------------- /src/main/resources/static/user/img/bg-ico.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jsbintask22/blog/dfa376cf15e7b556baf7a90db1f59d6a364fe5bc/src/main/resources/static/user/img/bg-ico.png -------------------------------------------------------------------------------- /src/main/resources/static/user/img/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jsbintask22/blog/dfa376cf15e7b556baf7a90db1f59d6a364fe5bc/src/main/resources/static/user/img/favicon.png -------------------------------------------------------------------------------- /src/main/resources/static/user/img/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jsbintask22/blog/dfa376cf15e7b556baf7a90db1f59d6a364fe5bc/src/main/resources/static/user/img/logo.png -------------------------------------------------------------------------------- /src/main/resources/static/user/img/rand/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jsbintask22/blog/dfa376cf15e7b556baf7a90db1f59d6a364fe5bc/src/main/resources/static/user/img/rand/1.jpg -------------------------------------------------------------------------------- /src/main/resources/static/user/img/rand/10.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jsbintask22/blog/dfa376cf15e7b556baf7a90db1f59d6a364fe5bc/src/main/resources/static/user/img/rand/10.jpg -------------------------------------------------------------------------------- /src/main/resources/static/user/img/rand/11.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jsbintask22/blog/dfa376cf15e7b556baf7a90db1f59d6a364fe5bc/src/main/resources/static/user/img/rand/11.jpg -------------------------------------------------------------------------------- /src/main/resources/static/user/img/rand/12.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jsbintask22/blog/dfa376cf15e7b556baf7a90db1f59d6a364fe5bc/src/main/resources/static/user/img/rand/12.jpg -------------------------------------------------------------------------------- /src/main/resources/static/user/img/rand/13.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jsbintask22/blog/dfa376cf15e7b556baf7a90db1f59d6a364fe5bc/src/main/resources/static/user/img/rand/13.jpg -------------------------------------------------------------------------------- /src/main/resources/static/user/img/rand/14.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jsbintask22/blog/dfa376cf15e7b556baf7a90db1f59d6a364fe5bc/src/main/resources/static/user/img/rand/14.jpg -------------------------------------------------------------------------------- /src/main/resources/static/user/img/rand/15.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jsbintask22/blog/dfa376cf15e7b556baf7a90db1f59d6a364fe5bc/src/main/resources/static/user/img/rand/15.jpg -------------------------------------------------------------------------------- /src/main/resources/static/user/img/rand/16.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jsbintask22/blog/dfa376cf15e7b556baf7a90db1f59d6a364fe5bc/src/main/resources/static/user/img/rand/16.jpg -------------------------------------------------------------------------------- /src/main/resources/static/user/img/rand/17.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jsbintask22/blog/dfa376cf15e7b556baf7a90db1f59d6a364fe5bc/src/main/resources/static/user/img/rand/17.jpg -------------------------------------------------------------------------------- /src/main/resources/static/user/img/rand/18.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jsbintask22/blog/dfa376cf15e7b556baf7a90db1f59d6a364fe5bc/src/main/resources/static/user/img/rand/18.jpg -------------------------------------------------------------------------------- /src/main/resources/static/user/img/rand/19.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jsbintask22/blog/dfa376cf15e7b556baf7a90db1f59d6a364fe5bc/src/main/resources/static/user/img/rand/19.jpg -------------------------------------------------------------------------------- /src/main/resources/static/user/img/rand/2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jsbintask22/blog/dfa376cf15e7b556baf7a90db1f59d6a364fe5bc/src/main/resources/static/user/img/rand/2.jpg -------------------------------------------------------------------------------- /src/main/resources/static/user/img/rand/3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jsbintask22/blog/dfa376cf15e7b556baf7a90db1f59d6a364fe5bc/src/main/resources/static/user/img/rand/3.jpg -------------------------------------------------------------------------------- /src/main/resources/static/user/img/rand/4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jsbintask22/blog/dfa376cf15e7b556baf7a90db1f59d6a364fe5bc/src/main/resources/static/user/img/rand/4.jpg -------------------------------------------------------------------------------- /src/main/resources/static/user/img/rand/5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jsbintask22/blog/dfa376cf15e7b556baf7a90db1f59d6a364fe5bc/src/main/resources/static/user/img/rand/5.jpg -------------------------------------------------------------------------------- /src/main/resources/static/user/img/rand/6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jsbintask22/blog/dfa376cf15e7b556baf7a90db1f59d6a364fe5bc/src/main/resources/static/user/img/rand/6.jpg -------------------------------------------------------------------------------- /src/main/resources/static/user/img/rand/7.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jsbintask22/blog/dfa376cf15e7b556baf7a90db1f59d6a364fe5bc/src/main/resources/static/user/img/rand/7.jpg -------------------------------------------------------------------------------- /src/main/resources/static/user/img/rand/8.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jsbintask22/blog/dfa376cf15e7b556baf7a90db1f59d6a364fe5bc/src/main/resources/static/user/img/rand/8.jpg -------------------------------------------------------------------------------- /src/main/resources/static/user/img/rand/9.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jsbintask22/blog/dfa376cf15e7b556baf7a90db1f59d6a364fe5bc/src/main/resources/static/user/img/rand/9.jpg -------------------------------------------------------------------------------- /src/main/resources/templates/admin/article_list.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |

文章管理

13 |
14 |
15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 32 | 33 | 34 | 35 | 43 | 54 | 55 | 56 | 57 | 58 |
文章标题发布时间浏览量所属分类发布状态操作
30 | 31 | 36 | 37 | 已发布 38 | 39 | 40 | 草稿 41 | 42 | 44 | 编辑 47 | 删除 50 | 预览 53 |
59 |

60 | 61 | 62 |
63 | 64 | 65 | 66 | 67 |
68 | 91 | 92 | -------------------------------------------------------------------------------- /src/main/resources/templates/admin/footer.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /src/main/resources/templates/admin/page_list.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |

文章管理

13 |
14 |
15 |
16 | 添加新页面 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 38 | 48 | 49 | 50 | 51 |
页面名称页面路径发布时间发布状态操作
35 | 36 | 37 | 39 | 编辑 41 | 删除 44 | 预览 47 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 | 83 | 84 | -------------------------------------------------------------------------------- /src/main/resources/templates/comm/error_404.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 404(找不到页面)- My Blog 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 18 | 19 | 20 | 21 |
22 |
23 |

404!

24 |

很抱歉,没有找到这个页面!

25 |

26 | 返回首页 27 |
28 |
29 | 30 | 31 | -------------------------------------------------------------------------------- /src/main/resources/templates/comm/error_500.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 500(服务器出差错了)- My Blog 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 18 | 19 | 20 | 21 |
22 |
23 |

500

24 |

服务器出了点差错.



25 |

可以尝试向社区发出求助 New Issues

26 | 返回首页 27 |
28 |
29 | 30 | 31 | -------------------------------------------------------------------------------- /src/main/resources/templates/comm/macros.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 21 | 22 |
23 |
24 | 46 |
47 |
48 | 49 | 50 | -------------------------------------------------------------------------------- /src/main/resources/templates/comm/tale_comment.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 61 | 62 | -------------------------------------------------------------------------------- /src/main/resources/templates/themes/README: -------------------------------------------------------------------------------- 1 | 这里存放主题 -------------------------------------------------------------------------------- /src/main/resources/templates/themes/default/archives.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 |
6 |
7 | 8 |
9 |
10 |
11 | 12 |
13 |
14 |
15 |
16 | 17 |
18 |
19 |
发布于
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 | 31 |
32 | -------------------------------------------------------------------------------- /src/main/resources/templates/themes/default/comments.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
5 |
6 |
7 |
8 | 9 | 10 | Hi, 12 | 如果你想 注销 ? 13 | 14 | 15 |
17 | 18 | 19 | 20 | 24 | 27 | 30 | 33 | 34 |
35 |
36 |
37 | 评论已关闭. 38 |
39 | 40 |
41 |
    42 | 43 |
  1. 44 |
    45 |
    46 |
    47 | 48 | 52 | 53 | 55 | 56 |
    57 |
    58 | 59 |

    60 |
    61 |
    62 | 63 | 64 | 65 |
    66 |
    67 |
    68 |
  2. 69 |
    70 |
71 |
72 | 85 | 86 |
87 |
88 |
89 |
90 |
91 | 92 |
93 | -------------------------------------------------------------------------------- /src/main/resources/templates/themes/default/header.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | <th:block th:text="${title ?: '首页'}+' - '+${commons.site_option('site_title','jsbintask22 Blog')}"></th:block> 15 | 16 | 17 | 18 | 19 | 23 | 24 | 25 | 30 | 59 | 60 | -------------------------------------------------------------------------------- /src/main/resources/templates/themes/default/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 |
6 |
7 |
8 |
9 |
10 | 12 | 13 | 14 |
15 |
16 |
17 |
19 |
20 |
21 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 | 36 |
37 | 38 | -------------------------------------------------------------------------------- /src/main/resources/templates/themes/default/links.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 |
6 |
7 |

友情链接

8 | 13 |

链接须知

14 |
15 |
    16 |
  • 请确定贵站可以稳定运营

  • 17 |
  • 原创博客优先,技术类博客优先,设计、视觉类博客优先

  • 18 |
  • 经常过来访问和评论,眼熟的

  • 19 |
20 |
21 |

基本信息

22 |

23 |             网站名称:13 Blog(13的技术分享)
24 |             网站地址:http://blog.hanshuai.xin
25 | 26 |

我的邮箱:1034683568@qq.com

27 |

暂时先这样,同时欢迎互换友链 ^_^

28 |

还有,我会不定时对无法访问的网址进行清理,请保证自己的链接长期有效

29 |
30 | 31 |
32 | -------------------------------------------------------------------------------- /src/main/resources/templates/themes/default/page-category.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 |
6 |
7 |
8 | : 9 |
10 | 11 |
12 |

抱歉,还没有相关文章.

13 |
14 |
15 | 16 |
17 |
18 | 19 |
20 |
21 |
22 |
23 | 24 |
25 |
26 |
28 |
发布于
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 | 38 |
39 |
40 | 41 |
42 | -------------------------------------------------------------------------------- /src/main/resources/templates/themes/default/page.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 |
6 |
7 |

8 |
9 | 10 |
11 |
12 |
13 |
14 |
15 |
16 | 17 | -------------------------------------------------------------------------------- /src/main/resources/templates/themes/default/post.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 |
6 |
7 |

8 | 9 |

10 |
11 | 12 | / / / 13 | 浏览 14 |
15 |
16 |
17 | 18 | 19 | 23 |
24 |
25 |
26 |
27 | 28 | -------------------------------------------------------------------------------- /src/test/java/com/my/blog/website/AsyncTest.java: -------------------------------------------------------------------------------- 1 | package com.my.blog.website; 2 | 3 | import org.junit.Test; 4 | import org.junit.runner.RunWith; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.boot.test.context.SpringBootTest; 7 | import org.springframework.scheduling.annotation.Async; 8 | import org.springframework.scheduling.annotation.AsyncResult; 9 | import org.springframework.scheduling.annotation.EnableAsync; 10 | import org.springframework.stereotype.Component; 11 | import org.springframework.test.context.junit4.SpringRunner; 12 | 13 | import java.util.Random; 14 | import java.util.concurrent.Future; 15 | 16 | /** 17 | * 测试异步调用 18 | * Created by Administrator on 2017/3/6 006. 19 | */ 20 | @RunWith(SpringRunner.class) 21 | @SpringBootTest 22 | @EnableAsync 23 | public class AsyncTest { 24 | 25 | @Autowired 26 | private Task task; 27 | 28 | @Test 29 | public void Test() throws Exception { 30 | 31 | long start = System.currentTimeMillis(); 32 | Future task1 = task.doTaskOne(); 33 | Future task2 = task.doTaskTwo(); 34 | Future task3 = task.doTaskThree(); 35 | while(true) { 36 | 37 | if(task1.isDone() && task2.isDone() && task3.isDone()) { 38 | // 三个任务都调用完成,退出循环等待 39 | break; 40 | } 41 | Thread.sleep(1000); 42 | } 43 | long end = System.currentTimeMillis(); 44 | System.out.println("任务全部完成,总耗时:" + (end - start) + "毫秒"); 45 | } 46 | 47 | 48 | 49 | } 50 | 51 | @Component 52 | class Task{ 53 | 54 | private static Random random =new Random(); 55 | 56 | @Async 57 | Future doTaskOne() throws Exception { 58 | System.out.println("开始做任务一"); 59 | long start = System.currentTimeMillis(); 60 | Thread.sleep(random.nextInt(10000)); 61 | long end = System.currentTimeMillis(); 62 | System.out.println("完成任务一,耗时:" + (end - start) + "毫秒"); 63 | return new AsyncResult<>("任务一OK"); 64 | } 65 | 66 | @Async 67 | Future doTaskTwo() throws Exception { 68 | System.out.println("开始做任务二"); 69 | long start = System.currentTimeMillis(); 70 | Thread.sleep(random.nextInt(10000)); 71 | long end = System.currentTimeMillis(); 72 | System.out.println("完成任务二,耗时:" + (end - start) + "毫秒"); 73 | return new AsyncResult<>("任务二OK"); 74 | } 75 | 76 | @Async 77 | Future doTaskThree() throws Exception { 78 | System.out.println("开始做任务三"); 79 | long start = System.currentTimeMillis(); 80 | Thread.sleep(random.nextInt(10000)); 81 | long end = System.currentTimeMillis(); 82 | System.out.println("完成任务三,耗时:" + (end - start) + "毫秒"); 83 | return new AsyncResult<>("任务三OK"); 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /src/test/java/com/my/blog/website/Pwdtest.java: -------------------------------------------------------------------------------- 1 | package com.my.blog.website; 2 | 3 | import com.my.blog.website.model.Vo.UserVo; 4 | import com.my.blog.website.utils.TaleUtils; 5 | 6 | /** 7 | * Created by 13 on 2017/4/2. 8 | */ 9 | public class Pwdtest { 10 | public static void main(String args[]){ 11 | UserVo user = new UserVo(); 12 | user.setUsername("admin"); 13 | user.setPassword("J9lew2irojE23"); 14 | String encodePwd = TaleUtils.MD5encode(user.getUsername() + user.getPassword()); 15 | System.out.println(encodePwd); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/test/java/com/my/blog/website/TranscationTest.java: -------------------------------------------------------------------------------- 1 | package com.my.blog.website; 2 | 3 | import com.my.blog.website.exception.TipException; 4 | import com.my.blog.website.model.Vo.UserVo; 5 | import com.my.blog.website.service.IUserService; 6 | import com.my.blog.website.service.IOptionService; 7 | import org.junit.Ignore; 8 | import org.junit.runner.RunWith; 9 | import org.mybatis.spring.annotation.MapperScan; 10 | import org.springframework.boot.test.context.SpringBootTest; 11 | import org.springframework.test.context.junit4.SpringRunner; 12 | import org.springframework.transaction.annotation.Transactional; 13 | 14 | import javax.annotation.Resource; 15 | 16 | /** 17 | * 测试数据库事务 18 | * Created by BlueT on 2017/3/8. 19 | */ 20 | @MapperScan("com.my.blog.website.dao") 21 | @RunWith(SpringRunner.class) 22 | @SpringBootTest 23 | @Transactional(rollbackFor = TipException.class) 24 | public class TranscationTest { 25 | 26 | @Resource 27 | private IUserService userService; 28 | 29 | @Resource 30 | private IOptionService optionService; 31 | 32 | @org.junit.Test 33 | @Ignore 34 | public void test() { 35 | UserVo user = new UserVo(); 36 | user.setUsername("wangqiang111"); 37 | user.setPassword("123456"); 38 | user.setEmail("8888"); 39 | userService.insertUser(user); 40 | optionService.insertOption("site_keywords", "qwqwq"); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/test/java/com/my/blog/website/controller/IndexControllerTest.java: -------------------------------------------------------------------------------- 1 | package com.my.blog.website.controller; 2 | 3 | import org.junit.Ignore; 4 | import org.junit.Test; 5 | import org.junit.runner.RunWith; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; 8 | import org.springframework.boot.test.context.SpringBootTest; 9 | import org.springframework.mock.web.MockHttpServletRequest; 10 | import org.springframework.test.context.junit4.SpringRunner; 11 | import org.springframework.test.web.servlet.MockMvc; 12 | import org.springframework.test.web.servlet.RequestBuilder; 13 | import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; 14 | import org.springframework.test.web.servlet.result.MockMvcResultHandlers; 15 | import org.springframework.test.web.servlet.result.MockMvcResultMatchers; 16 | 17 | import static org.junit.Assert.*; 18 | 19 | /** 20 | * 接口测试方法 21 | * Created by BlueT on 2017/3/22. 22 | */ 23 | @RunWith(SpringRunner.class) 24 | @SpringBootTest 25 | @AutoConfigureMockMvc 26 | public class IndexControllerTest { 27 | 28 | @Autowired 29 | private MockMvc mockMvc; 30 | @Test 31 | @Ignore 32 | public void index() throws Exception { 33 | mockMvc.perform(MockMvcRequestBuilders.get("")).andExpect(MockMvcResultMatchers.status().isOk()); 34 | 35 | } 36 | 37 | } -------------------------------------------------------------------------------- /static/images/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jsbintask22/blog/dfa376cf15e7b556baf7a90db1f59d6a364fe5bc/static/images/1.png -------------------------------------------------------------------------------- /static/images/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jsbintask22/blog/dfa376cf15e7b556baf7a90db1f59d6a364fe5bc/static/images/2.png -------------------------------------------------------------------------------- /static/images/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jsbintask22/blog/dfa376cf15e7b556baf7a90db1f59d6a364fe5bc/static/images/3.png -------------------------------------------------------------------------------- /static/images/4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jsbintask22/blog/dfa376cf15e7b556baf7a90db1f59d6a364fe5bc/static/images/4.png -------------------------------------------------------------------------------- /static/images/5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jsbintask22/blog/dfa376cf15e7b556baf7a90db1f59d6a364fe5bc/static/images/5.png --------------------------------------------------------------------------------