diff --git a/README.md b/README.md index ac5e876..096ae9c 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ #### 介绍 -基于[小说精品屋-plus](https://www.oschina.net/p/novel-plus)构建的Spring Cloud 微服务小说门户平台,可用于学习和商用。采用了Spring Boot 2 、Spring Cloud Greenwich、 MyBatis3DynamicSql、Redis、Mq、Elasticsearch、Docker等流行技术,集成了Nacos注册中心/配置中心、Spring Cloud Gateway网关、Spring Boot Admin监控中心等基础服务。前端计划使用Vue开发,目前还在 **开发中**,感兴趣的可以提前关注。 +基于[小说精品屋-plus](https://www.oschina.net/p/novel-plus)构建的Spring Cloud 微服务小说门户平台,可用于学习和商用。采用了Spring Boot 2 、Spring Cloud Greenwich、 MyBatis3DynamicSql、Redis、Mq、Elasticsearch、Docker等流行技术,集成了Nacos注册中心/配置中心、Spring Cloud Gateway网关、Spring Boot Admin监控中心等基础服务。前端计划使用Vue开发,后台接口一期开发已完成(充值/作家专区除外的所有接口)。 #### 演示地址 diff --git a/assert/QQ20200529-082052.png b/assert/QQ20200529-082052.png index 3e8d4d8..4eac435 100644 Binary files a/assert/QQ20200529-082052.png and b/assert/QQ20200529-082052.png differ diff --git a/novel-book/book-api/src/main/java/com/java2nb/novel/book/api/BookApi.java b/novel-book/book-api/src/main/java/com/java2nb/novel/book/api/BookApi.java index 785b634..76e60e9 100644 --- a/novel-book/book-api/src/main/java/com/java2nb/novel/book/api/BookApi.java +++ b/novel-book/book-api/src/main/java/com/java2nb/novel/book/api/BookApi.java @@ -1,7 +1,10 @@ package com.java2nb.novel.book.api; import com.java2nb.novel.book.entity.Book; +import com.java2nb.novel.book.entity.BookComment; +import com.java2nb.novel.book.vo.BookCommentVO; import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestParam; @@ -50,5 +53,21 @@ public interface BookApi { @GetMapping("api/book/queryBookById") Book queryBookById(@RequestParam("id") Long id); + /** + * 新增评论 + * @param userId 用户ID + * @param comment 评论数据 + * */ + @PostMapping("api/book/addBookComment") + void addBookComment(@RequestParam("userId") Long userId,@RequestParam("comment") BookComment comment); + /** + * 分页查询用户评论 + * @param userId 用户ID + * @param page 查询页码 + * @param pageSize 分页大小 + * @return 评论数据 + * */ + @GetMapping("api/book/listUserCommentByPage") + List listUserCommentByPage(@RequestParam("userId") Long userId,@RequestParam("page") int page, @RequestParam("pageSize") int pageSize); } diff --git a/novel-book/book-service/src/main/java/com/java2nb/novel/book/controller/BookController.java b/novel-book/book-service/src/main/java/com/java2nb/novel/book/controller/BookController.java index ee28586..ab6f4f4 100644 --- a/novel-book/book-service/src/main/java/com/java2nb/novel/book/controller/BookController.java +++ b/novel-book/book-service/src/main/java/com/java2nb/novel/book/controller/BookController.java @@ -102,7 +102,7 @@ public class BookController { @ApiOperation("书籍评论列表分页查询接口") @GetMapping("listCommentByPage") public ResultBean> listCommentByPage(@ApiParam("小说ID") @RequestParam("bookId") Long bookId, @ApiParam("当前页码") @RequestParam(value = "curr", defaultValue = "1") int page, @ApiParam("分页大小") @RequestParam(value = "limit", defaultValue = "5") int pageSize) { - return ResultBean.ok(new PageBean<>(bookService.listCommentByPage(null,bookId,page,pageSize))); + return ResultBean.ok(new PageBean<>(bookService.listBookCommentByPage(bookId,page,pageSize))); } /** diff --git a/novel-book/book-service/src/main/java/com/java2nb/novel/book/controller/api/BookApi.java b/novel-book/book-service/src/main/java/com/java2nb/novel/book/controller/api/BookApi.java index 1fdf2b8..08e18c7 100644 --- a/novel-book/book-service/src/main/java/com/java2nb/novel/book/controller/api/BookApi.java +++ b/novel-book/book-service/src/main/java/com/java2nb/novel/book/controller/api/BookApi.java @@ -1,10 +1,10 @@ package com.java2nb.novel.book.controller.api; import com.java2nb.novel.book.entity.Book; +import com.java2nb.novel.book.entity.BookComment; import com.java2nb.novel.book.service.BookService; -import io.swagger.annotations.Api; +import com.java2nb.novel.book.vo.BookCommentVO; import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.*; import springfox.documentation.annotations.ApiIgnore; @@ -69,4 +69,26 @@ public class BookApi { Book queryBookById(@RequestParam("id") Long id){ return bookService.queryBookDetail(id); } + + /** + * 新增评论 + * @param userId 用户ID + * @param comment 评论数据 + * */ + @PostMapping("addBookComment") + void addBookComment(Long userId, BookComment comment){ + bookService.addBookComment(userId,comment); + } + + /** + * 分页查询用户评论 + * @param userId 用户ID + * @param page 查询页码 + * @param pageSize 分页大小 + * @return 评论数据 + * */ + @GetMapping("listUserCommentByPage") + List listUserCommentByPage(@RequestParam("userId") Long userId,@RequestParam("page") int page, @RequestParam("pageSize") int pageSize){ + return bookService.listUserCommentByPage(userId,page,pageSize); + } } diff --git a/novel-book/book-service/src/main/java/com/java2nb/novel/book/mapper/BookMapper.java b/novel-book/book-service/src/main/java/com/java2nb/novel/book/mapper/BookMapper.java index a99ec86..b33c7dd 100644 --- a/novel-book/book-service/src/main/java/com/java2nb/novel/book/mapper/BookMapper.java +++ b/novel-book/book-service/src/main/java/com/java2nb/novel/book/mapper/BookMapper.java @@ -311,4 +311,6 @@ public interface BookMapper { void addVisitCount(@Param("bookId") Long bookId, @Param("visitCount") Integer visitCount); List listRecBookByCatId(@Param("catId") Integer catId); + + void addCommentCount(@Param("bookId") Long bookId); } \ No newline at end of file diff --git a/novel-book/book-service/src/main/java/com/java2nb/novel/book/service/BookService.java b/novel-book/book-service/src/main/java/com/java2nb/novel/book/service/BookService.java index 8cf92b7..1350e02 100644 --- a/novel-book/book-service/src/main/java/com/java2nb/novel/book/service/BookService.java +++ b/novel-book/book-service/src/main/java/com/java2nb/novel/book/service/BookService.java @@ -1,9 +1,6 @@ package com.java2nb.novel.book.service; -import com.java2nb.novel.book.entity.Book; -import com.java2nb.novel.book.entity.BookCategory; -import com.java2nb.novel.book.entity.BookContent; -import com.java2nb.novel.book.entity.BookIndex; +import com.java2nb.novel.book.entity.*; import com.java2nb.novel.book.vo.BookCommentVO; import java.util.Date; @@ -84,13 +81,12 @@ public interface BookService { /** *分页查询书籍评论列表 - * @param userId 用户ID * @param bookId 书籍ID * @param page 页码 * @param pageSize 分页大小 * @return 评论集合 * */ - List listCommentByPage(Long userId, Long bookId, int page, int pageSize); + List listBookCommentByPage( Long bookId, int page, int pageSize); /** * 查询目录列表 @@ -124,4 +120,20 @@ public interface BookService { * @return 上一章节和下一章节目录ID数据 * */ Map queryPreAndNextBookIndexId(Long bookId, Integer indexNum); + + /** + * 新增评价 + * @param userId 用户ID + * @param comment 评论内容 + * */ + void addBookComment(Long userId, BookComment comment); + + /** + * 分页查询用户评论 + * @param userId 用户ID + * @param page 查询页码 + * @param pageSize 分页大小 + * @return 评论数据 + * */ + List listUserCommentByPage(Long userId, int page, int pageSize); } diff --git a/novel-book/book-service/src/main/java/com/java2nb/novel/book/service/impl/BookServiceImpl.java b/novel-book/book-service/src/main/java/com/java2nb/novel/book/service/impl/BookServiceImpl.java index aa904a3..8efe3e1 100644 --- a/novel-book/book-service/src/main/java/com/java2nb/novel/book/service/impl/BookServiceImpl.java +++ b/novel-book/book-service/src/main/java/com/java2nb/novel/book/service/impl/BookServiceImpl.java @@ -6,6 +6,8 @@ import com.java2nb.novel.book.feign.UserFeignClient; import com.java2nb.novel.book.mapper.*; import com.java2nb.novel.book.service.BookService; import com.java2nb.novel.book.vo.BookCommentVO; +import com.java2nb.novel.common.enums.ResponseStatus; +import com.java2nb.novel.common.exception.BusinessException; import com.java2nb.novel.common.utils.BeanUtil; import com.java2nb.novel.user.entity.User; import lombok.RequiredArgsConstructor; @@ -15,6 +17,7 @@ import org.mybatis.dynamic.sql.render.RenderingStrategies; import org.mybatis.dynamic.sql.select.render.SelectStatementProvider; import org.springframework.beans.BeanUtils; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; import tk.mybatis.orderbyhelper.OrderByHelper; import java.util.*; @@ -166,7 +169,7 @@ public class BookServiceImpl implements BookService { } @Override - public List listCommentByPage(Long userId, Long bookId, int page, int pageSize) { + public List listBookCommentByPage(Long bookId, int page, int pageSize) { //分页查询小说评论数据 PageHelper.startPage(page, pageSize); List bookCommentList = bookCommentMapper.selectMany( @@ -280,4 +283,41 @@ public class BookServiceImpl implements BookService { return result; } + + @Transactional(rollbackFor = Exception.class) + @Override + public void addBookComment(Long userId, BookComment comment) { + //判断该用户是否已评论过该书籍 + SelectStatementProvider selectStatement = select(count(BookCommentDynamicSqlSupport.id)) + .from(BookCommentDynamicSqlSupport.bookComment) + .where(BookCommentDynamicSqlSupport.createUserId, isEqualTo(userId)) + .and(BookCommentDynamicSqlSupport.bookId, isEqualTo(comment.getBookId())) + .build() + .render(RenderingStrategies.MYBATIS3); + if (bookCommentMapper.count(selectStatement) > 0) { + throw new BusinessException(ResponseStatus.HAS_COMMENTS); + } + //增加评论 + comment.setCreateUserId(userId); + comment.setCreateTime(new Date()); + bookCommentMapper.insertSelective(comment); + //增加书籍评论数 + bookMapper.addCommentCount(comment.getBookId()); + + } + + @Override + public List listUserCommentByPage(Long userId, int page, int pageSize) { + PageHelper.startPage(page, pageSize); + return bookCommentMapper.selectMany( + select(BookCommentDynamicSqlSupport.id,BookCommentDynamicSqlSupport.bookId, + BookCommentDynamicSqlSupport.createUserId, + BookCommentDynamicSqlSupport.commentContent,BookCommentDynamicSqlSupport.replyCount, + BookCommentDynamicSqlSupport.createTime) + .from(BookCommentDynamicSqlSupport.bookComment) + .where(BookCommentDynamicSqlSupport.createUserId,isEqualTo(userId)) + .orderBy(BookCommentDynamicSqlSupport.createTime.descending()) + .build() + .render(RenderingStrategies.MYBATIS3)); + } } diff --git a/novel-user/user-service/src/main/java/com/java2nb/novel/user/controller/UserController.java b/novel-user/user-service/src/main/java/com/java2nb/novel/user/controller/UserController.java index 1391e88..f58974a 100644 --- a/novel-user/user-service/src/main/java/com/java2nb/novel/user/controller/UserController.java +++ b/novel-user/user-service/src/main/java/com/java2nb/novel/user/controller/UserController.java @@ -1,5 +1,7 @@ package com.java2nb.novel.user.controller; +import com.github.pagehelper.PageInfo; +import com.java2nb.novel.book.entity.BookComment; import com.java2nb.novel.common.base.BaseController; import com.java2nb.novel.common.bean.PageBean; import com.java2nb.novel.common.bean.ResultBean; @@ -9,6 +11,7 @@ import com.java2nb.novel.common.enums.ResponseStatus; import com.java2nb.novel.common.utils.RandomValidateCodeUtil; import com.java2nb.novel.user.entity.User; import com.java2nb.novel.user.entity.UserFeedback; +import com.java2nb.novel.user.feign.BookFeignClient; import com.java2nb.novel.user.form.UserForm; import com.java2nb.novel.user.service.UserService; import com.java2nb.novel.user.vo.BookReadHistoryVO; @@ -41,6 +44,8 @@ public class UserController extends BaseController { private final UserService userService; + private final BookFeignClient bookFeignClient; + /** * 登陆 */ @@ -274,6 +279,33 @@ public class UserController extends BaseController { return ResultBean.ok(); } + /** + * 发布评价 + * */ + @ApiOperation("发布评价接口") + @PostMapping("addBookComment") + public ResultBean addBookComment(BookComment comment, HttpServletRequest request) { + UserDetails userDetails = getUserDetails(request); + if (userDetails == null) { + return ResultBean.fail(ResponseStatus.NO_LOGIN); + } + bookFeignClient.addBookComment(userDetails.getId(),comment); + return ResultBean.ok(); + } + + /** + * 用户书评分页查询 + * */ + @ApiOperation("用户书评分页查询接口") + @GetMapping("listCommentByPage") + public ResultBean> listCommentByPage(@RequestParam(value = "curr", defaultValue = "1") int page, @RequestParam(value = "limit", defaultValue = "5") int pageSize,HttpServletRequest request) { + UserDetails userDetails = getUserDetails(request); + if (userDetails == null) { + return ResultBean.fail(ResponseStatus.NO_LOGIN); + } + return ResultBean.ok(new PageBean<>(bookFeignClient.listUserCommentByPage(userDetails.getId(),page,pageSize))); + } + diff --git a/novel-user/user-service/src/main/java/com/java2nb/novel/user/service/UserService.java b/novel-user/user-service/src/main/java/com/java2nb/novel/user/service/UserService.java index 7e6b772..e787a5e 100644 --- a/novel-user/user-service/src/main/java/com/java2nb/novel/user/service/UserService.java +++ b/novel-user/user-service/src/main/java/com/java2nb/novel/user/service/UserService.java @@ -147,4 +147,5 @@ public interface UserService { * @param newPassword 新密码 * */ void updatePassword(Long userId, String oldPassword, String newPassword); + } diff --git a/novel-user/user-service/src/main/java/com/java2nb/novel/user/service/impl/UserServiceImpl.java b/novel-user/user-service/src/main/java/com/java2nb/novel/user/service/impl/UserServiceImpl.java index 56cd1ee..ec757ea 100644 --- a/novel-user/user-service/src/main/java/com/java2nb/novel/user/service/impl/UserServiceImpl.java +++ b/novel-user/user-service/src/main/java/com/java2nb/novel/user/service/impl/UserServiceImpl.java @@ -2,6 +2,7 @@ package com.java2nb.novel.user.service.impl; import com.github.pagehelper.PageHelper; import com.java2nb.novel.book.entity.Book; +import com.java2nb.novel.book.entity.BookComment; import com.java2nb.novel.common.bean.UserDetails; import com.java2nb.novel.common.enums.ResponseStatus; import com.java2nb.novel.common.exception.BusinessException; @@ -42,6 +43,7 @@ import static org.mybatis.dynamic.sql.select.SelectDSL.select; /** * 小说服务接口实现 + * * @author xiongxiaoyang * @version 1.0 * @since 2020/5/28 @@ -79,7 +81,7 @@ public class UserServiceImpl implements UserService { @Override public UserDetails login(UserForm form) { //根据用户名密码查询记录 - User user = queryByUsernameAndPassword(form.getUsername(),form.getPassword()); + User user = queryByUsernameAndPassword(form.getUsername(), form.getPassword()); if (user == null) { throw new BusinessException(ResponseStatus.USERNAME_PASS_ERROR); } @@ -94,10 +96,10 @@ public class UserServiceImpl implements UserService { @Override public List queryById(List ids) { return userMapper.selectMany( - select(UserDynamicSqlSupport.id,UserDynamicSqlSupport.username, + select(UserDynamicSqlSupport.id, UserDynamicSqlSupport.username, UserDynamicSqlSupport.userPhoto) - .from(UserDynamicSqlSupport.user) - .where(UserDynamicSqlSupport.id,isIn(ids)).build() + .from(UserDynamicSqlSupport.user) + .where(UserDynamicSqlSupport.id, isIn(ids)).build() .render(RenderingStrategies.MYBATIS3)); } @@ -115,7 +117,7 @@ public class UserServiceImpl implements UserService { throw new BusinessException(ResponseStatus.USERNAME_EXIST); } User entity = new User(); - BeanUtils.copyProperties(form,entity); + BeanUtils.copyProperties(form, entity); //数据库生成注册记录 Long id = new IdWorker().nextId(); entity.setId(id); @@ -171,23 +173,23 @@ public class UserServiceImpl implements UserService { public List listBookShelfByPage(Long userId, int page, int pageSize) { PageHelper.startPage(page, pageSize); List userBookshelves = userBookshelfMapper.selectMany( - select(UserBookshelfDynamicSqlSupport.bookId,UserBookshelfDynamicSqlSupport.preContentId) - .from(userBookshelf) - .where(UserBookshelfDynamicSqlSupport.userId,isEqualTo(userId)) + select(UserBookshelfDynamicSqlSupport.bookId, UserBookshelfDynamicSqlSupport.preContentId) + .from(userBookshelf) + .where(UserBookshelfDynamicSqlSupport.userId, isEqualTo(userId)) .orderBy(UserBookshelfDynamicSqlSupport.createTime.descending()) .build() .render(RenderingStrategies.MYBATIS3)); List books = bookFeignClient.queryBookByIds(userBookshelves.stream().map(UserBookshelf::getBookId).collect(Collectors.toList())); - Map booksById = books.stream().collect(Collectors.toMap(Book::getId, Function.identity(),(key1, key2) -> key2)); + Map booksById = books.stream().collect(Collectors.toMap(Book::getId, Function.identity(), (key1, key2) -> key2)); List resultList = new ArrayList<>(booksById.size()); - for(UserBookshelf bookshelf : userBookshelves){ + for (UserBookshelf bookshelf : userBookshelves) { BookShelfVO bookShelfVO = new BookShelfVO(); - BeanUtils.copyProperties(bookshelf,bookShelfVO); + BeanUtils.copyProperties(bookshelf, bookShelfVO); Book book = booksById.get(bookshelf.getBookId()); - if(book != null){ - BeanUtils.copyProperties(book,bookShelfVO); + if (book != null) { + BeanUtils.copyProperties(book, bookShelfVO); resultList.add(bookShelfVO); } @@ -201,24 +203,24 @@ public class UserServiceImpl implements UserService { public List listReadHistoryByPage(Long userId, int page, int pageSize) { PageHelper.startPage(page, pageSize); List userReadHistories = userReadHistoryMapper.selectMany( - select(UserReadHistoryDynamicSqlSupport.bookId,UserReadHistoryDynamicSqlSupport.preContentId) + select(UserReadHistoryDynamicSqlSupport.bookId, UserReadHistoryDynamicSqlSupport.preContentId) .from(userReadHistory) - .where(UserReadHistoryDynamicSqlSupport.userId,isEqualTo(userId)) + .where(UserReadHistoryDynamicSqlSupport.userId, isEqualTo(userId)) .orderBy(UserReadHistoryDynamicSqlSupport.createTime.descending()) .build() .render(RenderingStrategies.MYBATIS3)); List books = bookFeignClient.queryBookByIds(userReadHistories.stream().map(UserReadHistory::getBookId).collect(Collectors.toList())); - Map booksById = books.stream().collect(Collectors.toMap(Book::getId, Function.identity(),(key1, key2) -> key2)); + Map booksById = books.stream().collect(Collectors.toMap(Book::getId, Function.identity(), (key1, key2) -> key2)); List resultList = new ArrayList<>(booksById.size()); - for(UserReadHistory readHistory : userReadHistories){ + for (UserReadHistory readHistory : userReadHistories) { BookReadHistoryVO readHistoryVO = new BookReadHistoryVO(); - BeanUtils.copyProperties(readHistory,readHistoryVO); + BeanUtils.copyProperties(readHistory, readHistoryVO); Book book = booksById.get(readHistory.getBookId()); - if(book != null){ - BeanUtils.copyProperties(book,readHistoryVO); + if (book != null) { + BeanUtils.copyProperties(book, readHistoryVO); resultList.add(readHistoryVO); } @@ -287,10 +289,11 @@ public class UserServiceImpl implements UserService { .build() .render(RenderingStrategies.MYBATIS3)); } + @Override public User userInfo(Long userId) { SelectStatementProvider selectStatement = select(UserDynamicSqlSupport.username, UserDynamicSqlSupport.nickName, - UserDynamicSqlSupport.userPhoto,UserDynamicSqlSupport.userSex,UserDynamicSqlSupport.accountBalance) + UserDynamicSqlSupport.userPhoto, UserDynamicSqlSupport.userSex, UserDynamicSqlSupport.accountBalance) .from(UserDynamicSqlSupport.user) .where(UserDynamicSqlSupport.id, isEqualTo(userId)) .limit(1) @@ -314,16 +317,16 @@ public class UserServiceImpl implements UserService { public void updatePassword(Long userId, String oldPassword, String newPassword) { SelectStatementProvider selectStatement = select(UserDynamicSqlSupport.password) .from(UserDynamicSqlSupport.user) - .where(UserDynamicSqlSupport.id,isEqualTo(userId)) + .where(UserDynamicSqlSupport.id, isEqualTo(userId)) .build() .render(RenderingStrategies.MYBATIS3); - if(!userMapper.selectMany(selectStatement).get(0).getPassword().equals(MD5Util.MD5Encode(oldPassword, Charsets.UTF_8.name()))){ + if (!userMapper.selectMany(selectStatement).get(0).getPassword().equals(MD5Util.MD5Encode(oldPassword, Charsets.UTF_8.name()))) { throw new BusinessException(ResponseStatus.OLD_PASSWORD_ERROR); } UpdateStatementProvider updateStatement = update(UserDynamicSqlSupport.user) .set(UserDynamicSqlSupport.password) .equalTo(MD5Util.MD5Encode(newPassword, Charsets.UTF_8.name())) - .where(UserDynamicSqlSupport.id,isEqualTo(userId)) + .where(UserDynamicSqlSupport.id, isEqualTo(userId)) .build() .render(RenderingStrategies.MYBATIS3); userMapper.update(updateStatement); @@ -331,4 +334,5 @@ public class UserServiceImpl implements UserService { } + }