Complete post update api

pull/137/head
johnniang 2019-03-21 23:09:24 +08:00
parent f27f4f8833
commit 7853bd679c
8 changed files with 134 additions and 30 deletions

View File

@ -66,8 +66,28 @@ public class PostParam implements InputConverter<Post> {
Post post = InputConverter.super.convertTo();
// Crypt password
post.setPassword(BCrypt.hashpw(password, BCrypt.gensalt()));
if (StringUtils.isNotBlank(password)) {
post.setPassword(BCrypt.hashpw(password, BCrypt.gensalt()));
}
return post;
}
@Override
public void update(Post post) {
if (StringUtils.isBlank(url)) {
url = HaloUtils.normalizeUrl(title);
} else {
url = HaloUtils.normalizeUrl(url);
}
url = HaloUtils.initializeUrlIfBlank(url);
InputConverter.super.update(post);
// Crypt password
if (StringUtils.isNotBlank(password)) {
post.setPassword(BCrypt.hashpw(password, BCrypt.gensalt()));
}
}
}

View File

@ -47,12 +47,12 @@ public interface PostCategoryService extends CrudService<PostCategory, Integer>
List<Post> listPostBy(@NonNull Integer categoryId);
/**
* Creates post categories by post id and category id set.
* Merges or creates post categories by post id and category id set if absent.
*
* @param postId post id must not be null
* @param categoryIds category id set
* @return a list of post category
*/
@NonNull
List<PostCategory> createBy(@NonNull Integer postId, Set<Integer> categoryIds);
List<PostCategory> mergeOrCreateByIfAbsent(@NonNull Integer postId, Set<Integer> categoryIds);
}

View File

@ -126,6 +126,18 @@ public interface PostService extends CrudService<Post, Integer> {
@Transactional
Post createBy(@NonNull Post post, Set<Integer> tagIds, Set<Integer> categoryIds);
/**
* Updates post by post, tag id set and category id set.
*
* @param postToUpdate post to update must not be null
* @param tagIds tag id set
* @param categoryIds category id set
* @return updated post
*/
@NonNull
@Transactional
Post updateBy(@NonNull Post postToUpdate, Set<Integer> tagIds, Set<Integer> categoryIds);
/**
* Get post by url.
*

View File

@ -58,12 +58,12 @@ public interface PostTagService extends CrudService<PostTag, Integer> {
List<Post> listPostsBy(@NonNull Integer tagId);
/**
* Creates post tags by post id and tag id set.
* Merges or creates post tags by post id and tag id set if absent.
*
* @param postId post id must not be null
* @param tagIds tag id set
* @return a list of post tag
*/
@NonNull
List<PostTag> createBy(@NonNull Integer postId, Set<Integer> tagIds);
List<PostTag> mergeOrCreateByIfAbsent(@NonNull Integer postId, Set<Integer> tagIds);
}

View File

@ -88,7 +88,7 @@ public class PostCategoryServiceImpl extends AbstractCrudService<PostCategory, I
}
@Override
public List<PostCategory> createBy(Integer postId, Set<Integer> categoryIds) {
public List<PostCategory> mergeOrCreateByIfAbsent(Integer postId, Set<Integer> categoryIds) {
Assert.notNull(postId, "Post id must not be null");
if (CollectionUtils.isEmpty(categoryIds)) {
@ -96,17 +96,41 @@ public class PostCategoryServiceImpl extends AbstractCrudService<PostCategory, I
}
// Build post categories
Set<PostCategory> postCategories = categoryIds.stream().map(categoryId -> {
List<PostCategory> postCategoriesStaging = categoryIds.stream().map(categoryId -> {
PostCategory postCategory = new PostCategory();
postCategory.setPostId(postId);
postCategory.setCategoryId(categoryId);
return postCategory;
}).collect(Collectors.toSet());
}).collect(Collectors.toList());
// List all post categories and remove them
postCategories.removeAll(postCategoryRepository.findAllByPostId(postId));
List<PostCategory> postCategoriesToCreate = new LinkedList<>();
List<PostCategory> postCategoriesToRemove = new LinkedList<>();
// Find all exist post categories
List<PostCategory> postCategories = postCategoryRepository.findAllByPostId(postId);
postCategories.forEach(postCategory -> {
if (!postCategoriesStaging.contains(postCategory)) {
postCategoriesToRemove.add(postCategory);
}
});
postCategoriesStaging.forEach(postCategoryStaging -> {
if (!postCategories.contains(postCategoryStaging)) {
postCategoriesToCreate.add(postCategoryStaging);
}
});
// Remove post categories
removeAll(postCategoriesToRemove);
// Remove all post categories need to remove
postCategories.removeAll(postCategoriesToRemove);
// Add all created post categories
postCategories.addAll(createInBatch(postCategoriesToCreate));
// Create them
return createInBatch(postCategories);
return postCategories;
}
}

View File

@ -20,12 +20,14 @@ 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.lang.NonNull;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;
/**
@ -166,10 +168,20 @@ public class PostServiceImpl extends AbstractCrudService<Post, Integer> implemen
}
@Override
public Post createBy(Post post, Set<Integer> tagIds, Set<Integer> categoryIds) {
Assert.notNull(post, "Post param must not be null");
public Post createBy(Post postToCreate, Set<Integer> tagIds, Set<Integer> categoryIds) {
return createOrUpdate(postToCreate, tagIds, categoryIds, this::create);
}
// TODO Check url
@Override
public Post updateBy(Post postToUpdate, Set<Integer> tagIds, Set<Integer> categoryIds) {
return createOrUpdate(postToUpdate, tagIds, categoryIds, this::update);
}
private Post createOrUpdate(@NonNull Post post, Set<Integer> tagIds, Set<Integer> categoryIds, @NonNull Function<Post, Post> postOperation) {
Assert.notNull(post, "Post param must not be null");
Assert.notNull(postOperation, "Post operation must not be null");
// Check url
long count = postRepository.countByUrl(post.getUrl());
if (count > 0) {
@ -179,10 +191,8 @@ public class PostServiceImpl extends AbstractCrudService<Post, Integer> implemen
// Render content
post.setFormatContent(MarkdownUtils.renderMarkdown(post.getOriginalContent()));
// TODO Handle thumbnail
// Create post
create(post);
// Update post
post = postOperation.apply(post);
// List all tags
List<Tag> tags = tagService.listAllByIds(tagIds);
@ -191,12 +201,12 @@ public class PostServiceImpl extends AbstractCrudService<Post, Integer> implemen
List<Category> categories = categoryService.listAllByIds(categoryIds);
// Create post tags
List<PostTag> postTags = postTagService.createBy(post.getId(), ServiceUtils.fetchProperty(tags, Tag::getId));
List<PostTag> postTags = postTagService.mergeOrCreateByIfAbsent(post.getId(), ServiceUtils.fetchProperty(tags, Tag::getId));
log.debug("Created post tags: [{}]", postTags);
// Create post categories
List<PostCategory> postCategories = postCategoryService.createBy(post.getId(), ServiceUtils.fetchProperty(categories, Category::getId));
List<PostCategory> postCategories = postCategoryService.mergeOrCreateByIfAbsent(post.getId(), ServiceUtils.fetchProperty(categories, Category::getId));
log.debug("Created post categories: [{}]", postCategories);
@ -212,6 +222,6 @@ public class PostServiceImpl extends AbstractCrudService<Post, Integer> implemen
*/
@Override
public Post getByUrl(String url, PostType type) {
return postRepository.getByUrlAndType(url, type).orElseThrow(()->new NotFoundException("The post does not exist").setErrorData(url));
return postRepository.getByUrlAndType(url, type).orElseThrow(() -> new NotFoundException("The post does not exist").setErrorData(url));
}
}

View File

@ -104,7 +104,7 @@ public class PostTagServiceImpl extends AbstractCrudService<PostTag, Integer> im
}
@Override
public List<PostTag> createBy(Integer postId, Set<Integer> tagIds) {
public List<PostTag> mergeOrCreateByIfAbsent(Integer postId, Set<Integer> tagIds) {
Assert.notNull(postId, "Post id must not be null");
if (CollectionUtils.isEmpty(tagIds)) {
@ -112,18 +112,41 @@ public class PostTagServiceImpl extends AbstractCrudService<PostTag, Integer> im
}
// Create post tags
Set<PostTag> postTags = tagIds.stream().map(tagId -> {
List<PostTag> postTagsStaging = tagIds.stream().map(tagId -> {
// Build post tag
PostTag postTag = new PostTag();
postTag.setPostId(postId);
postTag.setTagId(tagId);
return postTag;
}).collect(Collectors.toSet());
}).collect(Collectors.toList());
// Get post tag exist and remove them
postTags.removeAll(postTagRepository.findAllByPostId(postId));
List<PostTag> postTagsToRemove = new LinkedList<>();
List<PostTag> postTagsToCreate = new LinkedList<>();
// Create in batch
return createInBatch(postTags);
List<PostTag> postTags = postTagRepository.findAllByPostId(postId);
postTags.forEach(postTag -> {
if (!postTagsStaging.contains(postTag)) {
postTagsToRemove.add(postTag);
}
});
postTagsStaging.forEach(postTagStaging -> {
if (!postTags.contains(postTagStaging)) {
postTagsToCreate.add(postTagStaging);
}
});
// Remove post tags
removeAll(postTagsToRemove);
// Remove all post tags need to remove
postTags.removeAll(postTagsToRemove);
// Add all created post tags
postTags.addAll(createInBatch(postTagsToCreate));
// Return post tags
return postTags;
}
}

View File

@ -7,7 +7,7 @@ import cc.ryanc.halo.model.entity.Post;
import cc.ryanc.halo.model.enums.PostStatus;
import cc.ryanc.halo.model.enums.PostType;
import cc.ryanc.halo.model.params.PostParam;
import cc.ryanc.halo.service.*;
import cc.ryanc.halo.service.PostService;
import io.swagger.annotations.ApiOperation;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
@ -53,7 +53,22 @@ public class PostController {
// Convert to
Post post = postParam.convertTo();
return new PostDetailOutputDTO().convertFrom(postService.createBy(post, postParam.getTagIds(), postParam.getCategoryIds()));
Post createdPost = postService.createBy(post, postParam.getTagIds(), postParam.getCategoryIds());
return new PostDetailOutputDTO().convertFrom(createdPost);
}
@PutMapping("{postId:\\d+}")
public PostDetailOutputDTO updateBy(@Valid @RequestBody PostParam postParam,
@PathVariable("postId") Integer postId) {
// Get the post info
Post postToUpdate = postService.getById(postId);
postParam.update(postToUpdate);
Post updatedPost = postService.updateBy(postToUpdate, postParam.getTagIds(), postParam.getCategoryIds());
return new PostDetailOutputDTO().convertFrom(updatedPost);
}
}