diff --git a/README.md b/README.md index 7292355..ac5e876 100644 --- a/README.md +++ b/README.md @@ -89,12 +89,18 @@ novel-cloud ![QQ20200520-215756](./assert/QQ20200528-200023.png) + + ![QQ20200520-215756](./assert/QQ20200528-221348.png) + + + ![QQ20200520-215756](./assert/QQ20200529-082052.png) + 5. 门户网站 - + ![QQ20200520-215756](./assert/pc_index.png) - + #### 项目文档 diff --git a/assert/QQ20200529-082052.png b/assert/QQ20200529-082052.png new file mode 100644 index 0000000..3e8d4d8 Binary files /dev/null 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 153a618..785b634 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 @@ -42,5 +42,13 @@ public interface BookApi { @GetMapping("api/book/listRank") List listRank(@RequestParam("type") Byte type, @RequestParam("limit") Integer limit); + /** + * 根据小说ID查询书籍 + * @param id 小说ID + * @return 书籍对象 + * */ + @GetMapping("api/book/queryBookById") + Book queryBookById(@RequestParam("id") Long id); + } 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 4665bc7..1fdf2b8 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 @@ -60,4 +60,13 @@ public class BookApi { } + /** + * 根据小说ID查询书籍 + * @param id 小说ID + * @return 书籍对象 + * */ + @GetMapping("queryBookById") + Book queryBookById(@RequestParam("id") Long id){ + return bookService.queryBookDetail(id); + } } 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 d4428a3..aa904a3 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 @@ -60,7 +60,9 @@ public class BookServiceImpl implements BookService { @Override public List queryBookByIds(List ids) { - return bookMapper.selectMany(select(BookDynamicSqlSupport.id,BookDynamicSqlSupport.bookName,BookDynamicSqlSupport.authorName, + return bookMapper.selectMany(select(BookDynamicSqlSupport.id,BookDynamicSqlSupport.catId,BookDynamicSqlSupport.catName, + BookDynamicSqlSupport.bookName,BookDynamicSqlSupport.authorName, + BookDynamicSqlSupport.lastIndexId,BookDynamicSqlSupport.lastIndexName,BookDynamicSqlSupport.lastIndexUpdateTime, BookDynamicSqlSupport.picUrl,BookDynamicSqlSupport.bookDesc,BookDynamicSqlSupport.score) .from(book) .where(BookDynamicSqlSupport.id,isIn(ids)) diff --git a/novel-user/user-api/src/main/java/com/java2nb/novel/user/vo/BookReadHistoryVO.java b/novel-user/user-api/src/main/java/com/java2nb/novel/user/vo/BookReadHistoryVO.java new file mode 100644 index 0000000..b7623ef --- /dev/null +++ b/novel-user/user-api/src/main/java/com/java2nb/novel/user/vo/BookReadHistoryVO.java @@ -0,0 +1,30 @@ +package com.java2nb.novel.user.vo; + +import com.fasterxml.jackson.annotation.JsonFormat; +import com.java2nb.novel.user.entity.UserReadHistory; +import lombok.Data; + +import java.util.Date; + +/** + * @author 11797 + */ +@Data +public class BookReadHistoryVO extends UserReadHistory { + + private Integer catId; + private String catName; + private Long lastIndexId; + + private String lastIndexName; + private String bookName; + + @JsonFormat(timezone = "GMT+8", pattern = "MM/dd HH:mm:ss") + private Date lastIndexUpdateTime; + + + @Override + public String toString() { + return super.toString(); + } +} diff --git a/novel-user/user-api/src/main/java/com/java2nb/novel/user/vo/BookShelfVO.java b/novel-user/user-api/src/main/java/com/java2nb/novel/user/vo/BookShelfVO.java new file mode 100644 index 0000000..ae3e7d8 --- /dev/null +++ b/novel-user/user-api/src/main/java/com/java2nb/novel/user/vo/BookShelfVO.java @@ -0,0 +1,30 @@ +package com.java2nb.novel.user.vo; + +import com.fasterxml.jackson.annotation.JsonFormat; +import com.java2nb.novel.user.entity.UserBookshelf; +import lombok.Data; + +import java.util.Date; + +/** + * @author 11797 + */ +@Data +public class BookShelfVO extends UserBookshelf { + + private Integer catId; + private String catName; + private Long lastIndexId; + + private String lastIndexName; + private String bookName; + + @JsonFormat(timezone = "GMT+8", pattern = "MM/dd HH:mm:ss") + private Date lastIndexUpdateTime; + + + @Override + public String toString() { + return super.toString(); + } +} diff --git a/novel-user/user-service/pom.xml b/novel-user/user-service/pom.xml index c8376b9..d18a538 100644 --- a/novel-user/user-service/pom.xml +++ b/novel-user/user-service/pom.xml @@ -17,6 +17,10 @@ com.java2nb.novel user-api + + com.java2nb.novel + book-api + org.springframework.cloud 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 f3cdccc..1391e88 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,21 +1,27 @@ package com.java2nb.novel.user.controller; import com.java2nb.novel.common.base.BaseController; +import com.java2nb.novel.common.bean.PageBean; import com.java2nb.novel.common.bean.ResultBean; import com.java2nb.novel.common.bean.UserDetails; +import com.java2nb.novel.common.cache.CacheService; 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.form.UserForm; import com.java2nb.novel.user.service.UserService; +import com.java2nb.novel.user.vo.BookReadHistoryVO; +import com.java2nb.novel.user.vo.BookShelfVO; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; import org.springframework.validation.BindingResult; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; -import springfox.documentation.swagger2.annotations.EnableSwagger2; +import org.springframework.web.bind.annotation.*; +import javax.servlet.http.HttpServletRequest; import javax.validation.Valid; import java.util.HashMap; import java.util.Map; @@ -31,6 +37,7 @@ import java.util.Map; public class UserController extends BaseController { + private final CacheService cacheService; private final UserService userService; @@ -38,8 +45,8 @@ public class UserController extends BaseController { * 登陆 */ @ApiOperation("用户登陆接口") - @PostMapping("login") - public ResultBean login(@Valid UserForm user, BindingResult result) { + @GetMapping("login") + public ResultBean> login(@Valid UserForm user, BindingResult result) { //判断参数是否合法 if (result.hasErrors()) { log.info(result.getAllErrors().toString()); @@ -57,8 +64,215 @@ public class UserController extends BaseController { } + /** + * 注册 + */ + @ApiOperation("用户注册接口") + @PostMapping("register") + public ResultBean> register(@Valid UserForm user, @RequestParam(value = "velCode", defaultValue = "") String velCode, BindingResult result) { + + //判断参数是否合法 + if (result.hasErrors()) { + log.info(result.getAllErrors().toString()); + return ResultBean.fail(ResponseStatus.PARAM_ERROR); + } + + //判断验证码是否正确 + if (!velCode.equals(cacheService.get(RandomValidateCodeUtil.RANDOM_CODE_KEY))) { + return ResultBean.fail(ResponseStatus.VEL_CODE_ERROR); + } + + //注册 + UserDetails userDetails = userService.register(user); + Map data = new HashMap<>(1); + data.put("token", jwtTokenUtil.generateToken(userDetails)); + + return ResultBean.ok(data); + } + + /** + * 刷新token + */ + @ApiOperation("token刷新接口") + @PostMapping("refreshToken") + public ResultBean> refreshToken(HttpServletRequest request) { + String token = getToken(request); + if (jwtTokenUtil.canRefresh(token)) { + token = jwtTokenUtil.refreshToken(token); + Map data = new HashMap<>(2); + data.put("token", token); + UserDetails userDetail = jwtTokenUtil.getUserDetailsFromToken(token); + data.put("username", userDetail.getUsername()); + data.put("nickName", userDetail.getNickName()); + return ResultBean.ok(data); + + } else { + return ResultBean.fail(ResponseStatus.NO_LOGIN); + } + + } + + /** + * 查询小说是否已加入书架 + */ + @ApiOperation("小说加入书架状态查询接口") + @GetMapping("queryIsInShelf") + public ResultBean queryIsInShelf(Long bookId, HttpServletRequest request) { + UserDetails userDetails = getUserDetails(request); + if (userDetails == null) { + return ResultBean.fail(ResponseStatus.NO_LOGIN); + } + return ResultBean.ok(userService.queryIsInShelf(userDetails.getId(), bookId)); + } + + /** + * 加入书架 + * */ + @ApiOperation("小说加入书架接口") + @PostMapping("addToBookShelf") + public ResultBean addToBookShelf(Long bookId,Long preContentId, HttpServletRequest request) { + UserDetails userDetails = getUserDetails(request); + if (userDetails == null) { + return ResultBean.fail(ResponseStatus.NO_LOGIN); + } + userService.addToBookShelf(userDetails.getId(),bookId,preContentId); + return ResultBean.ok(); + } + + /** + * 移出书架 + * */ + @ApiOperation("小说移出书架接口") + @DeleteMapping("removeFromBookShelf") + public ResultBean removeFromBookShelf(Long bookId, HttpServletRequest request) { + UserDetails userDetails = getUserDetails(request); + if (userDetails == null) { + return ResultBean.fail(ResponseStatus.NO_LOGIN); + } + userService.removeFromBookShelf(userDetails.getId(),bookId); + return ResultBean.ok(); + } + + /** + * 分页查询书架 + * */ + @ApiOperation("书架列表分页查询接口") + @GetMapping("listBookShelfByPage") + public ResultBean> listBookShelfByPage(@RequestParam(value = "curr", defaultValue = "1") int page, @RequestParam(value = "limit", defaultValue = "10") int pageSize, HttpServletRequest request) { + UserDetails userDetails = getUserDetails(request); + if (userDetails == null) { + return ResultBean.fail(ResponseStatus.NO_LOGIN); + } + return ResultBean.ok(new PageBean<>(userService.listBookShelfByPage(userDetails.getId(),page,pageSize))); + } + + /** + * 分页查询阅读记录 + * */ + @ApiOperation("阅读记录分页查询接口") + @GetMapping("listReadHistoryByPage") + public ResultBean> listReadHistoryByPage(@RequestParam(value = "curr", defaultValue = "1") int page, @RequestParam(value = "limit", defaultValue = "10") int pageSize, HttpServletRequest request) { + UserDetails userDetails = getUserDetails(request); + if (userDetails == null) { + return ResultBean.fail(ResponseStatus.NO_LOGIN); + } + return ResultBean.ok(new PageBean<>(userService.listReadHistoryByPage(userDetails.getId(),page,pageSize))); + } + + /** + * 添加阅读记录 + * */ + @ApiOperation("阅读记录添加接口") + @PostMapping("addReadHistory") + public ResultBean addReadHistory(Long bookId,Long preContentId, HttpServletRequest request) { + UserDetails userDetails = getUserDetails(request); + if (userDetails == null) { + return ResultBean.fail(ResponseStatus.NO_LOGIN); + } + userService.addReadHistory(userDetails.getId(),bookId,preContentId); + return ResultBean.ok(); + } + + /** + * 添加反馈 + * */ + @ApiOperation("反馈添加接口") + @PostMapping("addFeedBack") + public ResultBean addFeedBack(String content, HttpServletRequest request) { + UserDetails userDetails = getUserDetails(request); + if (userDetails == null) { + return ResultBean.fail(ResponseStatus.NO_LOGIN); + } + userService.addFeedBack(userDetails.getId(),content); + return ResultBean.ok(); + } + + /** + * 分页查询我的反馈列表 + * */ + @ApiOperation("反馈列表分页查询接口") + @GetMapping("listUserFeedBackByPage") + public ResultBean> listUserFeedBackByPage(@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<>(userService.listUserFeedBackByPage(userDetails.getId(),page,pageSize))); + } + + + /** + * 查询个人信息 + * */ + @ApiOperation("人信息查询接口") + @GetMapping("userInfo") + public ResultBean userInfo(HttpServletRequest request) { + UserDetails userDetails = getUserDetails(request); + if (userDetails == null) { + return ResultBean.fail(ResponseStatus.NO_LOGIN); + } + return ResultBean.ok(userService.userInfo(userDetails.getId())); + } + + + /** + * 更新个人信息 + * */ + @ApiOperation("人信息更新接口") + @PostMapping("updateUserInfo") + public ResultBean updateUserInfo(User user, HttpServletRequest request) { + UserDetails userDetails = getUserDetails(request); + if (userDetails == null) { + return ResultBean.fail(ResponseStatus.NO_LOGIN); + } + userService.updateUserInfo(userDetails.getId(),user); + if(user.getNickName() != null){ + userDetails.setNickName(user.getNickName()); + Map data = new HashMap<>(1); + data.put("token", jwtTokenUtil.generateToken(userDetails)); + return ResultBean.ok(data); + } + return ResultBean.ok(); + } + + /** + * 更新密码 + * */ + @ApiOperation("更新密码接口") + @PostMapping("updatePassword") + public ResultBean updatePassword(String oldPassword,String newPassword1,String newPassword2,HttpServletRequest request) { + UserDetails userDetails = getUserDetails(request); + if (userDetails == null) { + return ResultBean.fail(ResponseStatus.NO_LOGIN); + } + if(!(StringUtils.isNotBlank(newPassword1) && newPassword1.equals(newPassword2))){ + ResultBean.fail(ResponseStatus.TWO_PASSWORD_DIFF); + } + userService.updatePassword(userDetails.getId(),oldPassword,newPassword1); + return ResultBean.ok(); + } diff --git a/novel-user/user-service/src/main/java/com/java2nb/novel/user/feign/BookFeignClient.java b/novel-user/user-service/src/main/java/com/java2nb/novel/user/feign/BookFeignClient.java new file mode 100644 index 0000000..daabb2a --- /dev/null +++ b/novel-user/user-service/src/main/java/com/java2nb/novel/user/feign/BookFeignClient.java @@ -0,0 +1,15 @@ +package com.java2nb.novel.user.feign; + +import com.java2nb.novel.book.api.BookApi; +import org.springframework.cloud.openfeign.FeignClient; + +/** + * 小说服务Feign客户端 + * @author xiongxiaoyang + * @version 1.0 + * @since 2020/5/28 + */ +@FeignClient("book-service") +public interface BookFeignClient extends BookApi { + +} 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 d9fa2c8..7e6b772 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 @@ -1,9 +1,13 @@ package com.java2nb.novel.user.service; +import com.java2nb.novel.book.entity.BookComment; import com.java2nb.novel.common.bean.UserDetails; import com.java2nb.novel.user.entity.User; +import com.java2nb.novel.user.entity.UserFeedback; import com.java2nb.novel.user.form.UserForm; +import com.java2nb.novel.user.vo.BookReadHistoryVO; +import com.java2nb.novel.user.vo.BookShelfVO; import java.util.List; @@ -17,24 +21,130 @@ public interface UserService { /** * 根据用户名密码查询记录 + * * @param username 用户名 * @param password 密码 * @return 用户对象,不存在返回null - * */ + */ User queryByUsernameAndPassword(String username, String password); /** * 用户登陆 + * * @param form 用户登陆提交信息类 * @return jwt载体信息类 - * */ + */ UserDetails login(UserForm form); /** * 根据用户名ID集合查询用户集合信息 + * * @param ids 用户ID集合 * @return 用户集合对象 - * */ + */ List queryById(List ids); + + /** + * 用户注册 + * + * @param form 用户注册提交信息类 + * @return jwt载体信息类 + */ + UserDetails register(UserForm form); + + /** + * 查询小说是否已加入书架 + * + * @param userId 用户ID + * @param bookId 小说ID + * @return true:已加入书架,未加入书架 + */ + Boolean queryIsInShelf(Long userId, Long bookId); + + /** + * 加入书架 + * + * @param userId 用户ID + * @param bookId 小说ID + * @param preContentId 阅读的内容ID + */ + void addToBookShelf(Long userId, Long bookId, Long preContentId); + + /** + * 移出书架 + * + * @param userId 用户ID + * @param bookId 小说ID + */ + void removeFromBookShelf(Long userId, Long bookId); + + /** + * 查询书架 + * + * @param userId 用户ID + * @param page + * @param pageSize + * @return 书架集合 + */ + List listBookShelfByPage(Long userId, int page, int pageSize); + + /** + * 分页查询阅读记录 + * + * @param userId 用户id + * @param page 页码 + * @param pageSize 分页大小 + * @return + */ + List listReadHistoryByPage(Long userId, int page, int pageSize); + + /** + * 添加阅读记录 + * + * @param userId 用户id + * @param bookId 书籍id + * @param preContentId 阅读的目录id + */ + void addReadHistory(Long userId, Long bookId, Long preContentId); + + + + /** + * 添加反馈 + * @param userId 用户id + * @param content 反馈内容 + * */ + void addFeedBack(Long userId, String content); + + /** + * 分页查询我的反馈列表 + * @param userId 用户ID + * @param page 页码 + * @param pageSize 分页大小 + * @return 反馈集合 + * */ + List listUserFeedBackByPage(Long userId, int page, int pageSize); + + /** + * 查询个人信息 + * @param userId 用户id + * @return 用户信息 + * */ + User userInfo(Long userId); + + /** + * 更新个人信息 + * @param userId 用户id + * @param user 需要更新的信息 + * */ + void updateUserInfo(Long userId, User user); + + /** + * 更新密码 + * @param userId 用户id + * @param oldPassword 旧密码 + * @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 1a5eb8c..56cd1ee 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 @@ -1,24 +1,43 @@ package com.java2nb.novel.user.service.impl; +import com.github.pagehelper.PageHelper; +import com.java2nb.novel.book.entity.Book; import com.java2nb.novel.common.bean.UserDetails; import com.java2nb.novel.common.enums.ResponseStatus; import com.java2nb.novel.common.exception.BusinessException; +import com.java2nb.novel.common.utils.IdWorker; import com.java2nb.novel.common.utils.MD5Util; import com.java2nb.novel.user.entity.User; +import com.java2nb.novel.user.entity.UserBookshelf; +import com.java2nb.novel.user.entity.UserFeedback; +import com.java2nb.novel.user.entity.UserReadHistory; +import com.java2nb.novel.user.feign.BookFeignClient; import com.java2nb.novel.user.form.UserForm; -import com.java2nb.novel.user.mapper.UserDynamicSqlSupport; -import com.java2nb.novel.user.mapper.UserMapper; +import com.java2nb.novel.user.mapper.*; import com.java2nb.novel.user.service.UserService; +import com.java2nb.novel.user.vo.BookReadHistoryVO; +import com.java2nb.novel.user.vo.BookShelfVO; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.commons.codec.Charsets; +import org.mybatis.dynamic.sql.delete.render.DeleteStatementProvider; import org.mybatis.dynamic.sql.render.RenderingStrategies; +import org.mybatis.dynamic.sql.select.render.SelectStatementProvider; +import org.mybatis.dynamic.sql.update.render.UpdateStatementProvider; +import org.springframework.beans.BeanUtils; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import java.util.ArrayList; +import java.util.Date; import java.util.List; +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Collectors; -import static org.mybatis.dynamic.sql.SqlBuilder.isEqualTo; -import static org.mybatis.dynamic.sql.SqlBuilder.isIn; +import static com.java2nb.novel.user.mapper.UserBookshelfDynamicSqlSupport.userBookshelf; +import static com.java2nb.novel.user.mapper.UserReadHistoryDynamicSqlSupport.userReadHistory; +import static org.mybatis.dynamic.sql.SqlBuilder.*; import static org.mybatis.dynamic.sql.select.SelectDSL.select; /** @@ -34,6 +53,14 @@ public class UserServiceImpl implements UserService { private final UserMapper userMapper; + private final UserBookshelfMapper userBookshelfMapper; + + private final UserReadHistoryMapper userReadHistoryMapper; + + private final UserFeedbackMapper userFeedbackMapper; + + private final BookFeignClient bookFeignClient; + @Override public User queryByUsernameAndPassword(String username, String password) { @@ -73,4 +100,235 @@ public class UserServiceImpl implements UserService { .where(UserDynamicSqlSupport.id,isIn(ids)).build() .render(RenderingStrategies.MYBATIS3)); } + + @Override + public UserDetails register(UserForm form) { + //查询用户名是否已注册 + SelectStatementProvider selectStatement = select(count(UserDynamicSqlSupport.id)) + .from(UserDynamicSqlSupport.user) + .where(UserDynamicSqlSupport.username, isEqualTo(form.getUsername())) + .build() + .render(RenderingStrategies.MYBATIS3); + long count = userMapper.count(selectStatement); + if (count > 0) { + //用户名已注册 + throw new BusinessException(ResponseStatus.USERNAME_EXIST); + } + User entity = new User(); + BeanUtils.copyProperties(form,entity); + //数据库生成注册记录 + Long id = new IdWorker().nextId(); + entity.setId(id); + entity.setNickName(entity.getUsername()); + Date currentDate = new Date(); + entity.setCreateTime(currentDate); + entity.setUpdateTime(currentDate); + entity.setPassword(MD5Util.MD5Encode(entity.getPassword(), Charsets.UTF_8.name())); + userMapper.insertSelective(entity); + //生成UserDetail对象并返回 + UserDetails userDetails = new UserDetails(); + userDetails.setId(id); + userDetails.setUsername(entity.getUsername()); + userDetails.setNickName(entity.getNickName()); + return userDetails; + } + + @Override + public Boolean queryIsInShelf(Long userId, Long bookId) { + SelectStatementProvider selectStatement = select(count(UserBookshelfDynamicSqlSupport.id)) + .from(userBookshelf) + .where(UserBookshelfDynamicSqlSupport.userId, isEqualTo(userId)) + .and(UserBookshelfDynamicSqlSupport.bookId, isEqualTo(bookId)) + .build() + .render(RenderingStrategies.MYBATIS3); + + return userBookshelfMapper.count(selectStatement) > 0; + } + + @Override + public void addToBookShelf(Long userId, Long bookId, Long preContentId) { + if (!queryIsInShelf(userId, bookId)) { + UserBookshelf shelf = new UserBookshelf(); + shelf.setUserId(userId); + shelf.setBookId(bookId); + shelf.setPreContentId(preContentId); + shelf.setCreateTime(new Date()); + userBookshelfMapper.insert(shelf); + } + } + + @Override + public void removeFromBookShelf(Long userId, Long bookId) { + DeleteStatementProvider deleteStatement = deleteFrom(userBookshelf) + .where(UserBookshelfDynamicSqlSupport.userId, isEqualTo(userId)) + .and(UserBookshelfDynamicSqlSupport.bookId, isEqualTo(bookId)) + .build() + .render(RenderingStrategies.MYBATIS3); + userBookshelfMapper.delete(deleteStatement); + } + + @Override + 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)) + .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)); + + List resultList = new ArrayList<>(booksById.size()); + for(UserBookshelf bookshelf : userBookshelves){ + BookShelfVO bookShelfVO = new BookShelfVO(); + BeanUtils.copyProperties(bookshelf,bookShelfVO); + Book book = booksById.get(bookshelf.getBookId()); + if(book != null){ + BeanUtils.copyProperties(book,bookShelfVO); + resultList.add(bookShelfVO); + } + + } + + + return resultList; + } + + @Override + public List listReadHistoryByPage(Long userId, int page, int pageSize) { + PageHelper.startPage(page, pageSize); + List userReadHistories = userReadHistoryMapper.selectMany( + select(UserReadHistoryDynamicSqlSupport.bookId,UserReadHistoryDynamicSqlSupport.preContentId) + .from(userReadHistory) + .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)); + + List resultList = new ArrayList<>(booksById.size()); + for(UserReadHistory readHistory : userReadHistories){ + BookReadHistoryVO readHistoryVO = new BookReadHistoryVO(); + BeanUtils.copyProperties(readHistory,readHistoryVO); + Book book = booksById.get(readHistory.getBookId()); + if(book != null){ + BeanUtils.copyProperties(book,readHistoryVO); + resultList.add(readHistoryVO); + } + + } + + + return resultList; + } + + @Transactional(rollbackFor = Exception.class) + @Override + public void addReadHistory(Long userId, Long bookId, Long preContentId) { + + Date currentDate = new Date(); + //删除该书以前的历史记录 + DeleteStatementProvider deleteStatement = deleteFrom(userReadHistory) + .where(UserReadHistoryDynamicSqlSupport.bookId, isEqualTo(bookId)) + .and(UserReadHistoryDynamicSqlSupport.userId, isEqualTo(userId)) + .build() + .render(RenderingStrategies.MYBATIS3); + userReadHistoryMapper.delete(deleteStatement); + + //插入该书新的历史记录 + UserReadHistory userReadHistory = new UserReadHistory(); + userReadHistory.setBookId(bookId); + userReadHistory.setUserId(userId); + userReadHistory.setPreContentId(preContentId); + userReadHistory.setCreateTime(currentDate); + userReadHistory.setUpdateTime(currentDate); + userReadHistoryMapper.insertSelective(userReadHistory); + + + //更新书架的阅读历史 + UpdateStatementProvider updateStatement = update(userBookshelf) + .set(UserBookshelfDynamicSqlSupport.preContentId) + .equalTo(preContentId) + .set(UserBookshelfDynamicSqlSupport.updateTime) + .equalTo(currentDate) + .where(UserBookshelfDynamicSqlSupport.userId, isEqualTo(userId)) + .and(UserBookshelfDynamicSqlSupport.bookId, isEqualTo(bookId)) + .build() + .render(RenderingStrategies.MYBATIS3); + + userBookshelfMapper.update(updateStatement); + + + } + + @Override + public void addFeedBack(Long userId, String content) { + UserFeedback feedback = new UserFeedback(); + feedback.setUserId(userId); + feedback.setContent(content); + feedback.setCreateTime(new Date()); + userFeedbackMapper.insertSelective(feedback); + } + + + @Override + public List listUserFeedBackByPage(Long userId, int page, int pageSize) { + PageHelper.startPage(page, pageSize); + return userFeedbackMapper.selectMany(select(UserFeedbackDynamicSqlSupport.content, UserFeedbackDynamicSqlSupport.createTime) + .from(UserFeedbackDynamicSqlSupport.userFeedback) + .where(UserFeedbackDynamicSqlSupport.userId, isEqualTo(userId)) + .orderBy(UserFeedbackDynamicSqlSupport.id.descending()) + .build() + .render(RenderingStrategies.MYBATIS3)); + } + @Override + public User userInfo(Long userId) { + SelectStatementProvider selectStatement = select(UserDynamicSqlSupport.username, UserDynamicSqlSupport.nickName, + UserDynamicSqlSupport.userPhoto,UserDynamicSqlSupport.userSex,UserDynamicSqlSupport.accountBalance) + .from(UserDynamicSqlSupport.user) + .where(UserDynamicSqlSupport.id, isEqualTo(userId)) + .limit(1) + .build() + .render(RenderingStrategies.MYBATIS3); + return userMapper.selectMany(selectStatement).get(0); + } + + @Override + public void updateUserInfo(Long userId, User user) { + User updateUser = new User(); + updateUser.setId(userId); + updateUser.setNickName(user.getNickName()); + updateUser.setUserSex(user.getUserSex()); + updateUser.setUpdateTime(new Date()); + userMapper.updateByPrimaryKeySelective(updateUser); + + } + + @Override + public void updatePassword(Long userId, String oldPassword, String newPassword) { + SelectStatementProvider selectStatement = select(UserDynamicSqlSupport.password) + .from(UserDynamicSqlSupport.user) + .where(UserDynamicSqlSupport.id,isEqualTo(userId)) + .build() + .render(RenderingStrategies.MYBATIS3); + 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)) + .build() + .render(RenderingStrategies.MYBATIS3); + userMapper.update(updateStatement); + + } + + }