daily commit

😒 fixed some bugs
pull/1/head
RYAN0UP_ 2018-02-03 10:16:31 +08:00
parent 019e3f7528
commit 056aadd8b0
114 changed files with 2095 additions and 637 deletions

11
pom.xml
View File

@ -23,7 +23,7 @@
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.8.RELEASE</version>
<version>1.5.9.RELEASE</version>
<relativePath/>
</parent>
@ -46,6 +46,7 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
@ -58,11 +59,19 @@
</dependency>
<!-- mysql -->
<!--
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
-->
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<!-- druid数据源 -->
<dependency>

View File

@ -1,6 +1,6 @@
package cc.ryanc.halo.config;
import cc.ryanc.halo.service.OptionsService;
import cc.ryanc.halo.web.interceptor.InstallInterceptor;
import cc.ryanc.halo.web.interceptor.LoginInterceptor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
@ -26,7 +26,7 @@ public class MvcConfiguration extends WebMvcConfigurerAdapter {
private LoginInterceptor loginInterceptor;
@Autowired
private OptionsService optionsService;
private InstallInterceptor installInterceptor;
/**
*
@ -34,7 +34,14 @@ public class MvcConfiguration extends WebMvcConfigurerAdapter {
*/
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(loginInterceptor).addPathPatterns("/admin/**").excludePathPatterns("/admin/login").excludePathPatterns("/admin/getLogin");
registry.addInterceptor(loginInterceptor)
.addPathPatterns("/admin/**")
.excludePathPatterns("/admin/login")
.excludePathPatterns("/admin/getLogin");
registry.addInterceptor(installInterceptor)
.addPathPatterns("/**")
.excludePathPatterns("/install")
.excludePathPatterns("/install/do");
}
/**
@ -43,11 +50,12 @@ public class MvcConfiguration extends WebMvcConfigurerAdapter {
*/
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/static/**").addResourceLocations("classpath:/static/");
registry.addResourceHandler("/**").addResourceLocations("classpath:/templates/themes/")
registry.addResourceHandler("/static/**")
.addResourceLocations("classpath:/static/");
registry.addResourceHandler("/**")
.addResourceLocations("classpath:/templates/themes/")
.addResourceLocations("classpath:/robots.txt");
registry.addResourceHandler("/upload/**").addResourceLocations("classpath:/upload/");
registry.addResourceHandler("/upload/**")
.addResourceLocations("classpath:/upload/");
}
}

View File

@ -31,9 +31,6 @@ public class StartupConfiguration implements ApplicationListener<ContextRefreshe
@Autowired
private OptionsService optionsService;
@Autowired
private UserService userService;
@Autowired
private AttachmentService attachmentService;
@ -43,7 +40,6 @@ public class StartupConfiguration implements ApplicationListener<ContextRefreshe
this.loadOptions();
this.loadFiles();
this.loadThemes();
this.loadUser();
}
/**
@ -102,15 +98,4 @@ public class StartupConfiguration implements ApplicationListener<ContextRefreshe
log.error("加载主题失败:"+e.getMessage());
}
}
private void loadUser(){
try {
User user = userService.findAllUser().get(0);
if(null!=user){
HaloConst.USER = user;
}
}catch (Exception e){
log.error("未知错误:"+e.getMessage());
}
}
}

View File

@ -0,0 +1,47 @@
package cc.ryanc.halo.model.domain;
import lombok.Data;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
/**
* @author : RYAN0UP
* @version : 1.0
* description :
* @date : 2018/1/24
*/
@Data
@Entity
@Table(name = "halo_menu")
public class Menu {
/**
*
*/
@Id
@GeneratedValue
private Long menuId;
/**
*
*/
private String menuName;
/**
*
*/
private String menuUrl;
/**
*
*/
private Integer menuSort;
/**
*
*/
private String menuIcon;
}

View File

@ -1,25 +0,0 @@
package cc.ryanc.halo.model.domain;
import lombok.Data;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
import java.io.Serializable;
/**
* @author : RYAN0UP
* @date : 2017/11/14
* @version : 1.0
* description :
*/
@Data
@Entity
@Table(name = "halo_postmeta")
public class PostMeta implements Serializable{
@Id
@GeneratedValue
private Long metaId;
}

View File

@ -1,25 +0,0 @@
package cc.ryanc.halo.model.domain;
import lombok.Data;
import javax.persistence.*;
import java.io.Serializable;
/**
* @author : RYAN0UP
* @date : 2017/11/14
* @version : 1.0
* description :
*/
@Data
@Entity
@Table(name = "halo_usermeta")
public class UserMeta implements Serializable{
@Id
@GeneratedValue
private Long userMetaId;
private Long userId;
private String userMetaKey;
@Lob
private String userMetaValue;
}

View File

@ -20,11 +20,6 @@ public class HaloConst {
*/
public static Map<String,String> OPTIONS = new HashMap<>();
/**
*
*/
public static User USER = new User();
/**
*
*/

View File

@ -8,6 +8,8 @@ package cc.ryanc.halo.model.dto;
*/
public interface LogsRecord {
String INSTALL = "初始化博客";
String LOGIN = "登录后台";
String LOGIN_SUCCESS = "登录成功";
@ -19,4 +21,12 @@ public interface LogsRecord {
String PUSH_POST = "发表文章";
String REMOVE_POST = "删除文章";
String CHANGE_THEME = "更换主题";
String UPLOAD_THEME = "上传主题";
String UPLOAD_FILE = "上传附件";
String REMOVE_FILE = "移除附件";
}

View File

@ -15,6 +15,7 @@ public interface AttachmentRepository extends JpaRepository<Attachment,Long>{
/**
*
*
* @param pageable pageable
* @return page
*/

View File

@ -13,7 +13,8 @@ public interface CategoryRepository extends JpaRepository<Category,Long>{
/**
*
* @param cateUrl cateUrl
*
* @param cateUrl cateUrl url
* @return category
*/
Category findCategoryByCateUrl(String cateUrl);

View File

@ -19,14 +19,16 @@ public interface CommentRepository extends JpaRepository<Comment,Long> {
/**
*
* @param status Status
* @param pageable pageable
*
* @param status Status
* @param pageable pageable
* @return page
*/
Page<Comment> findCommentsByCommentStatus(Integer status, Pageable pageable);
/**
*
*
* @param post post
* @param pageable pageable
* @return page
@ -35,6 +37,7 @@ public interface CommentRepository extends JpaRepository<Comment,Long> {
/**
*
*
* @param post post
* @param pageable pageable
* @param status status
@ -44,6 +47,7 @@ public interface CommentRepository extends JpaRepository<Comment,Long> {
/**
*
*
* @return list
*/
@Query(value = "SELECT * FROM halo_comment ORDER BY comment_date DESC LIMIT 5",nativeQuery = true)

View File

@ -9,13 +9,14 @@ import java.util.List;
/**
* @author : RYAN0UP
* @version : 1.0
* description :
* @date : 2018/1/19
* description :
*/
public interface LogsRepository extends JpaRepository<Logs,Long> {
/**
*
*
* @return list
*/
@Query(value = "SELECT * FROM halo_logs ORDER BY log_created DESC LIMIT 5",nativeQuery = true)

View File

@ -0,0 +1,16 @@
package cc.ryanc.halo.repository;
import cc.ryanc.halo.model.domain.Menu;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import java.util.List;
/**
* @author : RYAN0UP
* @version : 1.0
* @date : 2018/1/24
* description :
*/
public interface MenuRepository extends JpaRepository<Menu,Long> {
}

View File

@ -13,6 +13,7 @@ public interface OptionsRepository extends JpaRepository<Options,Long>{
/**
* keyoption
*
* @param key key
* @return String
*/

View File

@ -1,13 +0,0 @@
package cc.ryanc.halo.repository;
import cc.ryanc.halo.model.domain.PostMeta;
import org.springframework.data.jpa.repository.JpaRepository;
/**
* @author : RYAN0UP
* @date : 2017/11/14
* @version : 1.0
* description:
*/
public interface PostMetaRepository extends JpaRepository<PostMeta,Long>{
}

View File

@ -22,6 +22,7 @@ public interface PostRepository extends JpaRepository<Post,Long>{
/**
*
*
* @return list
*/
@Query(value = "SELECT * FROM halo_post ORDER BY post_date DESC LIMIT 5",nativeQuery = true)
@ -29,6 +30,7 @@ public interface PostRepository extends JpaRepository<Post,Long>{
/**
*
*
* @param pageable pageable
* @return page
*/
@ -37,6 +39,7 @@ public interface PostRepository extends JpaRepository<Post,Long>{
/**
*
*
* @param keyWord keyword
* @param pageable pageable
* @return list
@ -45,6 +48,7 @@ public interface PostRepository extends JpaRepository<Post,Long>{
/**
*
*
* @param status status
* @param pageable pageable
* @return page
@ -53,6 +57,7 @@ public interface PostRepository extends JpaRepository<Post,Long>{
/**
*
*
* @param status status
* @return List
*/
@ -60,6 +65,7 @@ public interface PostRepository extends JpaRepository<Post,Long>{
/**
*
*
* @param postUrl postUrl
* @return Post
*/
@ -67,6 +73,7 @@ public interface PostRepository extends JpaRepository<Post,Long>{
/**
*
*
* @param postDate postDate
* @param postStatus postStatus
* @return list
@ -76,6 +83,7 @@ public interface PostRepository extends JpaRepository<Post,Long>{
/**
*
*
* @param postDate postDate
* @param postStatus postStatus
* @return list
@ -84,22 +92,25 @@ public interface PostRepository extends JpaRepository<Post,Long>{
/**
*
*
* @return list
*/
@Query(value = "select year(post_date) as year,month(post_date) as month,count(*) as count from halo_post where post_status=0 group by year(post_date) DESC ,month(post_date) DESC",nativeQuery = true)
@Query(value = "select year(post_date) as year,month(post_date) as month,count(*) as count from halo_post where post_status=0 group by year(post_date),month(post_date)",nativeQuery = true)
List<Object[]> findPostGroupByDate();
/**
*
*
* @param year year
* @param month month
* @return list
*/
@Query(value = "select *,year(post_date) as year,month(post_date) as month from halo_post where post_status=0 and year(post_date)=:year and month(post_date)=:month order by post_date desc",nativeQuery = true)
@Query(value = "select *,year(post_date) as year,month(post_date) as month from halo_post where post_status=0 and year(post_date)=:year and month(post_date)=:month order by post_date",nativeQuery = true)
List<Post> findPostByYearAndMonth(@Param("year") String year,@Param("month") String month);
/**
*
*
* @param year year
* @param month month
* @param pageable pageable

View File

@ -1,15 +0,0 @@
package cc.ryanc.halo.repository;
import cc.ryanc.halo.model.domain.UserMeta;
import org.springframework.data.jpa.repository.JpaRepository;
/**
* @author : RYAN0UP
* @version :1.0
* @date : 2017/11/14
* description:
*/
public interface UserMetaRepository extends JpaRepository<UserMeta,Long>{
UserMeta findByUserMetaKey(String key);
}

View File

@ -3,6 +3,8 @@ package cc.ryanc.halo.repository;
import cc.ryanc.halo.model.domain.User;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.List;
/**
* @author : RYAN0UP
* @date : 2017/11/14
@ -10,16 +12,28 @@ import org.springframework.data.jpa.repository.JpaRepository;
* description:
*/
public interface UserRepository extends JpaRepository<User,Long>{
/**
*
*
* @param userName userName
* @param userPass userPass
* @return User
* @return list
*/
User findByUserNameAndUserPass(String userName,String userPass);
List<User> findByUserNameAndUserPass(String userName, String userPass);
/**
*
*
* @param userEmail userEmail
* @param userPass userPass
* @return list
*/
List<User> findByUserEmailAndUserPass(String userEmail,String userPass);
/**
*
*
* @param userId userId
* @param userPass userpass
* @return User

View File

@ -15,6 +15,7 @@ import java.util.List;
public interface AttachmentService {
/**
*
*
* @param attachment attachment
* @return Attachment
*/
@ -22,12 +23,14 @@ public interface AttachmentService {
/**
*
*
* @return list
*/
List<Attachment> findAllAttachments();
/**
*
*
* @param pageable pageable
* @return page
*/
@ -35,6 +38,7 @@ public interface AttachmentService {
/**
*
*
* @param attachId attachId
* @return Attachment
*/
@ -42,6 +46,7 @@ public interface AttachmentService {
/**
*
*
* @param attachId attachId
* @return Attachment
*/

View File

@ -13,6 +13,7 @@ import java.util.List;
public interface CategoryService {
/**
*
*
* @param category
* @return
*/
@ -20,6 +21,7 @@ public interface CategoryService {
/**
*
*
* @param cateId
* @return category
*/
@ -27,6 +29,7 @@ public interface CategoryService {
/**
*
*
* @param category
* @return
*/
@ -34,12 +37,14 @@ public interface CategoryService {
/**
*
*
* @return List
*/
List<Category> findAllCategories();
/**
*
*
* @param cateId
* @return category
*/
@ -47,6 +52,7 @@ public interface CategoryService {
/**
*
*
* @param cateUrl cateUrl
* @return category
*/

View File

@ -17,12 +17,14 @@ public interface CommentService {
/**
*
*
* @param comment comment
*/
void saveByComment(Comment comment);
/**
*
*
* @param status status
* @param pageable pageable
* @return page
@ -32,12 +34,14 @@ public interface CommentService {
/**
*
* @return
*
* @return list
*/
List<Comment> findAllComments();
/**
*
*
* @param commentId commentId
* @param status status
* @return comment
@ -46,6 +50,7 @@ public interface CommentService {
/**
*
*
* @param commentId commentId
* @return comment
*/
@ -53,6 +58,7 @@ public interface CommentService {
/**
*
*
* @param post post
* @param pageable pageable
* @return page
@ -61,6 +67,7 @@ public interface CommentService {
/**
*
*
* @param post post
* @param pageable pageable
* @param status status
@ -70,6 +77,7 @@ public interface CommentService {
/**
*
*
* @return list
*/
List<Comment> findCommentsLatest();

View File

@ -13,6 +13,7 @@ import java.util.List;
public interface LinkService {
/**
*
*
* @param link link
* @return Link
*/
@ -20,6 +21,7 @@ public interface LinkService {
/**
*
*
* @param linkId linkId
* @return Link
*/
@ -27,6 +29,7 @@ public interface LinkService {
/**
*
*
* @param link link
* @return Link
*/
@ -34,12 +37,14 @@ public interface LinkService {
/**
*
*
* @return List
*/
List<Link> findAllLinks();
/**
*
*
* @param linkId linkId
* @return Link
*/

View File

@ -1,6 +1,5 @@
package cc.ryanc.halo.service;
import cc.ryanc.halo.model.domain.Link;
import cc.ryanc.halo.model.domain.Logs;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
@ -17,6 +16,7 @@ public interface LogsService {
/**
*
*
* @param logs logs
* @return logs
*/
@ -35,6 +35,7 @@ public interface LogsService {
/**
*
*
* @param pageable pageable
* @return page
*/
@ -42,12 +43,14 @@ public interface LogsService {
/**
*
*
* @return list
*/
List<Logs> findLogsLatest();
/**
*
*
* @param logsId logsId
* @return logs
*/

View File

@ -0,0 +1,21 @@
package cc.ryanc.halo.service;
import cc.ryanc.halo.model.domain.Menu;
import java.util.List;
/**
* @author : RYAN0UP
* @version : 1.0
* description :
* @date : 2018/1/24
*/
public interface MenuService {
/**
*
*
* @return list
*/
List<Menu> findAllMenus();
}

View File

@ -15,6 +15,7 @@ public interface OptionsService {
/**
*
*
* @param key key
* @param value value
*/
@ -22,20 +23,28 @@ public interface OptionsService {
/**
*
*
* @param options options
*/
void saveOptions(Map<String,String> options);
/**
*
*
* @param options options
*/
void removeOption(Options options);
/**
*
*
* @return map
*/
Map<String,String> findAllOptions();
/**
* key
*
* @param key key
* @return String
*/

View File

@ -1,10 +0,0 @@
package cc.ryanc.halo.service;
/**
* @className: PostMetaService
* @author: RYAN0UP
* @date: 2017/11/14
* @description:
*/
public interface PostMetaService {
}

View File

@ -18,6 +18,7 @@ import java.util.List;
public interface PostService {
/**
*
*
* @param post Post
* @return Post
*/
@ -25,6 +26,7 @@ public interface PostService {
/**
*
*
* @param postId postId
* @return Post
*/
@ -32,6 +34,7 @@ public interface PostService {
/**
*
*
* @param post Post
* @return Post
*/
@ -39,6 +42,7 @@ public interface PostService {
/**
*
*
* @param postId postId
* @param status status
* @return Post
@ -47,12 +51,14 @@ public interface PostService {
/**
*
*
* @param postSummary postSummary
*/
void updateAllSummary(Integer postSummary);
/**
*
*
* @param pageable Pageable
* @return Page
*/
@ -60,18 +66,23 @@ public interface PostService {
/**
*
*
* @return List
*/
List<Post> findAllPosts();
/**
*
*
* @param keyWord keyword
* @param pageable pageable
* @return list
*/
List<Post> searchPosts(String keyWord,Pageable pageable);
/**
*
*
* @param status status
* @param pageable pageable
* @return page
@ -80,6 +91,7 @@ public interface PostService {
/**
*
*
* @param status status
* @return list
*/
@ -87,6 +99,7 @@ public interface PostService {
/**
*
*
* @param postId postId
* @return Post
*/
@ -94,6 +107,7 @@ public interface PostService {
/**
*
*
* @param postUrl postUrl
* @return post
*/
@ -101,12 +115,14 @@ public interface PostService {
/**
*
*
* @return List
*/
List<Post> findPostLatest();
/**
* Id
*
* @param postDate postDate
* @return post
*/
@ -114,6 +130,7 @@ public interface PostService {
/**
* Id
*
* @param postDate postDate
* @return list
*/
@ -121,12 +138,14 @@ public interface PostService {
/**
*
*
* @return List
*/
List<Archive> findPostGroupByPostDate();
/**
*
*
* @param year year
* @param month month
* @return list
@ -135,10 +154,27 @@ public interface PostService {
/**
*
*
* @param year year
* @param month month
* @param pageable pageable
* @return page
*/
Page<Post> findPostByYearAndMonth(@Param("year") String year, @Param("month") String month, Pageable pageable);
/**
* rss
*
* @param posts posts
* @return string
*/
String buildRss(List<Post> posts);
/**
* sitemap
*
* @param posts posts
* @return string
*/
String buildSiteMap(List<Post> posts);
}

View File

@ -14,6 +14,7 @@ public interface TagService {
/**
*
*
* @param tag tag
* @return Tag
*/
@ -21,6 +22,7 @@ public interface TagService {
/**
*
*
* @param tagId tagId
* @return Tag
*/
@ -28,6 +30,7 @@ public interface TagService {
/**
*
*
* @param tag tag
* @return tag
*/
@ -35,12 +38,14 @@ public interface TagService {
/**
*
*
* @return list
*/
List<Tag> findAllTags();
/**
*
*
* @param tagId tagId
* @return Link
*/
@ -48,6 +53,7 @@ public interface TagService {
/**
*
*
* @param tagUrl tagUrl
* @return tag
*/

View File

@ -1,33 +0,0 @@
package cc.ryanc.halo.service;
import cc.ryanc.halo.model.domain.UserMeta;
import java.util.List;
/**
* @author : RYAN0UP
* @version : 1.0
* @date : 2017/11/14
* description:
*/
public interface UserMetaService {
/**
*
* @param userMeta userMeta
*/
void saveByUserMeta(UserMeta userMeta);
/**
*
* @param userMetas userMeta
*/
void saveByUserMetas(List<UserMeta> userMetas);
/**
* userMetaKey
* @param key key
* @return userMeta
*/
UserMeta findByUserMetaKey(String key);
}

View File

@ -13,25 +13,38 @@ import java.util.List;
public interface UserService {
/**
*
*
* @param user user
*/
void saveByUser(User user);
/**
*
*
* @param userName userName
* @param userPass userPass
* @return User
*/
User userLogin(String userName,String userPass);
List<User> userLoginByName(String userName,String userPass);
/**
*
* @param userEmail userEmail
* @param userPass userPass
* @return list
*/
List<User> userLoginByEmail(String userEmail,String userPass);
/**
*
*
* @return list
*/
List<User> findAllUser();
/**
*
*
* @param userId userid
* @param userPass userpass
* @return user

View File

@ -22,8 +22,13 @@ public class AttachmentServiceImpl implements AttachmentService{
@Autowired
private AttachmentRepository attachmentRepository;
private static final String CATEGORY_KEY = "'category_key'";
private static final String CATEGORY_CACHE_NAME = "cateCache";
/**
*
*
* @param attachment attachment
* @return Attachment
*/
@ -32,21 +37,44 @@ public class AttachmentServiceImpl implements AttachmentService{
return attachmentRepository.save(attachment);
}
/**
*
*
* @return list
*/
@Override
public List<Attachment> findAllAttachments() {
return attachmentRepository.findAll();
}
/**
*
*
* @param pageable pageable
* @return page
*/
@Override
public Page<Attachment> findAllAttachments(Pageable pageable) {
return attachmentRepository.findAll(pageable);
}
/**
* id
*
* @param attachId attachId
* @return attachment
*/
@Override
public Attachment findByAttachId(Long attachId) {
return attachmentRepository.findOne(attachId);
}
/**
*
*
* @param attachId attachId
* @return attachment
*/
@Override
public Attachment removeByAttachId(Long attachId) {
Attachment attachment = this.findByAttachId(attachId);

View File

@ -28,10 +28,11 @@ public class CategoryServiceImpl implements CategoryService{
private static final String CATEGORY_KEY = "'category_key'";
private static final String CATEGORY_CACHE_NAME = "inkCache";
private static final String CATEGORY_CACHE_NAME = "cate_cache";
/**
*
*
* @param category
* @return ategory
*/
@ -43,6 +44,7 @@ public class CategoryServiceImpl implements CategoryService{
/**
*
*
* @param cateId
* @return Category
*/
@ -56,6 +58,7 @@ public class CategoryServiceImpl implements CategoryService{
/**
*
*
* @param category
* @return Category
*/
@ -68,6 +71,7 @@ public class CategoryServiceImpl implements CategoryService{
/**
*
*
* @return list
*/
@Cacheable(value = CATEGORY_CACHE_NAME,key = CATEGORY_KEY)
@ -78,6 +82,7 @@ public class CategoryServiceImpl implements CategoryService{
/**
*
*
* @param cateId
* @return Category
*/
@ -98,6 +103,7 @@ public class CategoryServiceImpl implements CategoryService{
return categoryRepository.findCategoryByCateUrl(cateUrl);
}
@Override
public List<Category> strListToCateList(List<String> strings) {
if(null==strings){

View File

@ -12,10 +12,10 @@ import org.springframework.stereotype.Service;
import java.util.List;
/**
* @className: LinkServiceImpl
* @author: RYAN0UP
* @date: 2017/11/14
* @description:
* @author : RYAN0UP
* @date : 2017/11/14
* @version : 1.0
* description:
*/
@Service
public class LinkServiceImpl implements LinkService {
@ -25,10 +25,11 @@ public class LinkServiceImpl implements LinkService {
private static final String LINK_KEY = "'link_key'";
private static final String LINK_CACHE_NAME = "inkCache";
private static final String LINK_CACHE_NAME = "link_cache";
/**
*
*
* @param link link
* @return Link
*/
@ -40,6 +41,7 @@ public class LinkServiceImpl implements LinkService {
/**
*
*
* @param linkId linkId
* @return link
*/
@ -53,6 +55,7 @@ public class LinkServiceImpl implements LinkService {
/**
*
*
* @param link link
* @return Link
*/
@ -65,6 +68,7 @@ public class LinkServiceImpl implements LinkService {
/**
*
*
* @return list
*/
@Cacheable(value = LINK_CACHE_NAME,key = LINK_KEY)
@ -75,6 +79,7 @@ public class LinkServiceImpl implements LinkService {
/**
*
*
* @param linkId linkId
* @return Link
*/

View File

@ -37,7 +37,6 @@ public class LogsServiceImpl implements LogsService {
*
*
* @param logsId logsId
* @return Logs
*/
@Override
public void removeByLogsId(Long logsId) {

View File

@ -0,0 +1,32 @@
package cc.ryanc.halo.service.impl;
import cc.ryanc.halo.model.domain.Menu;
import cc.ryanc.halo.repository.MenuRepository;
import cc.ryanc.halo.service.MenuService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* @author : RYAN0UP
* @version : 1.0
* description :
* @date : 2018/1/24
*/
@Service
public class MenuServiceImpl implements MenuService{
@Autowired
private MenuRepository menuRepository;
/**
*
*
* @return list
*/
@Override
public List<Menu> findAllMenus() {
return menuRepository.findAll();
}
}

View File

@ -31,6 +31,7 @@ public class OptionsServiceImpl implements OptionsService {
/**
*
*
* @param options options
*/
@CacheEvict(value = OPTIONS_CACHE_NAME,key = OPTIONS_KEY)
@ -43,6 +44,7 @@ public class OptionsServiceImpl implements OptionsService {
/**
*
*
* @param key key
* @param value value
*/
@ -73,6 +75,7 @@ public class OptionsServiceImpl implements OptionsService {
/**
*
*
* @param options options
*/
@CacheEvict(value = OPTIONS_CACHE_NAME,key = OPTIONS_KEY)
@ -83,6 +86,7 @@ public class OptionsServiceImpl implements OptionsService {
/**
*
*
* @return map
*/
@Cacheable(value = OPTIONS_CACHE_NAME,key = OPTIONS_KEY)
@ -98,6 +102,7 @@ public class OptionsServiceImpl implements OptionsService {
/**
* key
*
* @param key key
* @return String
*/

View File

@ -1,12 +0,0 @@
package cc.ryanc.halo.service.impl;
import cc.ryanc.halo.service.PostMetaService;
/**
* @className: PostMetaServiceImpl
* @author: RYAN0UP
* @date: 2017/11/14
* @description:
*/
public class PostMetaServiceImpl implements PostMetaService {
}

View File

@ -31,10 +31,11 @@ public class PostServiceImpl implements PostService {
private static final String POST_KEY = "'post_key'";
private static final String POST_CACHE_NAME = "inkCache";
private static final String POST_CACHE_NAME = "post_cache";
/**
*
*
* @param post Post
* @return Post
*/
@ -46,6 +47,7 @@ public class PostServiceImpl implements PostService {
/**
*
*
* @param postId postId
* @return Post
*/
@ -59,8 +61,9 @@ public class PostServiceImpl implements PostService {
/**
*
*
* @param post Post
* @return
* @return post
*/
@CacheEvict(value = POST_CACHE_NAME,key = POST_KEY)
@Override
@ -70,6 +73,7 @@ public class PostServiceImpl implements PostService {
/**
*
*
* @param postId postId
* @param status status
* @return Post
@ -84,6 +88,7 @@ public class PostServiceImpl implements PostService {
/**
*
*
* @param postSummary postSummary
*/
@CacheEvict(value = POST_CACHE_NAME,key = POST_KEY)
@ -100,6 +105,7 @@ public class PostServiceImpl implements PostService {
/**
*
*
* @param pageable Pageable
* @return Page
*/
@ -110,6 +116,7 @@ public class PostServiceImpl implements PostService {
/**
*
*
* @return List
*/
@Cacheable(value = POST_CACHE_NAME,key = POST_KEY)
@ -120,6 +127,7 @@ public class PostServiceImpl implements PostService {
/**
*
*
* @param keyWord keyword
* @param pageable pageable
* @return list
@ -131,6 +139,7 @@ public class PostServiceImpl implements PostService {
/**
*
*
* @param status status
* @param pageable pageable
* @return page
@ -143,6 +152,7 @@ public class PostServiceImpl implements PostService {
/**
*
*
* @param status status
* @return list
*/
@ -153,6 +163,7 @@ public class PostServiceImpl implements PostService {
/**
*
*
* @param postId postId
* @return post
*/
@ -164,10 +175,12 @@ public class PostServiceImpl implements PostService {
/**
*
*
* @param postUrl postUrl
* @return post
*/
@Override
@CacheEvict(value = POST_CACHE_NAME)
@Cacheable(value = POST_CACHE_NAME,key = "#postUrl+'post'")
public Post findByPostUrl(String postUrl) {
return postRepository.findPostByPostUrl(postUrl);
@ -175,6 +188,7 @@ public class PostServiceImpl implements PostService {
/**
* 5
*
* @return list
*/
@Override
@ -197,7 +211,7 @@ public class PostServiceImpl implements PostService {
* Id
*
* @param postId
* @return
* @return list
*/
@Override
public List<Post> findByPostDateBefore(Date postDate) {
@ -228,6 +242,7 @@ public class PostServiceImpl implements PostService {
/**
*
*
* @param year year
* @param month month
* @return list
@ -237,8 +252,43 @@ public class PostServiceImpl implements PostService {
return postRepository.findPostByYearAndMonth(year,month);
}
/**
*
* @param year year year
* @param month month month
* @param pageable pageable pageable
* @return page
*/
@Override
public Page<Post> findPostByYearAndMonth(String year, String month, Pageable pageable) {
return postRepository.findPostByYearAndMonth(year,month,pageable);
}
/**
* rss
*
* @param posts posts
* @return string
*/
@Override
public String buildRss(List<Post> posts) {
String rss = "";
try{
rss = HaloUtil.getRss(posts);
}catch (Exception e){
e.printStackTrace();
}
return rss;
}
/**
* sitemap
*
* @param posts posts
* @return string
*/
@Override
public String buildSiteMap(List<Post> posts) {
return HaloUtil.getSiteMap(posts);
}
}

View File

@ -20,6 +20,10 @@ public class TagServiceImpl implements TagService {
@Autowired
private TagRepository tagRepository;
private static final String CATEGORY_KEY = "'category_key'";
private static final String CATEGORY_CACHE_NAME = "cateCache";
/**
*
*

View File

@ -1,44 +0,0 @@
package cc.ryanc.halo.service.impl;
import cc.ryanc.halo.model.domain.UserMeta;
import cc.ryanc.halo.repository.UserMetaRepository;
import cc.ryanc.halo.service.UserMetaService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* @author : RYAN0UP
* @version : 1.0
* @date : 2017/11/14
* description:
*/
@Service
public class UserMetaServiceImpl implements UserMetaService {
@Autowired
private UserMetaRepository userMetaRepository;
@Override
public void saveByUserMeta(UserMeta userMeta) {
if(null==this.findByUserMetaKey(userMeta.getUserMetaKey())){
}
}
@Override
public void saveByUserMetas(List<UserMeta> userMetas) {
}
/**
* key
* @param key key
* @return
*/
@Override
public UserMeta findByUserMetaKey(String key) {
return userMetaRepository.findByUserMetaKey(key);
}
}

View File

@ -22,6 +22,7 @@ public class UserServiceImpl implements UserService {
/**
*
*
* @param user user
*/
@Override
@ -31,17 +32,31 @@ public class UserServiceImpl implements UserService {
/**
*
*
* @param userName userName
* @param userPass userPass
* @return user
*/
@Override
public User userLogin(String userName, String userPass) {
public List<User> userLoginByName(String userName, String userPass) {
return userRepository.findByUserNameAndUserPass(userName,userPass);
}
/**
*
*
* @param userEmail userEmail
* @param userPass userPass
* @return list
*/
@Override
public List<User> userLoginByEmail(String userEmail, String userPass) {
return userRepository.findByUserEmailAndUserPass(userEmail,userPass);
}
/**
*
*
* @return list
*/
@Override
@ -51,6 +66,7 @@ public class UserServiceImpl implements UserService {
/**
*
*
* @param userId userid
* @param userPass userpass
* @return User

View File

@ -238,13 +238,76 @@ public class HaloUtil {
return themes;
}
/**
*
* @param theme theme
* @return list
*/
public static List<String> getTplName (String theme){
List<String> tpls = new ArrayList<>();
try{
//获取项目根路径
File basePath = new File(ResourceUtils.getURL("classpath:").getPath());
//获取主题路径
File themesPath = new File(basePath.getAbsolutePath(),"templates/themes/"+theme);
File modulePath = new File(themesPath.getAbsolutePath(),"module");
File[] baseFiles = themesPath.listFiles();
File[] moduleFiles = modulePath.listFiles();
if(null!=moduleFiles) {
for (File file : moduleFiles) {
if (file.isFile()) {
if (file.getName().endsWith(".ftl")) {
tpls.add("module/" + file.getName());
}
}
}
}
if(null!=baseFiles){
for (File file:baseFiles){
if(file.isFile()) {
if (file.getName().endsWith(".ftl")) {
tpls.add(file.getName());
}
}
}
}
}catch (Exception e){
log.error("未知错误:"+e.getMessage());
}
return tpls;
}
/**
*
* @param filePath filePath
* @return string
*/
public static String getFileContent(String filePath){
File file = new File(filePath);
Long fileLength = file.length();
byte[] fileContent = new byte[fileLength.intValue()];
try{
FileInputStream inputStream = new FileInputStream(file);
inputStream.read(fileContent);
inputStream.close();
return new String(fileContent,"UTF-8");
}catch (Exception e){
log.error("读取模板文件错误:"+e.getMessage());
}
return null;
}
/**
*
* @param fileName fileName
* @return true or false
*/
public static boolean removeFile(String fileName){
File file = new File(fileName);
if(!file.exists()){
return false;
}else{
return file.delete();
if(file.exists() && file.delete()){
return true;
}
return false;
}
/**
@ -306,6 +369,10 @@ public class HaloUtil {
return md5;
}
public static void main(String[] args){
System.out.println(getMD5("123456"));
}
/**
* 216
* @param bytes bytes

View File

@ -1,15 +1,20 @@
package cc.ryanc.halo.web.controller;
import cc.ryanc.halo.model.domain.Comment;
import cc.ryanc.halo.model.domain.User;
import cc.ryanc.halo.service.CommentService;
import cc.ryanc.halo.service.PostService;
import cc.ryanc.halo.service.OptionsService;
import cc.ryanc.halo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.ui.Model;
import javax.servlet.http.HttpSession;
import java.util.List;
import java.util.Map;
/**
* @author : RYAN0UP
@ -27,17 +32,28 @@ public abstract class BaseController {
@Autowired
private CommentService commentService;
@Autowired
private OptionsService optionsService;
@Autowired
private UserService userService;
/**
*
*
*
* @param pageName pageName
* @return
*/
public String render(String pageName){
return "themes/"+THEME+"/"+pageName;
StringBuffer themeStr = new StringBuffer("themes/");
themeStr.append(THEME);
themeStr.append("/");
return themeStr.append(pageName).toString();
}
/**
*
*
* @param session session
*/
protected void getNewComments(HttpSession session){

View File

@ -1,8 +1,12 @@
package cc.ryanc.halo.web.controller;
import cc.ryanc.halo.model.dto.HaloConst;
import cc.ryanc.halo.service.OptionsService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.web.ErrorController;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import javax.servlet.http.HttpServletRequest;
@ -15,11 +19,19 @@ import javax.servlet.http.HttpServletRequest;
@Slf4j
@Controller
public class CommonController implements ErrorController{
private static final String ERROR_PATH = "/error";
/**
* 404500
*
* @param request request
* @return string
*/
@GetMapping(value = ERROR_PATH)
public String handleError(HttpServletRequest request){
public String handleError(HttpServletRequest request, Model model){
model.addAttribute("options", HaloConst.OPTIONS);
Integer statusCode = (Integer) request.getAttribute("javax.servlet.error.status_code");
if(statusCode==404) {
return "common/404";

View File

@ -48,11 +48,18 @@ public class IndexController extends BaseController{
@Autowired
private CommentService commentService;
@Autowired
private MenuService menuService;
@Autowired
private UserService userService;
@Autowired
private MailService mailService;
/**
*
*
* @param model model
* @return freemarker
*/
@ -64,6 +71,7 @@ public class IndexController extends BaseController{
/**
*
*
* @param model model
* @param page page
* @param size size
@ -84,16 +92,26 @@ public class IndexController extends BaseController{
Page<Post> posts = postService.findPostByStatus(0,pageable);
model.addAttribute("posts",posts);
//文章总数
model.addAttribute("postsCount",postService.findAllPosts().size());
model.addAttribute("is_home",true);
//系统设置
model.addAttribute("options",HaloConst.OPTIONS);
//用户信息
model.addAttribute("user",HaloConst.USER);
List<User> users = userService.findAllUser();
model.addAttribute("user",users.get(0));
//所有分类目录
List<Category> categories = categoryService.findAllCategories();
model.addAttribute("categories",categories);
//菜单列表
List<Menu> menus = menuService.findAllMenus();
model.addAttribute("menus",menus);
//归档数据,包含[year,month,count,List<Post>]
List<Archive> archives = postService.findPostGroupByPostDate();
model.addAttribute("archives",archives);
@ -102,8 +120,9 @@ public class IndexController extends BaseController{
/**
* ajax
* @param page
* @return
*
* @param page page
* @return list
*/
@GetMapping(value = "next")
@ResponseBody
@ -124,6 +143,7 @@ public class IndexController extends BaseController{
/**
*
*
* @param postId postId
* @param model model
* @return String
@ -151,11 +171,15 @@ public class IndexController extends BaseController{
}
model.addAttribute("post",post);
//文章总数
model.addAttribute("postsCount",postService.findAllPosts().size());
//系统设置
model.addAttribute("options",HaloConst.OPTIONS);
//用户信息
model.addAttribute("user",HaloConst.USER);
List<User> users = userService.findAllUser();
model.addAttribute("user",users.get(0));
//所有分类目录
List<Category> categories = categoryService.findAllCategories();
@ -164,6 +188,10 @@ public class IndexController extends BaseController{
//归档数据,包含[year,month,count,List<Post>]
List<Archive> archives = postService.findPostGroupByPostDate();
//菜单列表
List<Menu> menus = menuService.findAllMenus();
model.addAttribute("menus",menus);
//该文章的评论
Sort sort = new Sort(Sort.Direction.DESC,"commentDate");
Pageable pageable = new PageRequest(0,10,sort);
@ -176,6 +204,7 @@ public class IndexController extends BaseController{
/**
*
*
* @param model model
* @return string
*/
@ -190,6 +219,7 @@ public class IndexController extends BaseController{
/**
*
*
* @return String
*/
@GetMapping(value = "/gallery")
@ -201,6 +231,7 @@ public class IndexController extends BaseController{
/**
*
*
* @return string
*/
@GetMapping(value = "/links")
@ -213,7 +244,18 @@ public class IndexController extends BaseController{
//系统设置
model.addAttribute("options",HaloConst.OPTIONS);
model.addAttribute("user",HaloConst.USER);
//用户信息
List<User> users = userService.findAllUser();
model.addAttribute("user",users.get(0));
model.addAttribute("is_links",true);
//文章总数
model.addAttribute("postsCount",postService.findAllPosts().size());
//菜单列表
List<Menu> menus = menuService.findAllMenus();
model.addAttribute("menus",menus);
//所有分类目录
List<Category> categories = categoryService.findAllCategories();
@ -227,6 +269,7 @@ public class IndexController extends BaseController{
/**
*
*
* @param model model
* @return string
*/
@ -240,7 +283,15 @@ public class IndexController extends BaseController{
List<Category> categories = categoryService.findAllCategories();
model.addAttribute("categories",categories);
model.addAttribute("user",HaloConst.USER);
List<User> users = userService.findAllUser();
model.addAttribute("user",users.get(0));
//文章总数
model.addAttribute("postsCount",postService.findAllPosts().size());
//菜单列表
List<Menu> menus = menuService.findAllMenus();
model.addAttribute("menus",menus);
//归档数据,包含[year,month,count,List<Post>]
List<Archive> archives = postService.findPostGroupByPostDate();
@ -253,6 +304,7 @@ public class IndexController extends BaseController{
/**
*
*
* @param model model
* @param cateUrl cateUrl
* @return string
@ -266,6 +318,7 @@ public class IndexController extends BaseController{
/**
*
*
* @param model model
* @return string
*/
@ -276,6 +329,7 @@ public class IndexController extends BaseController{
/**
*
*
* @param model model
* @param page page
* @return string
@ -290,6 +344,11 @@ public class IndexController extends BaseController{
Page<Post> posts = postService.findPostByStatus(0,pageable);
model.addAttribute("posts",posts);
//文章总数
model.addAttribute("postsCount",postService.findAllPosts().size());
model.addAttribute("is_archives",true);
//包含[List<Post>,year,month,count]
List<Archive> archives = postService.findPostGroupByPostDate();
model.addAttribute("archives",archives);
@ -298,7 +357,12 @@ public class IndexController extends BaseController{
model.addAttribute("options",HaloConst.OPTIONS);
//用户信息
model.addAttribute("user",HaloConst.USER);
List<User> users = userService.findAllUser();
model.addAttribute("user",users.get(0));
//菜单列表
List<Menu> menus = menuService.findAllMenus();
model.addAttribute("menus",menus);
//所有分类目录
List<Category> categories = categoryService.findAllCategories();
@ -311,6 +375,7 @@ public class IndexController extends BaseController{
/**
*
*
* @param model model
* @param year year
* @param month month
@ -327,16 +392,24 @@ public class IndexController extends BaseController{
Page<Post> posts = postService.findPostByYearAndMonth(year,month,pageable);
model.addAttribute("posts",posts);
//文章总数
model.addAttribute("postsCount",postService.findAllPosts().size());
//系统设置
model.addAttribute("options",HaloConst.OPTIONS);
//用户信息
model.addAttribute("user",HaloConst.USER);
List<User> users = userService.findAllUser();
model.addAttribute("user",users.get(0));
//分类目录
List<Category> categories = categoryService.findAllCategories();
model.addAttribute("categories",categories);
//菜单列表
List<Menu> menus = menuService.findAllMenus();
model.addAttribute("menus",menus);
//归档数据,包含[year,month,count,List<Post>]
List<Archive> archives = postService.findPostGroupByPostDate();
model.addAttribute("archives",archives);
@ -348,6 +421,7 @@ public class IndexController extends BaseController{
/**
* rss
*
* @return rss
*/
@GetMapping(value = {"feed","feed.xml","atom.xml"},produces = { "application/xml;charset=UTF-8" })
@ -362,17 +436,12 @@ public class IndexController extends BaseController{
Pageable pageable = new PageRequest(0,Integer.parseInt(rssPosts),sort);
Page<Post> postsPage = postService.findPostByStatus(0,pageable);
List<Post> posts = postsPage.getContent();
String rss = "";
try {
rss = HaloUtil.getRss(posts);
}catch (Exception e){
e.printStackTrace();
}
return rss;
return postService.buildRss(posts);
}
/**
* sitemap
*
* @return sitemap
*/
@GetMapping(value = {"sitemap","sitemap.xml"},produces = { "application/xml;charset=UTF-8" })
@ -383,12 +452,13 @@ public class IndexController extends BaseController{
Pageable pageable = new PageRequest(0,999,sort);
Page<Post> postsPage = postService.findPostByStatus(0,pageable);
List<Post> posts = postsPage.getContent();
return HaloUtil.getSiteMap(posts);
return postService.buildSiteMap(posts);
}
/**
*
*
* @param comment comment
* @return string
*/

View File

@ -0,0 +1,138 @@
package cc.ryanc.halo.web.controller;
import cc.ryanc.halo.model.domain.Category;
import cc.ryanc.halo.model.domain.Logs;
import cc.ryanc.halo.model.domain.Post;
import cc.ryanc.halo.model.domain.User;
import cc.ryanc.halo.model.dto.HaloConst;
import cc.ryanc.halo.model.dto.LogsRecord;
import cc.ryanc.halo.service.*;
import cc.ryanc.halo.util.HaloUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.util.ResourceUtils;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
* @author : RYAN0UP
* @version : 1.0
* @date : 2018/1/28
* description :
*/
@Slf4j
@Controller
@RequestMapping(value = "/install")
public class InstallController {
@Autowired
private OptionsService optionsService;
@Autowired
private UserService userService;
@Autowired
private LogsService logsService;
@Autowired
private PostService postService;
@Autowired
private CategoryService categoryService;
/**
*
*
* @return string
*/
@GetMapping
public String install(){
return "common/install";
}
/**
*
*
* @return string
*/
@PostMapping(value = "/do")
@ResponseBody
public boolean doInstall(@RequestParam("siteTitle") String siteTitle,
@RequestParam("userName") String userName,
@RequestParam("userDisplayName") String userDisplayName,
@RequestParam("userEmail") String userEmail,
@RequestParam("userPwd") String userPwd,
HttpServletRequest request){
//创建install.lock文件
try{
File basePath = new File(ResourceUtils.getURL("classpath:").getPath());
File installFile = new File(basePath.getAbsolutePath(), "install.lock");
System.out.println(installFile.getAbsolutePath());
installFile.createNewFile();
//保存title设置
optionsService.saveOption("site_title",siteTitle);
//创建新的用户
User user= new User();
user.setUserName(userName);
user.setUserDisplayName(userDisplayName);
user.setUserEmail(userEmail);
user.setUserPass(HaloUtil.getMD5(userPwd));
userService.saveByUser(user);
//默认分类
Category category = new Category();
category.setCateName("未分类");
category.setCateUrl("default");
category.setCateDesc("未分类");
categoryService.saveByCategory(category);
//第一篇文章
Post post = new Post();
List<Category> categories = new ArrayList<>();
categories.add(category);
post.setPostTitle("Hello Halo!");
post.setPostContentMd("#Hello Halo!\n" +
"欢迎使用Halo进行创作删除这篇文章后赶紧开始吧。");
post.setPostContent("<h1 id=\"h1-hello-halo-\"><a name=\"Hello Halo!\" class=\"reference-link\"></a><span class=\"header-link octicon octicon-link\"></span>Hello Halo!</h1><p>欢迎使用Halo进行创作删除这篇文章后赶紧开始吧。</p>\n");
post.setPostSummary("欢迎使用Halo进行创作删除这篇文章后赶紧开始吧。");
post.setPostStatus(0);
post.setPostDate(new Date());
post.setPostUrl("hello-halo");
post.setUser(user);
post.setCategories(categories);
postService.saveByPost(post);
//设置默认主题
optionsService.saveOption("theme","halo");
//建立网站时间
optionsService.saveOption("site_start",HaloUtil.getStringDate("yyyy-MM-dd"));
//更新日志
logsService.saveByLogs(
new Logs(
LogsRecord.INSTALL,
"欢迎使用Halo",
HaloUtil.getIpAddr(request),
HaloUtil.getDate()
)
);
HaloConst.OPTIONS.clear();
HaloConst.OPTIONS = optionsService.findAllOptions();
}catch (Exception e){
log.error(e.getMessage());
return false;
}
return true;
}
}

View File

@ -27,6 +27,8 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.Date;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* @author : RYAN0UP
@ -56,6 +58,7 @@ public class AdminController extends BaseController{
/**
*
*
* @return freemarker
*/
@GetMapping(value = {"","/index"})
@ -63,15 +66,19 @@ public class AdminController extends BaseController{
//查询文章条数
Integer postCount = postService.findAllPosts().size();
model.addAttribute("postCount",postCount);
//查询评论的条数
Integer commentCount = commentService.findAllComments().size();
model.addAttribute("commentCount",commentCount);
//查询最新的文章
List<Post> postsLatest = postService.findPostLatest();
model.addAttribute("postTopFive",postsLatest);
//查询最新的日志
List<Logs> logsLatest = logsService.findLogsLatest();
model.addAttribute("logs",logsLatest);
//查询最新的评论
List<Comment> comments = commentService.findCommentsLatest();
model.addAttribute("comments",comments);
@ -79,11 +86,12 @@ public class AdminController extends BaseController{
model.addAttribute("options", HaloConst.OPTIONS);
model.addAttribute("mediaCount",HaloConst.ATTACHMENTS.size());
this.getNewComments(session);
return "admin/index";
return "admin/admin_index";
}
/**
*
*
* @return freemarker
*/
@GetMapping(value = "/login")
@ -93,11 +101,12 @@ public class AdminController extends BaseController{
if(null!=user){
return "redirect:/admin";
}
return "admin/login";
return "admin/admin_login";
}
/**
*
*
* @param loginName loginName
* @param loginPwd loginPwd
* @param session session
@ -109,10 +118,17 @@ public class AdminController extends BaseController{
@ModelAttribute("loginPwd") String loginPwd,
HttpSession session){
try {
User user = userService.userLogin(loginName, loginPwd);
if(null!=user){
session.setAttribute("user",user);
log.info("用户["+user.getUserName()+"]登录成功!");
List<User> users = null;
Pattern patternEmail = Pattern.compile("\\w[-\\w.+]*@([A-Za-z0-9][-A-Za-z0-9]+\\.)+[A-Za-z]{2,14}");
Matcher matcher = patternEmail.matcher(loginName);
if(matcher.find()){
users = userService.userLoginByEmail(loginName,HaloUtil.getMD5(loginPwd));
}else{
users = userService.userLoginByName(loginName,HaloUtil.getMD5(loginPwd));
}
if(null!=users){
session.setAttribute("user", users.get(0));
log.info("用户["+ users.get(0).getUserName()+"]登录成功!");
logsService.saveByLogs(new Logs(LogsRecord.LOGIN,LogsRecord.LOGIN_SUCCESS,HaloUtil.getIpAddr(request), HaloUtil.getDate()));
return RespStatus.SUCCESS;
}else{
@ -126,6 +142,7 @@ public class AdminController extends BaseController{
/**
* 退 session
*
* @param session session
* @return string
*/
@ -140,6 +157,7 @@ public class AdminController extends BaseController{
/**
*
*
* @param model model
* @param page page
* @param size size
@ -149,19 +167,16 @@ public class AdminController extends BaseController{
public String logs(Model model,
@RequestParam(value = "page",defaultValue = "0") Integer page,
@RequestParam(value = "size",defaultValue = "10") Integer size){
try {
Sort sort = new Sort(Sort.Direction.DESC,"logId");
Pageable pageable = new PageRequest(page,size,sort);
Page<Logs> logs = logsService.findAllLogs(pageable);
model.addAttribute("logs",logs);
}catch (Exception e){
log.error("未知错误:"+e.getMessage());
}
return "admin/widget/_logs-all";
}
/**
*
*
* @return return
*/
@GetMapping(value = "/logs/clear")
@ -176,12 +191,13 @@ public class AdminController extends BaseController{
/**
*
*
* @param model model
* @return string
*/
@GetMapping(value = "/halo")
public String halo(Model model){
model.addAttribute("options",HaloConst.OPTIONS);
return "admin/halo";
return "admin/admin_halo";
}
}

View File

@ -1,9 +1,12 @@
package cc.ryanc.halo.web.controller.admin;
import cc.ryanc.halo.model.domain.Attachment;
import cc.ryanc.halo.model.domain.Logs;
import cc.ryanc.halo.model.dto.HaloConst;
import cc.ryanc.halo.model.dto.LogsRecord;
import cc.ryanc.halo.model.dto.RespStatus;
import cc.ryanc.halo.service.AttachmentService;
import cc.ryanc.halo.service.LogsService;
import cc.ryanc.halo.util.HaloUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
@ -17,6 +20,7 @@ import org.springframework.util.ResourceUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import javax.websocket.server.PathParam;
import java.io.File;
@ -33,6 +37,10 @@ public class AttachmentController {
@Autowired
private AttachmentService attachmentService;
@Autowired
private LogsService logsService;
/**
* HaloConst
*/
@ -43,6 +51,7 @@ public class AttachmentController {
/**
* upload
*
* @param model model
* @return String
*/
@ -50,50 +59,49 @@ public class AttachmentController {
public String attachments(Model model,
@RequestParam(value = "page",defaultValue = "0") Integer page,
@RequestParam(value = "size",defaultValue = "18") Integer size){
try {
Sort sort = new Sort(Sort.Direction.DESC,"attachId");
Pageable pageable = new PageRequest(page,size,sort);
Page<Attachment> attachments = attachmentService.findAllAttachments(pageable);
model.addAttribute("attachments",attachments);
model.addAttribute("options", HaloConst.OPTIONS);
}catch (Exception e){
e.printStackTrace();
}
return "admin/attachment";
return "admin/admin_attachment";
}
/**
*
*
* @param model model
* @param page page
* @return string
*/
@GetMapping(value = "/select")
public String selectAttachment(Model model,
@RequestParam(value = "page",defaultValue = "0") Integer page){
try {
@RequestParam(value = "page",defaultValue = "0") Integer page,
@RequestParam(value = "id") String id){
Sort sort = new Sort(Sort.Direction.DESC,"attachId");
Pageable pageable = new PageRequest(page,18,sort);
Page<Attachment> attachments = attachmentService.findAllAttachments(pageable);
model.addAttribute("attachments",attachments);
}catch (Exception e){
e.printStackTrace();
}
model.addAttribute("id",id);
return "admin/widget/_attachment-select";
}
/**
*
*
* @param file file
*/
@PostMapping(value = "/upload",produces = { "application/json;charset=UTF-8" })
@ResponseBody
public boolean uploadAttachment(@RequestParam("file") MultipartFile file){
public boolean uploadAttachment(@RequestParam("file") MultipartFile file,
HttpServletRequest request){
if(!file.isEmpty()){
try{
File basePath = new File(ResourceUtils.getURL("classpath:").getPath());
File mediaPath = new File(basePath.getAbsolutePath(),"upload/"+ HaloUtil.YEAR+"/"+ HaloUtil.MONTH+"/");
StringBuffer sbMedia = new StringBuffer("upload/");
sbMedia.append(HaloUtil.YEAR).append("/").append(HaloUtil.MONTH).append("/");
File mediaPath = new File(basePath.getAbsolutePath(),sbMedia.toString());
if(!mediaPath.exists()){
mediaPath.mkdirs();
}
@ -105,18 +113,21 @@ public class AttachmentController {
//保存在数据库
Attachment attachment = new Attachment();
attachment.setAttachName(fileName);
attachment.setAttachPath("/upload/"+HaloUtil.YEAR+"/"+HaloUtil.MONTH+"/"+fileName);
attachment.setAttachSmallPath("/upload/"+HaloUtil.YEAR+"/"+HaloUtil.MONTH+"/"+nameWithOutSuffix+"_small."+fileSuffix);
attachment.setAttachPath(new StringBuffer("/upload/").append(HaloUtil.YEAR).append("/").append(HaloUtil.MONTH).append("/").append(fileName).toString());
attachment.setAttachSmallPath(new StringBuffer("/upload/").append(HaloUtil.YEAR).append("/").append(HaloUtil.MONTH).append("/").append(nameWithOutSuffix).append("_small.").append(fileSuffix).toString());
attachment.setAttachType(file.getContentType());
attachment.setAttachSuffix("."+fileSuffix);
attachment.setAttachSuffix(new StringBuffer(".").append(fileSuffix).toString());
attachment.setAttachCreated(HaloUtil.getDate());
attachmentService.saveByAttachment(attachment);
//剪裁图片
HaloUtil.cutCenterImage(mediaPath.getAbsolutePath()+"/"+fileName,mediaPath.getAbsolutePath()+"/"+nameWithOutSuffix+"_small."+fileSuffix,500,500,fileSuffix);
HaloUtil.cutCenterImage(new StringBuffer(mediaPath.getAbsolutePath()).append("/").append(fileName).toString(),new StringBuffer(mediaPath.getAbsolutePath()).append("/").append(nameWithOutSuffix).append("_small.").append(fileSuffix).toString(),500,500,fileSuffix);
updateConst();
log.info("上传文件["+file.getOriginalFilename()+"]到["+mediaPath.getAbsolutePath()+"]成功");
logsService.saveByLogs(
new Logs(LogsRecord.UPLOAD_FILE,file.getOriginalFilename(),HaloUtil.getIpAddr(request),HaloUtil.getDate())
);
return true;
}catch (Exception e){
log.error("未知错误:"+e.getMessage());
@ -129,6 +140,7 @@ public class AttachmentController {
/**
*
*
* @param attachId attachId
* @return string
*/
@ -141,12 +153,14 @@ public class AttachmentController {
/**
*
*
* @param attachId attachId
* @return string
*/
@GetMapping(value = "/remove")
@ResponseBody
public String removeAttachment(@PathParam("attachId") Long attachId){
public String removeAttachment(@PathParam("attachId") Long attachId,
HttpServletRequest request){
Attachment attachment = attachmentService.findByAttachId(attachId);
String delFileName = attachment.getAttachName();
String delSmallFileName = delFileName.substring(0,delFileName.lastIndexOf('.'))+"_small"+attachment.getAttachSuffix();
@ -158,12 +172,15 @@ public class AttachmentController {
//删除文件
File basePath = new File(ResourceUtils.getURL("classpath:").getPath());
File mediaPath = new File(basePath.getAbsolutePath(),attachment.getAttachPath().substring(0,attachment.getAttachPath().lastIndexOf('/')));
File delFile = new File(mediaPath.getAbsolutePath()+"/"+delFileName);
File delSmallFile = new File(mediaPath.getAbsolutePath()+"/"+delSmallFileName);
File delFile = new File(new StringBuffer(mediaPath.getAbsolutePath()).append("/").append(delFileName).toString());
File delSmallFile = new File(new StringBuffer(mediaPath.getAbsolutePath()).append("/").append(delSmallFileName).toString());
if(delFile.exists() && delFile.isFile()){
if(delFile.delete()&&delSmallFile.delete()){
updateConst();
log.info("删除文件["+delFileName+"]成功!");
logsService.saveByLogs(
new Logs(LogsRecord.REMOVE_FILE,delFileName,HaloUtil.getIpAddr(request),HaloUtil.getDate())
);
}else{
log.error("删除附件["+delFileName+"]失败!");
return RespStatus.ERROR;

View File

@ -32,17 +32,19 @@ public class BackupController {
/**
*
*
* @param model model
* @return return
*/
@GetMapping
public String backup(Model model){
model.addAttribute("options", HaloConst.OPTIONS);
return "admin/backup";
return "admin/admin_backup";
}
/**
*
*
* @return return
*/
@GetMapping(value = "/backupDb")
@ -60,6 +62,7 @@ public class BackupController {
/**
*
*
* @return return
*/
@GetMapping(value = "/backupRe")
@ -69,6 +72,7 @@ public class BackupController {
/**
* markdown
*
* @return return
*/
@GetMapping(value = "/backupPost")

View File

@ -29,6 +29,7 @@ public class CategoryController {
/**
* category
*
* @param model model
* @return freemarker
*/
@ -37,11 +38,12 @@ public class CategoryController {
List<Category> categories = categoryService.findAllCategories();
model.addAttribute("categories",categories);
model.addAttribute("options", HaloConst.OPTIONS);
return "admin/category";
return "admin/admin_category";
}
/**
*
*
* @param category category
* @return freemarker
*/
@ -58,6 +60,7 @@ public class CategoryController {
/**
*
*
* @param cateUrl cateUrl
* @return string
*/
@ -74,6 +77,7 @@ public class CategoryController {
/**
*
*
* @param cateId cateId
* @return freemarker
*/
@ -90,6 +94,7 @@ public class CategoryController {
/**
*
*
* @param category category
* @return redirect
*/
@ -107,6 +112,7 @@ public class CategoryController {
/**
*
*
* @param cateId cateId
* @param model model
* @return String
@ -121,6 +127,6 @@ public class CategoryController {
}catch (Exception e){
log.error("未知错误:"+e.getMessage());
}
return "admin/_cate-update";
return "admin/admin_cate-update";
}
}

View File

@ -4,8 +4,6 @@ import cc.ryanc.halo.model.domain.Comment;
import cc.ryanc.halo.model.dto.HaloConst;
import cc.ryanc.halo.service.CommentService;
import cc.ryanc.halo.service.MailService;
import cc.ryanc.halo.service.PostService;
import cc.ryanc.halo.util.HaloUtil;
import cc.ryanc.halo.web.controller.BaseController;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
@ -16,7 +14,6 @@ import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
@ -41,6 +38,7 @@ public class CommentController extends BaseController{
/**
*
*
* @param model model
* @param status status
* @param page page
@ -61,11 +59,12 @@ public class CommentController extends BaseController{
model.addAttribute("trashCount",commentService.findAllComments(2,pageable).getTotalElements());
model.addAttribute("status",status);
model.addAttribute("options", HaloConst.OPTIONS);
return "admin/comment";
return "admin/admin_comment";
}
/**
*
*
* @param commentId commentId
* @return string
*/
@ -83,9 +82,10 @@ public class CommentController extends BaseController{
/**
*
*
* @param commentId commentId
* @param status status
* @return
* @return string
*/
@GetMapping("/revert")
public String moveToPublish(@RequestParam("commentId") Long commentId,

View File

@ -0,0 +1,42 @@
package cc.ryanc.halo.web.controller.admin;
import cc.ryanc.halo.model.domain.Menu;
import cc.ryanc.halo.model.dto.HaloConst;
import cc.ryanc.halo.service.MenuService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import java.util.List;
/**
* @author : RYAN0UP
* @version : 1.0
* description :
* @date : 2018/1/30
*/
@Slf4j
@Controller
@RequestMapping(value = "/admin/menu")
public class MenuController {
@Autowired
private MenuService menuService;
/**
*
*
* @param model model
* @return string
*/
@GetMapping
public String menu(Model model){
model.addAttribute("options", HaloConst.OPTIONS);
List<Menu> menus = menuService.findAllMenus();
model.addAttribute("menus",menus);
return "/admin/admin_menu";
}
}

View File

@ -26,16 +26,18 @@ public class OptionController {
/**
* option
*
* @return freemarker
*/
@GetMapping
public String options(Model model){
model.addAttribute("options", HaloConst.OPTIONS);
return "admin/option";
return "admin/admin_option";
}
/**
*
*
* @param options options
*/
@PostMapping(value = "/save")

View File

@ -32,12 +32,41 @@ public class PageController {
@GetMapping
public String pages(Model model){
model.addAttribute("options", HaloConst.OPTIONS);
return "admin/page";
return "admin/admin_page";
}
/**
*
*
* @param map ModelMap
* @return String
*/
@GetMapping(value = "/links")
public String links(Model model){
List<Link> links = linkService.findAllLinks();
model.addAttribute("links",links);
model.addAttribute("options", HaloConst.OPTIONS);
return "admin/admin_link";
}
/**
*
*
* @param model model
* @param linkId linkId
* @return String
*/
@GetMapping("/links/edit")
public String toEditLink(Model model,@PathParam("linkId") Long linkId){
Link link = linkService.findByLinkId(linkId);
model.addAttribute("link",link);
model.addAttribute("options", HaloConst.OPTIONS);
return "admin/admin_link-update";
}
/**
*
*
* @param link Link
* @return freemarker
*/
@ -54,6 +83,7 @@ public class PageController {
/**
*
*
* @param linkId linkId
* @return String
*/
@ -70,6 +100,7 @@ public class PageController {
/**
*
*
* @param link Link
* @return freemarker
*/
@ -84,32 +115,4 @@ public class PageController {
}
return "redirect:/admin/page/links";
}
/**
*
* @param map ModelMap
* @return String
*/
@GetMapping(value = "/links")
public String links(Model model){
List<Link> links = linkService.findAllLinks();
model.addAttribute("links",links);
model.addAttribute("options", HaloConst.OPTIONS);
return "admin/link";
}
/**
*
* @param model model
* @param linkId linkId
* @return String
*/
@GetMapping("/links/edit")
public String toEditLink(Model model,@PathParam("linkId") Long linkId){
Link link = linkService.findByLinkId(linkId);
model.addAttribute("link",link);
model.addAttribute("options", HaloConst.OPTIONS);
log.info("linkId"+linkId+"的数据为:"+link);
return "admin/_link-update";
}
}

View File

@ -25,9 +25,7 @@ import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import javax.websocket.server.PathParam;
import java.util.Date;
import java.util.List;
import java.util.Set;
/**
* @author : RYAN0UP
@ -54,6 +52,7 @@ public class PostController extends BaseController{
/**
*
*
* @param model Model
* @param page Page
* @param size Size
@ -64,7 +63,6 @@ public class PostController extends BaseController{
@RequestParam(value = "status",defaultValue = "0") Integer status,
@RequestParam(value = "page",defaultValue = "0") Integer page,
@RequestParam(value = "size",defaultValue = "10") Integer size){
try {
Sort sort = new Sort(Sort.Direction.DESC,"postId");
Pageable pageable = new PageRequest(page,size,sort);
Page<Post> posts = postService.findPostByStatus(status,pageable);
@ -74,14 +72,13 @@ public class PostController extends BaseController{
model.addAttribute("trashCount",postService.findPostByStatus(2,pageable).getTotalElements());
model.addAttribute("options", HaloConst.OPTIONS);
model.addAttribute("status",status);
}catch (Exception e){
log.error("未知错误:"+e.getMessage());
}
return "admin/post";
return "admin/admin_post";
}
/**
*
*
* @param model Model
* @param keyword keyword
* @param page page
@ -102,11 +99,12 @@ public class PostController extends BaseController{
}catch (Exception e){
log.error("未知错误:"+e.getMessage());
}
return "admin/post";
return "admin/admin_post";
}
/**
*
*
* @param postId postId
* @param model model
* @return freemarker
@ -121,6 +119,7 @@ public class PostController extends BaseController{
/**
*
*
* @return freemarker
*/
@GetMapping(value = "/new")
@ -133,11 +132,12 @@ public class PostController extends BaseController{
}catch (Exception e){
log.error("未知错误:"+e.getMessage());
}
return "admin/editor";
return "admin/admin_editor";
}
/**
*
*
* @param post Post
*/
@PostMapping(value = "/new/push")
@ -156,7 +156,7 @@ public class PostController extends BaseController{
String summary = HaloUtil.getSummary(post.getPostContent(), postSummary);
post.setPostSummary(summary);
}
post.setPostDate(new Date());
post.setPostDate(HaloUtil.getDate());
//发表用户
User user = (User)session.getAttribute("user");
post.setUser(user);
@ -172,6 +172,7 @@ public class PostController extends BaseController{
/**
*
*
* @param postId postId
* @return String
*/
@ -188,6 +189,7 @@ public class PostController extends BaseController{
/**
*
*
* @param postId postId
* @return String
*/
@ -205,6 +207,7 @@ public class PostController extends BaseController{
/**
*
*
* @param postId postId
* @return
*/
@ -223,6 +226,7 @@ public class PostController extends BaseController{
/**
*
*
* @param postId postId
* @param model Model
* @return String
@ -239,11 +243,12 @@ public class PostController extends BaseController{
}catch (Exception e){
log.error("未知错误:"+e.getMessage());
}
return "admin/editor";
return "admin/admin_editor";
}
/**
*
*
* @param postSummary postSummary
* @return string
*/
@ -261,6 +266,7 @@ public class PostController extends BaseController{
/**
*
*
* @param postUrl postUrl
* @return String
*/

View File

@ -29,6 +29,7 @@ public class TagController {
/**
*
*
* @param model model
* @return string
*/
@ -37,11 +38,12 @@ public class TagController {
List<Tag> tags = tagService.findAllTags();
model.addAttribute("tags",tags);
model.addAttribute("options", HaloConst.OPTIONS);
return "admin/tag";
return "admin/admin_tag";
}
/**
*
*
* @param tag tag
* @return string
*/
@ -58,6 +60,7 @@ public class TagController {
/**
*
*
* @param tagUrl tagUrl
* @return string
*/
@ -74,6 +77,7 @@ public class TagController {
/**
*
*
* @param tagId tagId
* @return string
*/
@ -90,6 +94,7 @@ public class TagController {
/**
*
*
* @param model model
* @param tagId tagId
* @return string
@ -104,11 +109,12 @@ public class TagController {
}catch (Exception e){
log.error("未知错误:"+e.getMessage());
}
return "admin/_tag-update";
return "admin/admin_tag-update";
}
/**
*
*
* @param tag tag
* @return string
*/

View File

@ -1,19 +1,28 @@
package cc.ryanc.halo.web.controller.admin;
import cc.ryanc.halo.model.domain.Logs;
import cc.ryanc.halo.model.dto.HaloConst;
import cc.ryanc.halo.model.dto.LogsRecord;
import cc.ryanc.halo.model.dto.RespStatus;
import cc.ryanc.halo.service.LogsService;
import cc.ryanc.halo.service.OptionsService;
import cc.ryanc.halo.util.HaloUtil;
import cc.ryanc.halo.web.controller.BaseController;
import lombok.extern.slf4j.Slf4j;
import org.apache.catalina.servlet4preview.http.HttpServletRequest;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.ResourceUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.websocket.server.PathParam;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.List;
/**
* @author : RYAN0UP
@ -29,8 +38,12 @@ public class ThemeController extends BaseController{
@Autowired
private OptionsService optionsService;
@Autowired
private LogsService logsService;
/**
*
*
* @return String
*/
@GetMapping
@ -40,22 +53,27 @@ public class ThemeController extends BaseController{
model.addAttribute("themes",HaloConst.THEMES);
}
model.addAttribute("options", HaloConst.OPTIONS);
return "admin/theme";
return "admin/admin_theme";
}
/**
*
*
* @param siteTheme siteTheme
*/
@GetMapping(value = "/set")
@ResponseBody
public String activeTheme(@PathParam("siteTheme") String siteTheme){
public String activeTheme(@PathParam("siteTheme") String siteTheme,
HttpServletRequest request){
try {
//保存主题设置项在数据库
optionsService.saveOption("theme",siteTheme);
//设置主题
BaseController.THEME = siteTheme;
log.info("已将主题改变为:"+siteTheme);
logsService.saveByLogs(
new Logs(LogsRecord.CHANGE_THEME,"更换为"+siteTheme,HaloUtil.getIpAddr(request),HaloUtil.getDate())
);
return RespStatus.SUCCESS;
}catch (Exception e){
log.error("主题设置失败,当前主题为:"+BaseController.THEME);
@ -66,22 +84,26 @@ public class ThemeController extends BaseController{
/**
*
*
* @param file file
* @return String
*/
@RequestMapping(value = "/upload", method = RequestMethod.POST)
@ResponseBody
public boolean uploadTheme(@RequestParam("file") MultipartFile file){
public boolean uploadTheme(@RequestParam("file") MultipartFile file,
HttpServletRequest request){
try {
if(!file.isEmpty()) {
//获取项目根路径
File basePath = new File(ResourceUtils.getURL("classpath:").getPath());
File themePath = new File(basePath.getAbsolutePath(), "templates/themes/" + file.getOriginalFilename());
File themePath = new File(basePath.getAbsolutePath(), new StringBuffer("templates/themes/").append(file.getOriginalFilename()).toString());
file.transferTo(themePath);
log.info("上传主题成功,路径:" + themePath.getAbsolutePath());
logsService.saveByLogs(
new Logs(LogsRecord.UPLOAD_THEME,file.getOriginalFilename(),HaloUtil.getIpAddr(request),HaloUtil.getDate())
);
HaloUtil.unZip(themePath.getAbsolutePath(),new File(basePath.getAbsolutePath(),"templates/themes/").getAbsolutePath());
HaloUtil.removeFile(themePath.getAbsolutePath());
System.out.println(themePath);
HaloConst.THEMES.clear();
HaloConst.THEMES = HaloUtil.getThemes();
return true;
@ -96,6 +118,7 @@ public class ThemeController extends BaseController{
/**
*
*
* @param theme theme
*/
@GetMapping(value = "/options")
@ -104,4 +127,67 @@ public class ThemeController extends BaseController{
model.addAttribute("themeDir",theme);
return "themes/"+theme+"/module/options";
}
/**
*
*
* @return string
*/
@GetMapping(value = "/editor")
public String editor(Model model){
List<String> tpls = HaloUtil.getTplName(BaseController.THEME);
model.addAttribute("tpls",tpls);
model.addAttribute("options",HaloConst.OPTIONS);
return "admin/admin_theme-editor";
}
/**
*
*
* @return string
*/
@GetMapping(value = "/getTpl",produces = "text/text;charset=UTF-8")
@ResponseBody
public String getTplContent(@RequestParam("tplName") String tplName){
String tplContent = "";
try {
//获取项目根路径
File basePath = new File(ResourceUtils.getURL("classpath:").getPath());
//获取主题路径
File themesPath = new File(basePath.getAbsolutePath(),new StringBuffer("templates/themes/").append(BaseController.THEME).append("/").append(tplName).toString());
tplContent = HaloUtil.getFileContent(themesPath.getAbsolutePath());
}catch (Exception e){
log.error("获取模板文件错误:"+e.getMessage());
}
return tplContent;
}
/**
*
*
* @param tplName tplName
* @param tplContent tplContent
* @return string
*/
@PostMapping(value = "/editor/save")
@ResponseBody
public boolean saveTpl(@RequestParam("tplName") String tplName,
@RequestParam("tplContent") String tplContent){
System.out.println(tplContent);
if(StringUtils.isBlank(tplContent)){
return false;
}
try {
//获取项目根路径
File basePath = new File(ResourceUtils.getURL("classpath:").getPath());
//获取主题路径
File tplPath = new File(basePath.getAbsolutePath(),new StringBuffer("templates/themes/").append(BaseController.THEME).append("/").append(tplName).toString());
byte[] tplContentByte = tplContent.getBytes("UTF-8");
Files.write(Paths.get(tplPath.getAbsolutePath()),tplContentByte);
}catch (Exception e){
log.error("文件保存失败:"+e.getMessage());
return false;
}
return true;
}
}

View File

@ -29,17 +29,19 @@ public class UserController {
/**
*
*
* @return string
*/
@GetMapping
public String profile(Model model){
model.addAttribute("user",userService.findAllUser().get(0));
model.addAttribute("options", HaloConst.OPTIONS);
return "admin/profile";
return "admin/admin_profile";
}
/**
*
*
* @param user user
* @return String
*/
@ -49,7 +51,6 @@ public class UserController {
try{
if(null!=user){
userService.saveByUser(user);
HaloConst.USER = userService.findAllUser().get(0);
session.invalidate();
}else{
log.error("用户信息不能为空值");
@ -64,6 +65,7 @@ public class UserController {
/**
*
*
* @param beforePass
* @param newPass
* @return String

View File

@ -0,0 +1,40 @@
package cc.ryanc.halo.web.interceptor;
import org.springframework.stereotype.Component;
import org.springframework.util.ResourceUtils;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
/**
* @author : RYAN0UP
* @version : 1.0
* description :
* @date : 2018/1/28
*/
@Component
public class InstallInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object o) throws Exception {
File basePath = new File(ResourceUtils.getURL("classpath:").getPath());
File installFile = new File(basePath.getAbsolutePath(), "install.lock");
if(installFile.exists()){
return true;
}
response.sendRedirect("/install");
return false;
}
@Override
public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
}
@Override
public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
}
}

View File

@ -5,13 +5,22 @@ spring:
# 数据源配置 使用druid数据源
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/testdb?useUnicode=true&characterEncoding=utf8&useSSL=false
username: root
# H2database 配置
driver-class-name: org.h2.Driver
url: jdbc:h2:file:~/halo/halo_db
username: admin
password: 123456
#SQL脚本导入
#schema: classpath:/import.sql
#sql-script-encoding: utf-8
# MySQL配置
#driver-class-name: com.mysql.jdbc.Driver
#url: jdbc:mysql://localhost:3306/halodb?useUnicode=true&characterEncoding=utf8&useSSL=false
#username: root
#password: 123456
h2:
console:
settings:
web-allow-others: true
path: /h2-console
enabled: true
# jpa配置
jpa:
@ -33,19 +42,7 @@ spring:
http:
multipart:
max-file-size: 10Mb
max-request-size:
mail:
host: smtp.exmail.qq.com
username: i@ryanc.cc
password: Wangdashen666
properties:
mail:
smtp:
auth: true
starttls:
enable: true
required: true
# TODO config this ehcache
max-request-size: 10Mb
cache:
ehcache:
config: ehcache.xml

View File

@ -5,4 +5,4 @@ ${AnsiColor.BLUE}
/ __ / /_/ / / /_/ /
/_/ /_/\__,_/_/\____/
${AnsiColor.BRIGHT_YELLOW}
::: Halo (version:${application.version}) ::: Spring-Boot ${spring-boot.version}
::: Spring-Boot ${spring-boot.version} ::: Halo (version:${application.formatted-version})

View File

@ -13,7 +13,7 @@
memoryStoreEvictionPolicy="LRU" />
<cache
name="inkCache"
name="cate_cache"
eternal="false"
maxElementsInMemory="10000"
overflowToDisk="false"
@ -31,4 +31,24 @@
timeToIdleSeconds="0"
timeToLiveSeconds="300"
memoryStoreEvictionPolicy="LRU" />
<cache
name="link_cache"
eternal="false"
maxElementsInMemory="10000"
overflowToDisk="false"
diskPersistent="false"
timeToIdleSeconds="0"
timeToLiveSeconds="300"
memoryStoreEvictionPolicy="LRU" />
<cache
name="post_cache"
eternal="false"
maxElementsInMemory="10000"
overflowToDisk="false"
diskPersistent="false"
timeToIdleSeconds="0"
timeToLiveSeconds="300"
memoryStoreEvictionPolicy="LRU" />
</ehcache>

View File

@ -1,3 +0,0 @@
insert into options(option_name,option_value) values('site','Ryan0up Blog');
insert into options(option_name,option_value) values('keyword','Ryan0up,Ryan0up Blog');
insert into options(option_name,option_value) values('desc','我是Ryan');

View File

@ -12,7 +12,7 @@ function showMsg(text,icon,hideAfter) {
showHideTransition: 'fade',
allowToastClose: true,
hideAfter: hideAfter,
stack: 5,
stack: 1,
position: 'top-center',
textAlign: 'left',
loader: true,

View File

@ -17,13 +17,13 @@
.thumbnail{margin-bottom:0}
</style>
<section class="content-header">
<h1 style="display: inline-block;">媒体库</h1>
<h1 style="display: inline-block;">附件</h1>
<a id="showForm" href="#">
<i class="fa fa-cloud-upload" aria-hidden="true"></i>上传
</a>
<ol class="breadcrumb">
<li><a href="/admin"><i class="fa fa-dashboard"></i> 首页</a></li>
<li class="active">媒体库</li>
<li class="active">附件</li>
</ol>
</section>
<section class="content container-fluid">
@ -66,7 +66,7 @@
title: '附件详情',
shadeClose: true,
shade: 0.5,
area: ['66%', '66%'],
area: ['90%', '90%'],
content: '/admin/attachments/attachment?attachId='+id,
scrollbar: false
});

View File

@ -7,18 +7,21 @@
<#include "module/_sidebar.ftl">
<div class="content-wrapper">
<section class="content-header">
<h1 style="display: inline-block;">备份恢复</h1>
<h1 style="display: inline-block;">正在开发中...</h1>
<ol class="breadcrumb">
<li>
<a href="/admin"><i class="fa fa-dashboard"></i> 首页</a>
</li>
<li><a href="#">设置</a></li>
<li class="active">备份恢复</li>
</ol>
</section>
<!--
<section class="content container-fluid">
<a href="/admin/backup/backupDb">备份数据库</a>
<a href="/admin/backup/backupPost">备份文章</a>
</section>
-->
</div>
<#include "module/_footer.ftl">
</div>

View File

@ -18,6 +18,7 @@
<a href="/admin">
<i class="fa fa-dashboard"></i> 首页</a>
</li>
<li><a href="#">文章</a></li>
<li class="active">分类目录</li>
</ol>
</section>

View File

@ -0,0 +1,5 @@
<#if (options.post_editor?default('editor.md'))=='editor.md'>
<#include "admin_md-editor.ftl">
<#else >
<#include "admin_rt-editor.ftl">
</#if>

View File

@ -0,0 +1,40 @@
<#include "module/_macro.ftl">
<@head title="Halo后台管理-关于Halo"></@head>
<div class="wrapper">
<!-- 顶部栏模块 -->
<#include "module/_header.ftl">
<!-- 菜单栏模块 -->
<#include "module/_sidebar.ftl">
<div class="content-wrapper">
<style type='text/css'>
blockquote{
border-left: 4px solid #dddddd;
padding: 0 15px;
color: #777777;
}
</style>
<section class="content-header">
<h1 style="display: inline-block;">关于Halo</h1>
<ol class="breadcrumb">
<li>
<a href="/admin"><i class="fa fa-dashboard"></i> 首页</a>
</li>
<li class="active">关于Halo</li>
</ol>
</section>
<section class="content container-fluid">
<div id='write' class='is-mac'>
<blockquote>
<p>一款使用Java开发的简约&quot;轻&quot;,快的博客系统。</p>
<p>非常感谢你使用Halo进行创作。</p>
</blockquote>
<p>目前该博客系统为beta测试版有可能会出现一些莫名奇妙的bug所以希望各位在使用过程中及时向我反馈</p>
<p>Github issues <a href='https://github.com/ruibaby/halo'>https://github.com/ruibaby/halo</a></p>
<p>Email : <a href='mailto:i@ryanc.cc'>i@ryanc.cc</a></p>
<p>QQ : 709831589</p>
</div>
</section>
</div>
<#include "module/_footer.ftl">
</div>
<@footer></@footer>

View File

@ -71,13 +71,13 @@
</div>
</div>
<div class="form-group">
<label for="widgetVisitorCount" class="col-sm-4 control-label">访客总数:</label>
<label for="widgetDayCount" class="col-sm-4 control-label">成立天数:</label>
<div class="col-sm-8">
<label class="radio-inline">
<input type="radio" name="widget_visitorcount" id="widgetVisitorCount" value="true" ${((options.widget_visitorcount?default('true'))=='true')?string('checked','')}> 显示
<input type="radio" name="widget_daycount" id="widgetDayCount" value="true" ${((options.widget_daycount?default('true'))=='true')?string('checked','')}> 显示
</label>
<label class="radio-inline">
<input type="radio" name="widget_visitorcount" id="widgetVisitorCount" value="false" ${((options.widget_visitorcount?default('true'))=='false')?string('checked','')}> 隐藏
<input type="radio" name="widget_daycount" id="widgetDayCount" value="false" ${((options.widget_daycount?default('true'))=='false')?string('checked','')}> 隐藏
</label>
</div>
</div>
@ -151,18 +151,18 @@
<div class="small-box bg-yellow">
<div class="inner"><h3>${mediaCount?default(0)}</h3><p>媒体库</p></div>
<div class="icon"><i class="ion ion-person-add"></i></div>
<a href="/admin/attachments" class="small-box-footer">上传图片<i class="fa fa-arrow-circle-right"></i></a>
<a href="/admin/attachments" class="small-box-footer">上传图片 <i class="fa fa-arrow-circle-right"></i></a>
</div>
</div>
</#if>
<!-- ./col -->
<#if options.widget_visitorcount?default("true")=="true">
<div class="col-lg-3 col-xs-6" id="widgetVisitorCountBody">
<#if options.widget_daycount?default("true")=="true">
<div class="col-lg-3 col-xs-6" id="widgetDayCountBody">
<!-- small box -->
<div class="small-box bg-red">
<div class="inner"><h3>65</h3><p>今日访客</p></div>
<div class="inner"><h3 id="siteStart">1</h3><p>成立天数</p></div>
<div class="icon"><i class="ion ion-pie-graph"></i></div>
<a href="#" class="small-box-footer">清空数据 <i class="fa fa-arrow-circle-right"></i></a>
<a href="#" class="small-box-footer">${options.site_start?default('0000-00-00')} <i class="fa fa-star"></i></a>
</div>
</div>
</#if>
@ -329,6 +329,13 @@
<script src="/static/plugins/toast/js/jquery.toast.min.js"></script>
<script src="/static/plugins/layer/layer.js"></script>
<script type="application/javascript">
$(document).ready(function () {
var dateBegin = new Date("${options.site_start?default('0000-00-00')}");
var dateEnd = new Date();
var parseDate = dateEnd.getTime() - dateBegin.getTime();
var days = Math.floor(parseDate/(24*3600*1000));
$('#siteStart').html(days+1);
});
function openAllLogs() {
layer.open({
type: 2,
@ -357,7 +364,7 @@
showHideTransition: 'fade',
allowToastClose: true,
hideAfter: 1000,
stack: 5,
stack: 1,
position: 'top-center',
textAlign: 'left',
loader: true,

View File

@ -15,19 +15,19 @@
</style>
</head>
<body>
<div class="container login-form animated fadeInDown">
<div class="login-logo">
<div class="container login-form">
<div class="login-logo animated fadeInUp">
Halo
</div>
<div class="login-body">
<div class="login-body animated">
<form>
<div class="form-group">
<input type="text" class="form-control" name="loginName" id="login-name" placeholder="用户名" value="admin">
<div class="form-group animated fadeInUp" style="animation-delay: 0.1s">
<input type="text" class="form-control" name="loginName" id="login-name" placeholder="用户名/邮箱">
</div>
<div class="form-group">
<input type="password" class="form-control" name="loginPwd" id="login-pwd" placeholder="密码" value="123456">
<div class="form-group animated fadeInUp" style="animation-delay: 0.2s">
<input type="password" class="form-control" name="loginPwd" id="login-pwd" placeholder="密码">
</div>
<div class="row control">
<div class="row control animated fadeInUp" style="animation-delay: 0.3s">
<div class="col-xs-6">
<label for="remember"><input type="checkbox" id="remember"> <span style="color: #000;font-weight: lighter">记住我</span></label>
</div>
@ -35,7 +35,7 @@
<a href="#" style="color: #000;">忘记密码?</a>
</div>
</div>
<button type="button" id="btn-login" data-loading-text="登录中..." class="btn btn-block login-button" onclick="btn_login()">登录</button>
<button type="button" id="btn-login" data-loading-text="登录中..." class="btn btn-block login-button animated fadeInUp" onclick="btn_login()" style="animation-delay: 0.4s">登录</button>
</form>
</div>
</div>
@ -80,7 +80,27 @@
window.location.href="/admin";
}
});
}else if(data=="wait"){
$('.login-body').addClass('animate shake');
$.toast({
text: "密码错误已达到5次请30分钟后再试",
heading: '提示',
icon: 'error',
showHideTransition: 'fade',
allowToastClose: true,
hideAfter: 2000,
stack: 1,
position: 'top-center',
textAlign: 'left',
loader: true,
loaderBg: '#ffffff',
afterHidden: function () {
$('.login-body').removeClass('animate shake');
}
});
$('#btn-login').button('reset');
}else{
$('.login-body').addClass('animate shake');
$.toast({
text: "用户名或者密码错误!",
heading: '提示',
@ -92,7 +112,10 @@
position: 'top-center',
textAlign: 'left',
loader: true,
loaderBg: '#ffffff'
loaderBg: '#ffffff',
afterHidden: function () {
$('.login-body').removeClass('animate shake');
}
});
$('#btn-login').button('reset');
}

View File

@ -237,7 +237,7 @@
showHideTransition: 'fade',
allowToastClose: true,
hideAfter: 1000,
stack: 5,
stack: 1,
position: 'top-center',
textAlign: 'left',
loader: true,

View File

@ -0,0 +1,89 @@
<#include "module/_macro.ftl">
<@head title="Halo后台管理-菜单设置"></@head>
<div class="wrapper">
<!-- 顶部栏模块 -->
<#include "module/_header.ftl">
<!-- 菜单栏模块 -->
<#include "module/_sidebar.ftl">
<div class="content-wrapper">
<section class="content-header">
<h1 style="display: inline-block;">菜单设置</h1>
<ol class="breadcrumb">
<li>
<a href="/admin"><i class="fa fa-dashboard"></i> 首页</a>
</li>
<li><a href="#">外观</a></li>
<li class="active">菜单设置</li>
</ol>
</section>
<section class="content container-fluid">
<div class="row">
<div class="col-md-5">
<div class="box box-primary">
<div class="box-header with-border">
<h3 class="box-title">添加分类目录</h3>
</div>
<form action="/admin/category/save" method="post" role="form" id="cateAddForm" onsubmit="return checkCate()">
<div class="box-body">
<div class="form-group">
<label for="exampleInputEmail1">名称</label>
<input type="text" class="form-control" id="cateName" name="cateName" placeholder="">
<small>页面上所显示的名称</small>
</div>
<div class="form-group">
<label for="exampleInputPassword1">路径名称</label>
<input type="text" class="form-control" id="cateUrl" name="cateUrl" placeholder="">
<small>*这是文章路径上显示的名称,最好为英文</small>
</div>
<div class="form-group">
<label for="cateDesc" class="control-label">描述</label>
<textarea class="form-control" rows="3" id="cateDesc" name="cateDesc" style="resize: none"></textarea>
<small>*添加描述,部分主题可显示</small>
</div>
</div>
<div class="box-footer">
<button type="submit" class="btn btn-primary btn-flat">确定添加</button>
</div>
</form>
</div>
</div>
<div class="col-md-7">
<div class="box box-primary">
<div class="box-header with-border">
<h3 class="box-title">所有菜单选项</h3>
</div>
<div class="box-body table-responsive">
<table class="table table-hover">
<thead>
<tr>
<th>名称</th>
<th>路径</th>
<th>排序</th>
<th>图标</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<#list menus as menu>
<tr>
<td>${menu.menuName}</td>
<td>${menu.menuUrl}</td>
<td>${(menu.menuSort)!}</td>
<td>${menu.menuIcon}</td>
<td>
<a href="#" class="btn btn-primary btn-xs btn-flat">修改</a>
<button class="btn btn-danger btn-xs btn-flat" onclick="modelShow()">删除</button>
</td>
</tr>
</#list>
</tbody>
</table>
</div>
</div>
</div>
</div>
</section>
</div>
<#include "module/_footer.ftl">
</div>
<@footer></@footer>

View File

@ -26,7 +26,8 @@
<a href="/admin">
<i class="fa fa-dashboard"></i> 首页</a>
</li>
<li class="active">设置</li>
<li><a href="#">设置</a></li>
<li class="active">网站设置</li>
</ol>
</section>
<!-- tab选项卡 -->

View File

@ -21,7 +21,8 @@
<li>
<a href="/admin"><i class="fa fa-dashboard"></i> 首页</a>
</li>
<li class="active">页面</li>
<li><a href="#">页面</a></li>
<li class="active">所有页面</li>
</ol>
</section>
<section class="content container-fluid">

View File

@ -23,10 +23,13 @@
<a href="/admin">
<i class="fa fa-dashboard"></i> 首页</a>
</li>
<li class="active">文章</li>
<li><a href="#">文章</a></li>
<li class="active">所有文章</li>
</ol>
</section>
<section class="content container-fluid">
<div class="row">
<div class="col-xs-12">
<ul style="list-style: none;padding-left: 0">
<li class="publish">
<a href="/admin/posts">已发布<span class="count">(${publishCount})</span></a>&nbsp;|&nbsp;
@ -38,7 +41,7 @@
<a href="/admin/posts?status=2">回收站<span class="count">(${trashCount})</span></a>
</li>
</ul>
<div class="row">
</div>
<div class="col-xs-12">
<div class="box box-primary">
<div class="box-body table-responsive">

View File

@ -23,6 +23,7 @@
<a href="/admin">
<i class="fa fa-dashboard"></i> 首页</a>
</li>
<li><a href="#">用户</a></li>
<li class="active">个人资料</li>
</ol>
</section>
@ -75,9 +76,9 @@
<label for="userAvatar" class="col-sm-2 control-label">头像:</label>
<div class="col-sm-4">
<div class="input-group">
<input type="text" class="form-control selectData" id="userAvatar" name="userAvatar" value="${user.userAvatar?if_exists}">
<input type="text" class="form-control" id="userAvatar" name="userAvatar" value="${user.userAvatar?if_exists}">
<span class="input-group-btn">
<button class="btn btn-default btn-flat" type="button" onclick="openAttach()">选择</button>
<button class="btn btn-default btn-flat" type="button" onclick="openAttach('userAvatar')">选择</button>
</span>
</div>
</div>
@ -138,14 +139,14 @@
$(function () {
$('[data-toggle="tooltip"]').tooltip()
});
function openAttach() {
function openAttach(id) {
layer.open({
type: 2,
title: '所有附件',
shadeClose: true,
shade: 0.5,
area: ['90%', '90%'],
content: '/admin/attachments/select',
content: '/admin/attachments/select?id='+id,
scrollbar: false
});
}
@ -164,7 +165,7 @@
showHideTransition: 'fade',
allowToastClose: true,
hideAfter: 1000,
stack: 5,
stack: 1,
position: 'top-center',
textAlign: 'left',
loader: true,
@ -205,7 +206,7 @@
showHideTransition: 'fade',
allowToastClose: true,
hideAfter: 1000,
stack: 5,
stack: 1,
position: 'top-center',
textAlign: 'left',
loader: true,

View File

@ -19,6 +19,7 @@
<a href="#">
<i class="fa fa-dashboard"></i> 首页</a>
</li>
<li><a href="#">文章</a></li>
<li class="active">标签</li>
</ol>
</section>

View File

@ -0,0 +1,174 @@
<#include "module/_macro.ftl">
<@head title="Halo后台管理-主题编辑"></@head>
<div class="wrapper">
<!-- 顶部栏模块 -->
<#include "module/_header.ftl">
<!-- 菜单栏模块 -->
<#include "module/_sidebar.ftl">
<div class="content-wrapper">
<link rel="stylesheet" href="/static/plugins/toast/css/jquery.toast.min.css">
<link rel="stylesheet" href="/static/plugins/editor.md/css/editormd.min.css">
<section class="content-header">
<h1 style="display: inline-block;">主题编辑</h1>
<ol class="breadcrumb">
<li>
<a href="/admin"><i class="fa fa-dashboard"></i> 首页</a>
</li>
<li><a href="#">外观</a></li>
<li class="active">主题编辑</li>
</ol>
</section>
<section class="content container-fluid">
<div class="row">
<div class="col-md-9">
<div class="box box-primary">
<div class="box-header with-border">
<h3 class="box-title" id="tplNameTitle"></h3>
</div>
<div class="box-body">
<div id="theme-editor">
<textarea style="display:none;" id="tplContent"></textarea>
</div>
</div>
<div class="box-footer">
<button type="button" class="btn btn-primary btn-flat" onclick="saveTpl()">确定修改</button>
</div>
</div>
</div>
<div class="col-md-3">
<div class="box box-primary">
<div class="box-header with-border">
<h3 class="box-title">${options.theme?default('halo')}主题</h3>
</div>
<div class="box-body table-responsive">
<div class="table-responsive mailbox-messages">
<table class="table table-hover table-striped">
<tbody>
<#list tpls as tpl>
<tr style="cursor: pointer">
<td class="mailbox-name" onclick="loadContent('${tpl}')"><a href="#">${tpl}</a></td>
<td class="mailbox-subject">
<#switch tpl>
<#case "index.ftl">
首页
<#break >
<#case "post.ftl">
文章内容
<#break >
<#case "archives.ftl">
文章归档
<#break >
<#case "links.ftl">
友情链接
<#break >
<#case "module/macro.ftl">
宏模板
<#break >
</#switch>
</td>
</tr>
</#list>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</section>
<script src="/static/plugins/toast/js/jquery.toast.min.js"></script>
<script>
var editor;
function loadEditor() {
$.getScript("/static/plugins/editor.md/editormd.min.js",function () {
editor = editormd("theme-editor", {
width: "100%",
height: 620,
syncScrolling: "single",
path: "/static/plugins/editor.md/lib/",
watch : false,
toolbar : false,
codeFold : true,
searchReplace : true,
placeholder : "Enjoy coding!",
value : (localStorage.mode) ? $("#"+localStorage.mode.replace("text/", "")+"-code").val() : $("#html-code").val(),
theme : (localStorage.theme) ? localStorage.theme : "default",
mode : (localStorage.mode) ? localStorage.mode : "text/html"
});
});
}
$(document).ready(function () {
loadEditor();
});
<#if options.admin_pjax?default("true") == "true">
$(document).on('pjax:complete',function () {
loadEditor();
});
</#if>
function loadContent(tplName) {
if (tplName && tplName != '') {
$.ajax({
type: 'GET',
url: '/admin/themes/getTpl',
async: false,
data: {
tplName: tplName
},
success: function (data) {
editor.setValue(data);
$('#tplNameTitle').html(tplName);
}
});
} else {
editor.setValue('');
$('#tplNameTitle').html('');
}
}
function saveTpl() {
$.ajax({
type: 'POST',
url: '/admin/themes/editor/save',
async: false,
data:{
'tplName': $('#tplNameTitle').html(),
'tplContent': editor.getValue()
},
success: function (data) {
if(data==true){
$.toast({
text: "保存成功!",
heading: '提示',
icon: 'success',
showHideTransition: 'fade',
allowToastClose: true,
hideAfter: 1000,
stack: 1,
position: 'top-center',
textAlign: 'left',
loader: true,
loaderBg: '#ffffff'
});
}else{
$.toast({
text: "保存失败!",
heading: '提示',
icon: 'error',
showHideTransition: 'fade',
allowToastClose: true,
hideAfter: 2000,
stack: 1,
position: 'top-center',
textAlign: 'left',
loader: true,
loaderBg: '#ffffff'
});
}
}
});
}
</script>
</div>
<#include "module/_footer.ftl">
</div>
<@footer></@footer>

View File

@ -66,6 +66,7 @@
</a>
<ol class="breadcrumb">
<li><a href="/admin"><i class="fa fa-dashboard"></i> 首页</a></li>
<li><a href="#">外观</a></li>
<li class="active">主题设置</li>
</ol>
</section>
@ -86,13 +87,13 @@
<div class="box box-solid">
<div class="box-body theme-thumbnail" style="background-image: url(/${theme.themeName?if_exists}/screenshot.png)"></div>
<div class="box-footer">
<span class="theme-title">${theme.themeName?if_exists}</span>
<span class="theme-title">${theme.themeName?if_exists?upper_case}</span>
<#if theme.hasOptions==true>
<button class="btn btn-primary btn-sm pull-right btn-flat" onclick="openSetting('${theme.themeName?if_exists}')">设置</button>
</#if>
<#if activeTheme == "${theme.themeName?if_exists}">
<#if activeTheme == "${theme.themeName}">
<button class="btn btn-primary btn-sm pull-right btn-flat" disabled>已启用</button>
<#else >
<#else>
<button onclick="setTheme('${theme.themeName?if_exists}')" class="btn btn-primary btn-sm pull-right btn-flat">启用</button>
</#if>
</div>
@ -178,7 +179,7 @@
showHideTransition: 'fade',
allowToastClose: true,
hideAfter: 1000,
stack: 5,
stack: 1,
position: 'top-center',
textAlign: 'left',
loader: true,

View File

@ -1,5 +0,0 @@
<#if (options.post_editor?default('editor.md'))=='editor.md'>
<#include "_md-editor.ftl">
<#else >
<#include "_rt-editor.ftl">
</#if>

View File

@ -1,26 +0,0 @@
<#include "module/_macro.ftl">
<@head title="Halo后台管理-关于Halo"></@head>
<div class="wrapper">
<!-- 顶部栏模块 -->
<#include "module/_header.ftl">
<!-- 菜单栏模块 -->
<#include "module/_sidebar.ftl">
<div class="content-wrapper">
<section class="content-header">
<h1 style="display: inline-block;">关于Halo</h1>
<ol class="breadcrumb">
<li>
<a href="/admin"><i class="fa fa-dashboard"></i> 首页</a>
</li>
<li class="active">关于Halo</li>
</ol>
</section>
<section class="content container-fluid">
<p>
非常感谢你使用Halo进行创作。
</p>
</section>
</div>
<#include "module/_footer.ftl">
</div>
<@footer></@footer>

View File

@ -79,8 +79,8 @@
</a>
<ul class="treeview-menu">
<li><a href="/admin/themes"><i class="fa fa-circle-o"></i>主题</a></li>
<li><a href="/admin/themes"><i class="fa fa-circle-o"></i>菜单</a></li>
<li><a href="#"><i class="fa fa-circle-o"></i>自定义</a></li>
<li><a href="/admin/menu"><i class="fa fa-circle-o"></i>菜单</a></li>
<li><a href="/admin/themes/editor"><i class="fa fa-circle-o"></i>自定义</a></li>
</ul>
</li>
<li class="treeview">

View File

@ -102,7 +102,7 @@
showHideTransition: 'fade',
allowToastClose: true,
hideAfter: 1000,
stack: 5,
stack: 1,
position: 'top-center',
textAlign: 'left',
loader: true,

View File

@ -97,7 +97,7 @@
}
});
function doTransport(url) {
parent.$('.selectData').val(url);
parent.$('#${id}').val(url);
parent.layer.closeAll();
}
</script>

View File

@ -10,7 +10,7 @@
<link href="https://cdn.bootcss.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet">
<link href="https://cdn.bootcss.com/animate.css/3.5.2/animate.min.css" rel="stylesheet">
<style type="text/css" rel="stylesheet">
body{margin:0}*{box-sizing:border-box}h1,h2{margin:0}a{color:#fff;text-decoration:none}body,html{font-family:-apple-system,system-ui,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,sans-serif}.fullscreen{background-position:50% 50%;background-size:cover}.fullscreen,.fullscreen .backColor{position:absolute;top:0;left:0;width:100%;height:100%}.fullscreen .backColor{background-color:rgba(0,0,0,.1)}.infos{display:flex;text-align:center;align-items:center;justify-content:center}.infos,.main-content{position:absolute;top:0;left:0;width:100%;height:100%;color:#fff}.main-content{background-color:#000}.errorPage{position:relative;width:100vw;height:100vh}.infos-h1{margin:0;font-size:5em;line-height:1}.infos-h1 h1{font-weight:200}.footer{position:absolute;right:1rem;bottom:1rem;left:1rem;z-index:9999;font-size:14px}.infos-h2{font-size:24px}.infos-h2 a:hover{color:#7a8d85}
body{margin:0}*{box-sizing:border-box}h1,h2{margin:0}a{color:#fff;text-decoration:none}body,html{font-family:-apple-system,system-ui,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,sans-serif}.fullscreen{background-position:50% 50%;background-size:cover}.fullscreen,.fullscreen .backColor{position:absolute;top:0;left:0;width:100%;height:100%}.fullscreen .backColor{background-color:rgba(0,0,0,.1)}.infos{display:flex;text-align:center;align-items:center;justify-content:center}.infos,.main-content{position:absolute;top:0;left:0;width:100%;height:100%;color:#fff}.main-content{background: #833ab4;background: -webkit-linear-gradient(to right, #833ab4, #fd1d1d, #fcb045);background: linear-gradient(to right, #833ab4, #fd1d1d, #fcb045);}.errorPage{position:relative;width:100vw;height:100vh}.infos-h1{margin:0;font-size:5em;line-height:1}.infos-h1 h1{font-weight:200}.footer{position:absolute;right:1rem;bottom:1rem;left:1rem;z-index:9999;font-size:14px}.infos-h2{font-size:24px}.infos-h2 a:hover{color:#7a8d85}
</style>
</head>
<body>
@ -34,10 +34,10 @@
</div>
</div>
<div class="footer">
<span>Copyright © 2016</span>
<a href="https://ryanc.cc">Ryan0up'S Blog</a>
<span>Copyright © 2018</span>
<a href="https://ryanc.cc">${options.site_title?default('Halo')}</a>
<span style="float: right">
背景来自<a href="https://cn.bing.com/" target="_blank">Bing</a>
Background image from <a href="https://cn.bing.com/" target="_blank">Bing</a>.
</span>
</div>
</div>

View File

@ -1,10 +1,54 @@
<#compress>
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<title>500</title>
<meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1">
<meta name="renderer" content="webkit">
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
<title>500 Error Page</title>
<link href="https://cdn.bootcss.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet">
<link href="https://cdn.bootcss.com/animate.css/3.5.2/animate.min.css" rel="stylesheet">
<style type="text/css" rel="stylesheet">
body{margin:0}*{box-sizing:border-box}h1,h2{margin:0}a{color:#fff;text-decoration:none}body,html{font-family:-apple-system,system-ui,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,sans-serif}.fullscreen{background-position:50% 50%;background-size:cover}.fullscreen,.fullscreen .backColor{position:absolute;top:0;left:0;width:100%;height:100%}.fullscreen .backColor{background-color:rgba(0,0,0,.1)}.infos{display:flex;text-align:center;align-items:center;justify-content:center}.infos,.main-content{position:absolute;top:0;left:0;width:100%;height:100%;color:#fff}.main-content{background: #833ab4;background: -webkit-linear-gradient(to right, #833ab4, #fd1d1d, #fcb045);background: linear-gradient(to right, #833ab4, #fd1d1d, #fcb045);}.errorPage{position:relative;width:100vw;height:100vh}.infos-h1{margin:0;font-size:5em;line-height:1}.infos-h1 h1{font-weight:200}.footer{position:absolute;right:1rem;bottom:1rem;left:1rem;z-index:9999;font-size:14px}.infos-h2{font-size:24px}.infos-h2 a:hover{color:#7a8d85}
</style>
</head>
<body>
<h1>500错误</h1>
<div class="container">
<div class="errorPage">
<div class="main-content ">
<div class="fullscreen">
<div class="backColor"></div>
</div>
<div class="infos">
<div class="infos-main">
<div class="infos-h1"><h1>500内部错误</h1></div>
<div class="infos-h2">
<a href="javascript:window.history.back()" title="返回上一页">
<i class="fa fa-chevron-left"></i>
</a>
<a href="/" title="返回到主页">
<i class="fa fa-home"></i>
</a>
</div>
</div>
</div>
<div class="footer">
<span>Copyright © 2018</span>
<a href="https://ryanc.cc">${options.site_title?default('Halo')}</a>
<span style="float: right">
Background image from <a href="https://cn.bing.com/" target="_blank">Bing</a>.
</span>
</div>
</div>
</div>
</div>
</body>
<script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script>
<@compress single_line=true>
<script>
eval(function(p,a,c,k,e,r){e=function(c){return(c<a?'':e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)r[e(c)]=k[c]||e(c);k=[function(e){return r[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('$.o(\'m://q.8.n/?1=4%y%z%B.5.9%d.e%f%g%h%i%j%k\',l(b){6 a=b.p[0].1;6 c=$(\'.r\');c.t("u-v","1(4://s.w.5.x"+a+")");c.2(\'3 A\');$(\'.7-C\').2(\'3 D\');$(\'.7-E\').2(\'3 F\')});',42,42,'|url|addClass|animated|http|bing|var|infos|afeld|com||||2FHPImageArchive|aspx|3Fformat|3Djs|26idx|3D0|26n|3D1|function|https|me|get|images|jsonp|fullscreen||css|background|image|cn|net|3A|2F|fadeIn|2Fcn|h1|shake|h2|fadeInDown'.split('|'),0,{}))
</script>
</@compress>
</html>
</#compress>

View File

@ -0,0 +1,144 @@
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1">
<meta name="renderer" content="webkit">
<meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" name="viewport">
<title>Halo安装向导</title>
<link rel="stylesheet" href="/static/plugins/bootstrap/css/bootstrap.min.css">
<link rel="stylesheet" href="/static/css/AdminLTE.min.css">
<link rel="stylesheet" href="/static/plugins/animate/animate.min.css">
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
<![endif]-->
<style>
body{
background-color: #f5f5f5;
}
.vertical-center{
position: absolute;
top: 40%;
left: 50%;
transform: translate(-50%, -60%);
}
.form-horizontal .control-label{
text-align: left;
}
.logo{font-size:56px;text-align:center;margin-bottom:25px;font-weight:500;color:#444;text-shadow:#b2baba .1em .1em .2em;}
</style>
</head>
<body>
<div class="container">
<div class="row row-centered">
<div class="col-lg-4 vertical-center">
<div class="logo animated fadeInUp">
Halo<small style="font-size: 14px;">安装向导</small>
</div>
<form method="post" class="form-horizontal" id="installForm">
<div class="box box-solid animated" id="installFirst">
<div class="box-body" style="padding: 30px;">
<div class="form-group animated fadeInUp" style="animation-delay: 0.1s">
<label for="siteTitle" class="col-sm-4 control-label">网站标题:</label>
<div class="col-sm-8">
<input type="text" class="form-control" id="siteTitle" name="siteTitle">
</div>
</div>
<div class="form-group animated fadeInUp" style="animation-delay: 0.2s">
<label for="userEmail" class="col-sm-4 control-label">电子邮箱:
<span data-toggle="tooltip" data-placement="top" title="重要,将用于找回密码" style="cursor: pointer">
<i class="fa fa-question-circle" aria-hidden="true"></i>
</span>
</label>
<div class="col-sm-8">
<input type="text" class="form-control" id="userEmail" name="userEmail">
</div>
</div>
<div class="form-group animated fadeInUp" style="animation-delay: 0.3s">
<label for="userName" class="col-sm-4 control-label">用户名:
<span data-toggle="tooltip" data-placement="top" title="用于登录后台" style="cursor: pointer">
<i class="fa fa-question-circle" aria-hidden="true"></i>
</span>
</label>
<div class="col-sm-8">
<input type="text" class="form-control" id="userName" name="userName">
</div>
</div>
<div class="form-group animated fadeInUp" style="animation-delay: 0.4s">
<label for="userDisplayName" class="col-sm-4 control-label">显示昵称:
<span data-toggle="tooltip" data-placement="top" title="主题或后台显示的名称" style="cursor: pointer">
<i class="fa fa-question-circle" aria-hidden="true"></i>
</span>
</label>
<div class="col-sm-8">
<input type="text" class="form-control" id="userDisplayName" name="userDisplayName">
</div>
</div>
<div class="form-group animated fadeInUp" style="animation-delay: 0.5s">
<label for="userPwd" class="col-sm-4 control-label">登录密码:</label>
<div class="col-sm-8">
<input type="password" class="form-control" id="userPwd" name="userPwd">
</div>
</div>
<div class="form-group animated fadeInUp" style="animation-delay: 0.6s">
<label for="userRePwd" class="col-sm-4 control-label">确认密码:</label>
<div class="col-sm-8">
<input type="password" class="form-control" id="userRePwd">
</div>
</div>
</div>
<div class="box-footer" style="padding-right: 30px;">
<button type="button" class="btn btn-primary btn-sm btn-flat pull-right animated fadeInUp" onclick="doInstall()" style="animation-delay: 0.9s">安装Halo</button>
</div>
</div>
<div class="box box-solid animated fadeInUp" style="display: none" id="installSuccess">
<div class="box-body">
<h2>安装成功!</h2>
<h4>你可以选择进入前台,或者登陆后台!</h4>
</div>
<div class="box-footer" style="padding-right: 30px;">
<a class="btn btn-primary btn-sm btn-flat" href="/">前台</a>
<a class="btn btn-primary btn-sm btn-flat" href="/admin/login">登录后台</a>
</div>
</div>
<div class="box box-solid animated fadeInUp" style="display: none" id="installError">
<div class="box-body">
<h2>安装失败!</h2>
<h4>请返回安装页面尝试重新安装!</h4>
</div>
<div class="box-footer" style="padding-right: 30px;">
<a class="btn btn-primary btn-sm btn-flat" href="/install">返回</a>
</div>
</div>
</form>
</div>
</div>
</div>
</body>
<script src="/static/plugins/jquery/jquery.min.js"></script>
<script src="/static/plugins/bootstrap/js/bootstrap.min.js"></script>
<script src="/static/js/adminlte.min.js"></script>
<script>
$(function () {
$('[data-toggle="tooltip"]').tooltip()
});
function doInstall() {
var param = $('#installForm').serialize();
$.ajax({
type: 'post',
url: '/install/do',
data: param,
success: function (data) {
if(data==true){
$('#installFirst').hide();
$('#installSuccess').show();
}else{
$('#installFirst').hide();
$('#installError').show();
}
}
});
}
</script>
</html>

View File

@ -1,4 +1,4 @@
<#include "module/marco.ftl">
<#include "module/macro.ftl">
<@head title="归档 · ${options.site_title?default('Anatole')}" keywords="文章归档,${options.seo_keywords?default('Anatole')}" description="${options.seo_desc?default('Anatole')}"></@head>
<#include "module/sidebar.ftl">
<div class="main">

View File

@ -1,4 +1,4 @@
<#include "module/marco.ftl">
<#include "module/macro.ftl">
<@head title="${options.site_title?default('Anatole')}" keywords="${options.seo_keywords?default('Anatole')}" description="${options.seo_desc?default('Anatole')}"></@head>
<#include "module/sidebar.ftl">
<div class="main">

View File

@ -1,4 +1,4 @@
<#include "module/marco.ftl">
<#include "module/macro.ftl">
<@head title="友情链接 · ${options.site_title?default('Anatole')}" keywords="${options.seo_keywords?default('Anatole')}" description="${options.seo_desc?default('Anatole')}"></@head>
<#include "module/sidebar.ftl">
<div class="main">

View File

@ -1,16 +1,16 @@
<div class="page-top animated fadeInDown">
<div class="nav">
<li>
<a href="/" class="current">Home </a>
<a href="/" <#if is_home?default(false)==true>class="current"</#if>>Home </a>
</li>
<li>
<a href="/about">About</a>
</li>
<li>
<a href="/archives">Archive</a>
<a href="/archives" <#if is_archives?default(false)==true>class="current"</#if>>Archive</a>
</li>
<li>
<a href="/links">Links</a>
<a href="/links" <#if is_links?default(false)==true>class="current"</#if>>Links</a>
</li>
</div>
<div class="information">

View File

@ -1,4 +1,4 @@
<#include "module/marco.ftl">
<#include "module/macro.ftl">
<@head title="${post.postTitle} · ${options.site_title?default('Anatole')}" keywords="${post.postTitle},${options.seo_keywords?default('Anatole')}" description="${options.seo_desc?default('Anatole')}"></@head>
<#include "module/sidebar.ftl">
<div class="main">

View File

@ -1,5 +1,5 @@
<#list posts.content as post>
<div class="post_entry-module mdl-card mdl-shadow--2dp mdl-cell mdl-cell--12-col fade out">
<div class="post_entry-module mdl-card mdl-shadow--${options.theme_material_uiux_card_elevation?default(2)}dp mdl-cell mdl-cell--12-col fade out">
<!-- Post_entry Header -->
<!-- Post Header Info -->
<div class="post_entry-header_info without-thumbnail">

Some files were not shown because too many files have changed in this diff Show More