|
@@ -30,6 +30,7 @@ import com.google.gson.JsonParser;
|
|
|
import org.apache.commons.lang3.StringUtils;
|
|
|
import org.slf4j.Logger;
|
|
|
import org.slf4j.LoggerFactory;
|
|
|
+import org.springframework.beans.BeanUtils;
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
import org.springframework.data.redis.core.RedisTemplate;
|
|
|
import org.springframework.stereotype.Service;
|
|
@@ -74,8 +75,18 @@ public class BookServiceImpl implements BookService {
|
|
|
|
|
|
@Override
|
|
|
public List<BookRes> query(QueryVO queryVO) {
|
|
|
- queryVO.setQuery("%" + queryVO.getQuery() + "%");
|
|
|
- List<BookRes> bookResList = bookMapper2.queryBookRes(queryVO, queryVO.getPage() * queryVO.getSize(), queryVO.getSize());
|
|
|
+ List<BookRes> bookResList = new ArrayList<>();
|
|
|
+ if (queryVO.getBookId() != null) {
|
|
|
+ Book bookById = getBookById(queryVO.getBookId());
|
|
|
+ String categoryName = getCategoryName(bookById.getBookCategoryId());
|
|
|
+ BookRes bookRes = new BookRes();
|
|
|
+ BeanUtils.copyProperties(bookById, bookRes);
|
|
|
+ bookRes.setCategoryName(categoryName);
|
|
|
+ bookResList.add(bookRes);
|
|
|
+ } else {
|
|
|
+ queryVO.setQuery("%" + queryVO.getQuery() + "%");
|
|
|
+ bookResList = bookMapper2.queryBookRes(queryVO, queryVO.getPage() * queryVO.getSize(), queryVO.getSize());
|
|
|
+ }
|
|
|
return bookResList;
|
|
|
}
|
|
|
|
|
@@ -85,13 +96,44 @@ public class BookServiceImpl implements BookService {
|
|
|
if (queryVO.getPage() == 5) {
|
|
|
return bookRes;
|
|
|
}
|
|
|
+ return getRecommendFromCache(queryVO);
|
|
|
+ }
|
|
|
+
|
|
|
+ public List<BookRes> getRecommendFromCache(QueryVO queryVO) {
|
|
|
+ String key = "recommend_" + queryVO.getSex() + "_" + queryVO.getPage() + "_" + queryVO.getSize();
|
|
|
+ Object o = redisUtil.get(key);
|
|
|
+ if (o == null) {
|
|
|
+ return setRecommendCache(key, queryVO);
|
|
|
+ } else {
|
|
|
+ return (List<BookRes>) o;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public synchronized List<BookRes> setRecommendCache(String key, QueryVO queryVO) {
|
|
|
+ Object o = redisUtil.get(key);
|
|
|
+ if (o != null) {
|
|
|
+ return (List<BookRes>) o;
|
|
|
+ }
|
|
|
List<BookRes> books = bookMapper2.novelEndRecommend(queryVO,
|
|
|
queryVO.getPage() * queryVO.getSize(), queryVO.getSize());
|
|
|
+ redisUtil.setWithTime(key, books);
|
|
|
return books;
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
public List<BlockRes> getBlockByPageId(Integer pageId) {
|
|
|
+ ArrayList<BlockRes> list = setBlockByPageIdCache(pageId);
|
|
|
+ return list;
|
|
|
+ }
|
|
|
+
|
|
|
+ private synchronized ArrayList<BlockRes> setBlockByPageIdCache(Integer pageId) {
|
|
|
+ //缓存
|
|
|
+ String key = pageId.toString();
|
|
|
+ Object o = redisUtil.get(key);
|
|
|
+ if (o != null) {
|
|
|
+ return (ArrayList<BlockRes>) o;
|
|
|
+ }
|
|
|
+ //没有缓存
|
|
|
ArrayList<BlockRes> list = new ArrayList<>();
|
|
|
// 获取板块
|
|
|
ManageBlockExample manageBlockExample = ManageBlockExample.newAndCreateCriteria()
|
|
@@ -100,7 +142,6 @@ public class BookServiceImpl implements BookService {
|
|
|
manageBlockExample.orderBy(ManageBlock.Column.weigh.desc());
|
|
|
List<ManageBlock> manageBlocks = manageBlockMapper.selectByExample(manageBlockExample);
|
|
|
|
|
|
-
|
|
|
// 获取已有版本的所有书籍
|
|
|
List<Integer> blockIds = manageBlocks.stream().map(ManageBlock::getId).collect(Collectors.toList());
|
|
|
List<ManageBlockResourceRes> blockResourceResList = manageBlockResource2Mapper.getBooks(blockIds);
|
|
@@ -120,9 +161,11 @@ public class BookServiceImpl implements BookService {
|
|
|
blockRes.setResources(map.getOrDefault(x.getId(), new TreeSet<>()));
|
|
|
list.add(blockRes);
|
|
|
});
|
|
|
+ redisUtil.setWithTime(key, list);
|
|
|
return list;
|
|
|
}
|
|
|
|
|
|
+
|
|
|
@Override
|
|
|
public void insertBooks() {
|
|
|
|
|
@@ -230,11 +273,29 @@ public class BookServiceImpl implements BookService {
|
|
|
|
|
|
@Override
|
|
|
public List<Chapter> getChaptersByBookId(Long bookId) {
|
|
|
- List<Chapter> list = new ArrayList<>();
|
|
|
-
|
|
|
if (bookId == null) {
|
|
|
throw new IllegalArgumentException("bookId cannot be null or empty");
|
|
|
}
|
|
|
+
|
|
|
+ //缓存
|
|
|
+ String key = "chaptersByBookId" + bookId;
|
|
|
+ Object o = redisUtil.get(key);
|
|
|
+ if (o != null) {
|
|
|
+ return (List<Chapter>) o;
|
|
|
+ } else {
|
|
|
+ return setChaptersByBookIdCache(bookId);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private synchronized List<Chapter> setChaptersByBookIdCache(Long bookId) {
|
|
|
+ String key = "chaptersByBookId" + bookId;
|
|
|
+ Object o = redisUtil.get(key);
|
|
|
+ if (o != null) {
|
|
|
+ return (List<Chapter>) o;
|
|
|
+ }
|
|
|
+
|
|
|
+ List<Chapter> list = new ArrayList<>();
|
|
|
+
|
|
|
final String chaptersUrl = "http://new.emeixs.com/index.php/Home/Interface/chapters/bid/" + bookId;
|
|
|
String result = HttpTool.sendGet(chaptersUrl, "");
|
|
|
if (StringUtils.isEmpty(result)) {
|
|
@@ -263,22 +324,39 @@ public class BookServiceImpl implements BookService {
|
|
|
chapter.setType(jsonObject.get("type").getAsString());
|
|
|
chapter.setVolumeId(jsonObject.get("volume_id").getAsString());
|
|
|
chapter.setWords(jsonObject.get("words").getAsString());
|
|
|
- if (i + 1 == freeChapterNum) {
|
|
|
+ if (i + 1 <= freeChapterNum) {
|
|
|
chapter.setReadAble("0");
|
|
|
}
|
|
|
list.add(chapter);
|
|
|
}
|
|
|
-
|
|
|
+ redisUtil.setWithTime(key, list);
|
|
|
return list;
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
public List<SearchKeyword> getSearchKeywordBySex(String sex) {
|
|
|
+ String key = "getSearchKeywordBySex" + sex;
|
|
|
+ Object o = redisUtil.get(key);
|
|
|
+ if (o != null) {
|
|
|
+ return (List<SearchKeyword>) o;
|
|
|
+ } else {
|
|
|
+ return getSearchKeywordsCache(key, sex);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private List<SearchKeyword> getSearchKeywordsCache(String key, String sex) {
|
|
|
+ Object o = redisUtil.get(key);
|
|
|
+ if (o != null) {
|
|
|
+ return (List<SearchKeyword>) o;
|
|
|
+ }
|
|
|
+
|
|
|
SearchKeywordExample example = SearchKeywordExample.newAndCreateCriteria()
|
|
|
.andSexEqualTo(sex)
|
|
|
.example();
|
|
|
example.orderBy(SearchKeyword.Column.weigh.desc());
|
|
|
List<SearchKeyword> searchKeywords = searchKeywordMapper.selectByExample(example);
|
|
|
+
|
|
|
+ redisUtil.setWithTime(key, searchKeywords);
|
|
|
return searchKeywords;
|
|
|
}
|
|
|
|
|
@@ -288,9 +366,35 @@ public class BookServiceImpl implements BookService {
|
|
|
return getRandom(bookRes);
|
|
|
}
|
|
|
|
|
|
+ private synchronized List<BookRes> setTopRecommendCache(String key, QueryVO queryVO) {
|
|
|
+ Object o = redisUtil.get(key);
|
|
|
+ if (o != null) {
|
|
|
+ return (List<BookRes>) o;
|
|
|
+ }
|
|
|
+ List<BookRes> bookRes = bookMapper2.topRecommend(queryVO, 0, 20);
|
|
|
+ redisUtil.setWithTime(key, bookRes);
|
|
|
+ return bookRes;
|
|
|
+ }
|
|
|
+
|
|
|
@Override
|
|
|
public List<BookRes> smartRecommand(QueryVO queryVO) {
|
|
|
+ String key = "smartRecommand_" + queryVO.getSex();
|
|
|
+ Object o = redisUtil.get(key);
|
|
|
+ if (o == null) {
|
|
|
+ List<BookRes> bookRes = setSmartRecommandCache(queryVO, key);
|
|
|
+ return bookRes;
|
|
|
+ } else {
|
|
|
+ return (List<BookRes>) o;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private synchronized List<BookRes> setSmartRecommandCache(QueryVO queryVO, String key) {
|
|
|
+ Object o = redisUtil.get(key);
|
|
|
+ if (o != null) {
|
|
|
+ return (List<BookRes>) o;
|
|
|
+ }
|
|
|
List<BookRes> bookRes = bookMapper2.smartRecommand(queryVO);
|
|
|
+ redisUtil.setWithTime(key, bookRes);
|
|
|
return bookRes;
|
|
|
}
|
|
|
|
|
@@ -356,7 +460,7 @@ public class BookServiceImpl implements BookService {
|
|
|
// 更新免费看点到 user
|
|
|
int i = userMapper.updateUserKandian(user, user.getKandian(), freeCount - book.getPrice(), DateUtils.getNow());
|
|
|
checkUpdate(i);
|
|
|
- updateUserById(user.getId());
|
|
|
+ updateUserByIdCache(user.getId());
|
|
|
|
|
|
} else if (user.getKandian() + freeCount > book.getPrice()) { //免费+充值足够
|
|
|
Integer left = user.getKandian() + freeCount;
|
|
@@ -375,7 +479,7 @@ public class BookServiceImpl implements BookService {
|
|
|
// 更新到 user
|
|
|
int i = userMapper.updateUserKandian(user, kandian, 0, DateUtils.getNow());
|
|
|
checkUpdate(i);
|
|
|
- updateUserById(user.getId());
|
|
|
+ updateUserByIdCache(user.getId());
|
|
|
|
|
|
} else {
|
|
|
return Result.failure(ResultCode.NOMONEY);
|
|
@@ -421,7 +525,23 @@ public class BookServiceImpl implements BookService {
|
|
|
}
|
|
|
|
|
|
private BookContent getBookContent(BookContentVO bookContentVO) {
|
|
|
+ String key = "" + bookContentVO.getBookId() + bookContentVO.getContentId();
|
|
|
+ Object o = redisUtil.get(key);
|
|
|
+ if (o != null) {
|
|
|
+ return (BookContent) o;
|
|
|
+ } else {
|
|
|
+ return setBookContentCache(key, bookContentVO);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private synchronized BookContent setBookContentCache(String key, BookContentVO bookContentVO) {
|
|
|
+ Object o = redisUtil.get(key);
|
|
|
+ if (o != null) {
|
|
|
+ return (BookContent) o;
|
|
|
+ }
|
|
|
+
|
|
|
BookContent bookContent;
|
|
|
+ // 修改过的章节
|
|
|
String content = getEditBookContentById(bookContentVO.getBookId(), bookContentVO.getContentId());
|
|
|
if (content != null) {
|
|
|
return getBookContentFromVO(bookContentVO, content);
|
|
@@ -433,6 +553,7 @@ public class BookServiceImpl implements BookService {
|
|
|
} else {
|
|
|
bookContent = getBookContentFromRemote(bookContentVO);
|
|
|
}
|
|
|
+ redisUtil.setWithTime(key, bookContent);
|
|
|
return bookContent;
|
|
|
}
|
|
|
|
|
@@ -752,14 +873,23 @@ public class BookServiceImpl implements BookService {
|
|
|
String key = "defaultFreeChapterNum";
|
|
|
Object o = redisUtil.get(key);
|
|
|
if (o == null) {
|
|
|
- int book_free_chapter_num = Integer.parseInt(configMapper.selectByName("book_free_chapter_num").getValue());
|
|
|
- redisUtil.set(key, book_free_chapter_num, 1, TimeUnit.HOURS);
|
|
|
+ int book_free_chapter_num = setBook_free_chapter_num(key);
|
|
|
return book_free_chapter_num;
|
|
|
} else {
|
|
|
return (int) o;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ private synchronized int setBook_free_chapter_num(String key) {
|
|
|
+ Object o = redisUtil.get(key);
|
|
|
+ if (o != null) {
|
|
|
+ return (int) o;
|
|
|
+ }
|
|
|
+ int book_free_chapter_num = Integer.parseInt(configMapper.selectByName("book_free_chapter_num").getValue());
|
|
|
+ redisUtil.setWithTime(key, book_free_chapter_num);
|
|
|
+ return book_free_chapter_num;
|
|
|
+ }
|
|
|
+
|
|
|
public Book getBookById(Long id) {
|
|
|
String key = "book" + id;
|
|
|
Object o = redisUtil.get(key);
|
|
@@ -770,10 +900,14 @@ public class BookServiceImpl implements BookService {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- public Book updateBookByIdToRedis(Long id) {
|
|
|
+ public synchronized Book updateBookByIdToRedis(Long id) {
|
|
|
String key = "book" + id;
|
|
|
+ Object o = redisUtil.get(key);
|
|
|
+ if (o != null) {
|
|
|
+ return (Book) o;
|
|
|
+ }
|
|
|
Book obj = bookMapper.selectByPrimaryKey(id);
|
|
|
- redisUtil.set(key, obj, 15, TimeUnit.MINUTES);
|
|
|
+ redisUtil.setWithTime(key, obj);
|
|
|
return obj;
|
|
|
}
|
|
|
|
|
@@ -781,19 +915,52 @@ public class BookServiceImpl implements BookService {
|
|
|
String key = "user" + id;
|
|
|
Object o = redisUtil.get(key);
|
|
|
if (o == null) {
|
|
|
- return updateUserById(id);
|
|
|
+ return updateUserByIdCache(id);
|
|
|
} else {
|
|
|
return (User) o;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- public User updateUserById(Long id) {
|
|
|
+ public synchronized User updateUserByIdCache(Long id) {
|
|
|
String key = "user" + id;
|
|
|
+ Object o = redisUtil.get(key);
|
|
|
+ if (o != null) {
|
|
|
+ return (User) o;
|
|
|
+ }
|
|
|
User obj = userMapper.selectByPrimaryKey(id);
|
|
|
- redisUtil.set(key, obj, 30, TimeUnit.MINUTES);
|
|
|
+ redisUtil.setWithTime(key, obj);
|
|
|
return obj;
|
|
|
}
|
|
|
|
|
|
+ public String getCategoryName(Integer id) {
|
|
|
+ String key = "category";
|
|
|
+ Object o = redisUtil.hashGet(key, id);
|
|
|
+ if (o == null) {
|
|
|
+ String name = setCategoryCache(id, key);
|
|
|
+ return name;
|
|
|
+ } else {
|
|
|
+ return (String) o;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private synchronized String setCategoryCache(Integer id, String key) {
|
|
|
+ Object o = redisUtil.hashGet(key, id);
|
|
|
+ if (o != null) {
|
|
|
+ return (String) o;
|
|
|
+ }
|
|
|
+ List<BookCategory> bookCategories = bookCategoryMapper.selectByExample(BookCategoryExample.newAndCreateCriteria().example());
|
|
|
+ String name = "";
|
|
|
+ for (BookCategory x : bookCategories) {
|
|
|
+ redisUtil.hashSet(key, x.getId(), x.getName());
|
|
|
+ if (x.getId() == id) {
|
|
|
+ name = x.getName();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ redisTemplate.expire(key, redisUtil.getRandomTime(), TimeUnit.MINUTES);
|
|
|
+ return name;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
@Autowired
|
|
|
private RedisTemplate redisTemplate;
|
|
|
|
|
@@ -807,7 +974,7 @@ public class BookServiceImpl implements BookService {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- public EditBook updateEditBookById(Long bookId, Long chapterId) {
|
|
|
+ public synchronized void updateEditBookById(Long bookId, Long chapterId) {
|
|
|
String key = "edit_book" + bookId + chapterId;
|
|
|
EditBook obj = editBookMapper.selectOneByExampleSelective(
|
|
|
EditBookExample.newAndCreateCriteria()
|
|
@@ -817,11 +984,10 @@ public class BookServiceImpl implements BookService {
|
|
|
EditBook.Column.content
|
|
|
);
|
|
|
redisUtil.set(key, obj);
|
|
|
- return obj;
|
|
|
}
|
|
|
|
|
|
@PostConstruct
|
|
|
- public void initUpdateEditBookIds() {
|
|
|
+ public void initUpdateEditBookIdsCache() {
|
|
|
List<EditBook> editBooks = editBookMapper.selectByExampleSelective(EditBookExample.newAndCreateCriteria().example(),
|
|
|
EditBook.Column.bookId, EditBook.Column.chapterId, EditBook.Column.content);
|
|
|
editBooks.forEach(x -> {
|