search.js 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. import { getNovelSearch } from '../../api/api'
  2. import { goToBookDetail } from '../../utils/util'
  3. Page({
  4. data: {
  5. keyword: '',
  6. bookList: [],
  7. loading: false,
  8. hasMore: true,
  9. page: 1,
  10. size: 10
  11. },
  12. onLoad: function(options) {
  13. // 获取传入的关键词
  14. const keyword = options.keyword || '';
  15. this.setData({ keyword });
  16. // 如果有关键词,立即搜索
  17. if (keyword) {
  18. this.search();
  19. }
  20. },
  21. // 输入框内容变化
  22. handleInput: function(e) {
  23. this.setData({
  24. keyword: e.detail.value
  25. });
  26. },
  27. // 清空搜索内容
  28. clearSearch: function() {
  29. this.setData({
  30. keyword: '',
  31. bookList: []
  32. });
  33. },
  34. // 开始搜索
  35. search: function() {
  36. // 如果关键词为空,不执行搜索
  37. if (!this.data.keyword.trim()) {
  38. return;
  39. }
  40. // 重置搜索状态
  41. this.setData({
  42. page: 1,
  43. bookList: [],
  44. hasMore: true
  45. });
  46. // 执行搜索
  47. this.loadSearchResult();
  48. },
  49. // 加载搜索结果
  50. async loadSearchResult() {
  51. if (this.data.loading || !this.data.hasMore) return;
  52. this.setData({ loading: true });
  53. try {
  54. const params = {
  55. keyword: this.data.keyword,
  56. page: this.data.page,
  57. size: this.data.size
  58. };
  59. const result = await getNovelSearch(params);
  60. if (result && result.records) {
  61. // 处理搜索结果,标记匹配关键字的部分
  62. const processedList = this.processBookList(result.records);
  63. const newList = this.data.page === 1 ? processedList : [...this.data.bookList, ...processedList];
  64. const hasMore = !result.last;
  65. this.setData({
  66. bookList: newList,
  67. loading: false,
  68. hasMore: hasMore,
  69. page: hasMore ? this.data.page + 1 : this.data.page
  70. });
  71. } else {
  72. this.setData({
  73. loading: false,
  74. hasMore: false
  75. });
  76. }
  77. } catch (error) {
  78. console.error('搜索失败:', error);
  79. this.setData({
  80. loading: false,
  81. hasMore: false
  82. });
  83. wx.showToast({
  84. title: '搜索失败,请重试',
  85. icon: 'none'
  86. });
  87. }
  88. },
  89. // 处理搜索结果,标记匹配关键字的部分
  90. processBookList(books) {
  91. if (!this.data.keyword || !books || !books.length) return books;
  92. const keyword = this.data.keyword.trim();
  93. return books.map(book => {
  94. if (book.title && keyword) {
  95. // 添加标记,表示这本书的标题包含关键字
  96. book.titleContainsKeyword = book.title.toLowerCase().includes(keyword.toLowerCase());
  97. // 添加处理后的标题,用于在WXML中展示
  98. // 由于小程序不支持直接用rich-text高亮,我们标记出匹配部分在后续WXML中用view嵌套处理
  99. const titleLower = book.title.toLowerCase();
  100. const keywordLower = keyword.toLowerCase();
  101. if (book.titleContainsKeyword) {
  102. const index = titleLower.indexOf(keywordLower);
  103. if (index !== -1) {
  104. book.titleBeforeKeyword = book.title.substring(0, index);
  105. book.titleKeyword = book.title.substring(index, index + keyword.length);
  106. book.titleAfterKeyword = book.title.substring(index + keyword.length);
  107. }
  108. }
  109. }
  110. return book;
  111. });
  112. },
  113. // 监听滚动到底部
  114. onScrollToLower: function() {
  115. if (this.data.hasMore) {
  116. this.loadSearchResult();
  117. }
  118. },
  119. // 跳转到书籍详情
  120. handleBookTap: function(e) {
  121. const { id, wxbookid } = e.currentTarget.dataset;
  122. goToBookDetail({
  123. bookId: id,
  124. wxBookId: wxbookid
  125. });
  126. },
  127. // 返回上一页
  128. goBack: function() {
  129. wx.navigateBack({
  130. delta: 1
  131. });
  132. }
  133. })