mirror of https://github.com/halo-dev/halo
Complete ArchiveController#listYearArchives
parent
1468307620
commit
3c70b83c1d
|
@ -63,7 +63,7 @@ public class SwaggerConfiguration {
|
||||||
public Docket haloDefaultApi() {
|
public Docket haloDefaultApi() {
|
||||||
log.debug("Doc disabled: [{}]", haloProperties.getDocDisabled());
|
log.debug("Doc disabled: [{}]", haloProperties.getDocDisabled());
|
||||||
return buildApiDocket("cc.ryanc.halo.default",
|
return buildApiDocket("cc.ryanc.halo.default",
|
||||||
"cc.ryanc.halo.web.controller.api",
|
"cc.ryanc.halo.web.controller.portal.api",
|
||||||
"/api/**")
|
"/api/**")
|
||||||
.enable(!haloProperties.getDocDisabled());
|
.enable(!haloProperties.getDocDisabled());
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
package cc.ryanc.halo.model.vo;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import lombok.ToString;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Archive vo.
|
||||||
|
*
|
||||||
|
* @author johnniang
|
||||||
|
* @date 4/2/19
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@ToString(callSuper = true)
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
public class ArchiveMonthVO extends ArchiveYearVO {
|
||||||
|
|
||||||
|
private Integer month;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int compare(ArchiveYearVO current, ArchiveYearVO other) {
|
||||||
|
int compare = super.compare(current, other);
|
||||||
|
|
||||||
|
if (compare != 0) {
|
||||||
|
return compare;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ((ArchiveMonthVO) current).month - ((ArchiveMonthVO) other).month;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
package cc.ryanc.halo.model.vo;
|
||||||
|
|
||||||
|
import cc.ryanc.halo.model.dto.post.PostMinimalOutputDTO;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import lombok.ToString;
|
||||||
|
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Archive vo.
|
||||||
|
*
|
||||||
|
* @author johnniang
|
||||||
|
* @date 4/2/19
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@ToString
|
||||||
|
@EqualsAndHashCode
|
||||||
|
public class ArchiveYearVO implements Comparator<ArchiveYearVO> {
|
||||||
|
|
||||||
|
private Integer year;
|
||||||
|
|
||||||
|
private List<PostMinimalOutputDTO> posts;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int compare(ArchiveYearVO current, ArchiveYearVO other) {
|
||||||
|
return current.year - other.year;
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,9 +4,11 @@ import cc.ryanc.halo.model.entity.BasePost;
|
||||||
import cc.ryanc.halo.model.enums.PostStatus;
|
import cc.ryanc.halo.model.enums.PostStatus;
|
||||||
import org.springframework.data.domain.Page;
|
import org.springframework.data.domain.Page;
|
||||||
import org.springframework.data.domain.Pageable;
|
import org.springframework.data.domain.Pageable;
|
||||||
|
import org.springframework.data.domain.Sort;
|
||||||
import org.springframework.data.repository.NoRepositoryBean;
|
import org.springframework.data.repository.NoRepositoryBean;
|
||||||
import org.springframework.lang.NonNull;
|
import org.springframework.lang.NonNull;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -19,15 +21,34 @@ import java.util.Optional;
|
||||||
public interface BasePostRepository<DOMAIN extends BasePost> extends BaseRepository<DOMAIN, Integer> {
|
public interface BasePostRepository<DOMAIN extends BasePost> extends BaseRepository<DOMAIN, Integer> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Finds posts by status and type.
|
* Finds posts by status and pageable.
|
||||||
*
|
*
|
||||||
* @param status status
|
* @param status post status must not be null
|
||||||
* @param pageable pageable
|
* @param pageable page info must not be null
|
||||||
* @return Page<Post>
|
* @return a page of post
|
||||||
*/
|
*/
|
||||||
@NonNull
|
@NonNull
|
||||||
Page<DOMAIN> findAllByStatus(@NonNull PostStatus status, @NonNull Pageable pageable);
|
Page<DOMAIN> findAllByStatus(@NonNull PostStatus status, @NonNull Pageable pageable);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finds posts by status.
|
||||||
|
*
|
||||||
|
* @param status post staus must not be null
|
||||||
|
* @return a list of post
|
||||||
|
*/
|
||||||
|
@NonNull
|
||||||
|
List<DOMAIN> findAllByStatus(@NonNull PostStatus status);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finds posts by status.
|
||||||
|
*
|
||||||
|
* @param status post staus must not be null
|
||||||
|
* @param sort sort info must not be null
|
||||||
|
* @return a list of post
|
||||||
|
*/
|
||||||
|
@NonNull
|
||||||
|
List<DOMAIN> findAllByStatus(@NonNull PostStatus status, @NonNull Sort sort);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Counts posts by status and type.
|
* Counts posts by status and type.
|
||||||
*
|
*
|
||||||
|
|
|
@ -4,6 +4,8 @@ import cc.ryanc.halo.model.dto.post.PostMinimalOutputDTO;
|
||||||
import cc.ryanc.halo.model.dto.post.PostSimpleOutputDTO;
|
import cc.ryanc.halo.model.dto.post.PostSimpleOutputDTO;
|
||||||
import cc.ryanc.halo.model.entity.Post;
|
import cc.ryanc.halo.model.entity.Post;
|
||||||
import cc.ryanc.halo.model.enums.PostStatus;
|
import cc.ryanc.halo.model.enums.PostStatus;
|
||||||
|
import cc.ryanc.halo.model.vo.ArchiveMonthVO;
|
||||||
|
import cc.ryanc.halo.model.vo.ArchiveYearVO;
|
||||||
import cc.ryanc.halo.model.vo.PostDetailVO;
|
import cc.ryanc.halo.model.vo.PostDetailVO;
|
||||||
import cc.ryanc.halo.model.vo.PostListVO;
|
import cc.ryanc.halo.model.vo.PostListVO;
|
||||||
import cc.ryanc.halo.service.base.CrudService;
|
import cc.ryanc.halo.service.base.CrudService;
|
||||||
|
@ -12,6 +14,7 @@ import org.springframework.data.domain.Pageable;
|
||||||
import org.springframework.lang.NonNull;
|
import org.springframework.lang.NonNull;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -144,4 +147,20 @@ public interface PostService extends CrudService<Post, Integer> {
|
||||||
* @return like total number
|
* @return like total number
|
||||||
*/
|
*/
|
||||||
long countLike();
|
long countLike();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lists year archives.
|
||||||
|
*
|
||||||
|
* @return a list of year archive
|
||||||
|
*/
|
||||||
|
@NonNull
|
||||||
|
List<ArchiveYearVO> listYearArchives();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lists month archives.
|
||||||
|
*
|
||||||
|
* @return a list of month archive
|
||||||
|
*/
|
||||||
|
@NonNull
|
||||||
|
List<ArchiveMonthVO> listMonthArchives();
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,6 +58,7 @@ public class OptionServiceImpl extends AbstractCrudService<Option, Integer> impl
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO Consider cache options with map
|
||||||
Option option = optionRepository.findByOptionKey(key).map(anOption -> {
|
Option option = optionRepository.findByOptionKey(key).map(anOption -> {
|
||||||
// Exist
|
// Exist
|
||||||
anOption.setOptionValue(value);
|
anOption.setOptionValue(value);
|
||||||
|
@ -87,6 +88,7 @@ public class OptionServiceImpl extends AbstractCrudService<Option, Integer> impl
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO Optimize the queries
|
||||||
options.forEach((key, value) -> save(key, value, source));
|
options.forEach((key, value) -> save(key, value, source));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -121,7 +123,7 @@ public class OptionServiceImpl extends AbstractCrudService<Option, Integer> impl
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<OptionOutputDTO> listDtos() {
|
public List<OptionOutputDTO> listDtos() {
|
||||||
return listAll().stream().map(option -> (OptionOutputDTO) new OptionOutputDTO().convertFrom(option)).collect(Collectors.toList());
|
return listAll().stream().map(option -> new OptionOutputDTO().<OptionOutputDTO>convertFrom(option)).collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -72,7 +72,8 @@ public class PostCategoryServiceImpl extends AbstractCrudService<PostCategory, I
|
||||||
Map<Integer, List<Category>> categoryListMap = new HashMap<>();
|
Map<Integer, List<Category>> categoryListMap = new HashMap<>();
|
||||||
|
|
||||||
// Foreach and collect
|
// Foreach and collect
|
||||||
postCategories.forEach(postCategory -> categoryListMap.computeIfAbsent(postCategory.getPostId(), postId -> new LinkedList<>()).add(categoryMap.get(postCategory.getCategoryId())));
|
postCategories.forEach(postCategory -> categoryListMap.computeIfAbsent(postCategory.getPostId(), postId -> new LinkedList<>())
|
||||||
|
.add(categoryMap.get(postCategory.getCategoryId())));
|
||||||
|
|
||||||
return categoryListMap;
|
return categoryListMap;
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,8 @@ import cc.ryanc.halo.model.dto.post.PostMinimalOutputDTO;
|
||||||
import cc.ryanc.halo.model.dto.post.PostSimpleOutputDTO;
|
import cc.ryanc.halo.model.dto.post.PostSimpleOutputDTO;
|
||||||
import cc.ryanc.halo.model.entity.*;
|
import cc.ryanc.halo.model.entity.*;
|
||||||
import cc.ryanc.halo.model.enums.PostStatus;
|
import cc.ryanc.halo.model.enums.PostStatus;
|
||||||
|
import cc.ryanc.halo.model.vo.ArchiveMonthVO;
|
||||||
|
import cc.ryanc.halo.model.vo.ArchiveYearVO;
|
||||||
import cc.ryanc.halo.model.vo.PostDetailVO;
|
import cc.ryanc.halo.model.vo.PostDetailVO;
|
||||||
import cc.ryanc.halo.model.vo.PostListVO;
|
import cc.ryanc.halo.model.vo.PostListVO;
|
||||||
import cc.ryanc.halo.repository.PostRepository;
|
import cc.ryanc.halo.repository.PostRepository;
|
||||||
|
@ -26,12 +28,15 @@ import org.springframework.lang.Nullable;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
|
import org.springframework.util.CollectionUtils;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import static org.springframework.data.domain.Sort.Direction.DESC;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Post service implementation.
|
* Post service implementation.
|
||||||
*
|
*
|
||||||
|
@ -83,7 +88,7 @@ public class PostServiceImpl extends AbstractCrudService<Post, Integer> implemen
|
||||||
public Page<Post> pageLatest(int top) {
|
public Page<Post> pageLatest(int top) {
|
||||||
Assert.isTrue(top > 0, "Top number must not be less than 0");
|
Assert.isTrue(top > 0, "Top number must not be less than 0");
|
||||||
|
|
||||||
PageRequest latestPageable = PageRequest.of(0, top, Sort.by(Sort.Direction.DESC, "editTime"));
|
PageRequest latestPageable = PageRequest.of(0, top, Sort.by(DESC, "editTime"));
|
||||||
|
|
||||||
return listAll(latestPageable);
|
return listAll(latestPageable);
|
||||||
}
|
}
|
||||||
|
@ -253,6 +258,41 @@ public class PostServiceImpl extends AbstractCrudService<Post, Integer> implemen
|
||||||
return Optional.ofNullable(postRepository.countLike()).orElse(0L);
|
return Optional.ofNullable(postRepository.countLike()).orElse(0L);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<ArchiveYearVO> listYearArchives() {
|
||||||
|
// Get all posts
|
||||||
|
List<Post> posts = postRepository.findAllByStatus(PostStatus.PUBLISHED, Sort.by(DESC, "createTime"));
|
||||||
|
|
||||||
|
Map<Integer, List<Post>> yearPostMap = new HashMap<>();
|
||||||
|
|
||||||
|
posts.forEach(post -> {
|
||||||
|
Calendar calendar = DateUtils.convertTo(post.getCreateTime());
|
||||||
|
yearPostMap.computeIfAbsent(calendar.get(Calendar.YEAR), year -> new LinkedList<>())
|
||||||
|
.add(post);
|
||||||
|
});
|
||||||
|
|
||||||
|
List<ArchiveYearVO> archives = new LinkedList<>();
|
||||||
|
|
||||||
|
yearPostMap.forEach((year, postList) -> {
|
||||||
|
// Build archive
|
||||||
|
ArchiveYearVO archive = new ArchiveYearVO();
|
||||||
|
archive.setYear(year);
|
||||||
|
archive.setPosts(convertTo(postList));
|
||||||
|
|
||||||
|
// Add archive
|
||||||
|
archives.add(archive);
|
||||||
|
});
|
||||||
|
|
||||||
|
// TODO Sort this list and inner list
|
||||||
|
|
||||||
|
return archives;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<ArchiveMonthVO> listMonthArchives() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional
|
@Transactional
|
||||||
public Post removeById(Integer postId) {
|
public Post removeById(Integer postId) {
|
||||||
|
@ -273,6 +313,23 @@ public class PostServiceImpl extends AbstractCrudService<Post, Integer> implemen
|
||||||
return super.removeById(postId);
|
return super.removeById(postId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts to post minimal output dto.
|
||||||
|
*
|
||||||
|
* @param posts a list of post
|
||||||
|
* @return a list of post minimal output dto
|
||||||
|
*/
|
||||||
|
@NonNull
|
||||||
|
private List<PostMinimalOutputDTO> convertTo(@NonNull List<Post> posts) {
|
||||||
|
if (CollectionUtils.isEmpty(posts)) {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert
|
||||||
|
return posts.stream().map(post -> new PostMinimalOutputDTO().<PostMinimalOutputDTO>convertFrom(post))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts to post detail vo.
|
* Converts to post detail vo.
|
||||||
*
|
*
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
package cc.ryanc.halo.utils;
|
package cc.ryanc.halo.utils;
|
||||||
|
|
||||||
import org.springframework.lang.NonNull;
|
import org.springframework.lang.NonNull;
|
||||||
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
|
import java.util.Calendar;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -24,4 +26,19 @@ public class DateUtils {
|
||||||
public static Date now() {
|
public static Date now() {
|
||||||
return new Date();
|
return new Date();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts from date into a calendar instance.
|
||||||
|
*
|
||||||
|
* @param date date instance must not be null
|
||||||
|
* @return calendar instance
|
||||||
|
*/
|
||||||
|
@NonNull
|
||||||
|
public static Calendar convertTo(@NonNull Date date) {
|
||||||
|
Assert.notNull(date, "Date must not be null");
|
||||||
|
|
||||||
|
Calendar calendar = Calendar.getInstance();
|
||||||
|
calendar.setTime(date);
|
||||||
|
return calendar;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,8 @@ import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Theme controller.
|
||||||
|
*
|
||||||
* @author : RYAN0UP
|
* @author : RYAN0UP
|
||||||
* @date : 2019/3/20
|
* @date : 2019/3/20
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -10,6 +10,8 @@ import org.springframework.web.bind.annotation.*;
|
||||||
import javax.validation.Valid;
|
import javax.validation.Valid;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* User controller.
|
||||||
|
*
|
||||||
* @author johnniang
|
* @author johnniang
|
||||||
* @date 3/19/19
|
* @date 3/19/19
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
package cc.ryanc.halo.web.controller.portal.api;
|
||||||
|
|
||||||
|
import cc.ryanc.halo.model.vo.ArchiveMonthVO;
|
||||||
|
import cc.ryanc.halo.model.vo.ArchiveYearVO;
|
||||||
|
import cc.ryanc.halo.service.PostService;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Archive portal controller.
|
||||||
|
*
|
||||||
|
* @author johnniang
|
||||||
|
* @date 4/2/19
|
||||||
|
*/
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/api/archives")
|
||||||
|
public class ArchiveController {
|
||||||
|
|
||||||
|
private final PostService postService;
|
||||||
|
|
||||||
|
public ArchiveController(PostService postService) {
|
||||||
|
this.postService = postService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("years")
|
||||||
|
public List<ArchiveYearVO> listYearArchives() {
|
||||||
|
return postService.listYearArchives();
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("months")
|
||||||
|
public List<ArchiveMonthVO> listMonthArchives() {
|
||||||
|
return postService.listMonthArchives();
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue