图书馆小程序
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

274 lines
6.3 KiB

2 months ago
1 month ago
2 months ago
1 month ago
1 month ago
2 months ago
1 month ago
2 months ago
1 month ago
1 month ago
1 month ago
2 months ago
1 month ago
2 months ago
1 month ago
2 months ago
1 month ago
2 months ago
1 month ago
2 months ago
1 month ago
2 months ago
1 month ago
1 month ago
2 months ago
1 month ago
1 month ago
1 month ago
2 months ago
1 month ago
1 month ago
1 month ago
2 months ago
1 month ago
1 month ago
2 months ago
2 months ago
1 month ago
2 months ago
1 month ago
2 months ago
1 month ago
2 months ago
1 month ago
  1. <template>
  2. <view class="collection-page">
  3. <view class="content-box">
  4. <view class="empty" v-if="bookCollectList.length === 0 && !isLoading">
  5. <uni-icons style="margin-left: 20px;" custom-prefix="iconfont" type="icon-kongshuju" size="80"></uni-icons>
  6. <text style="margin-top: 20px;">暂无收藏的图书~</text>
  7. </view>
  8. <view class="recommendation-list" v-else>
  9. <book-list-item
  10. class="hot-list-item"
  11. v-for="(item, index) in bookCollectList"
  12. :key="index"
  13. :data="item"
  14. :ranking="index + 1"
  15. @click="onItemClick(item)"
  16. ></book-list-item>
  17. </view>
  18. <uni-load-more status="loading" v-if="isLoading && bookCollectList.length > 0"></uni-load-more>
  19. <view class="no-more" v-if="noMore && bookCollectList.length > 0">
  20. 没有更多数据了
  21. </view>
  22. </view>
  23. </view>
  24. </template>
  25. <script>
  26. import BookListItem from "@/components/book-list-item/book-list-item.vue";
  27. import { FetchFindAllBookCollectionByOpenId } from '@/api/book';
  28. import { getOpenId } from '@/utils/storage';
  29. import config from '@/utils/config';
  30. import { loadBookCovers } from '@/utils/bookCover';
  31. export default {
  32. components: {
  33. BookListItem,
  34. },
  35. data() {
  36. return {
  37. isLoading: false,
  38. noMore: false,
  39. pageNum: 0,
  40. pageSize: 10,
  41. bookCollectList: [],
  42. hasLoadedAll: false,
  43. }
  44. },
  45. onLoad() {
  46. // this.loadData();
  47. },
  48. onShow() {
  49. // 检查是否需要刷新(从图书详情取消收藏回来)
  50. const needRefresh = uni.getStorageSync('needRefreshCollect');
  51. uni.removeStorageSync('needRefreshCollect');
  52. // 如果已经加载到最后,或者有取消收藏操作,需要刷新数据
  53. if (this.hasLoadedAll || needRefresh) {
  54. this.refreshData();
  55. } else if (this.bookCollectList.length === 0) {
  56. // 如果还没加载过数据,也需要加载
  57. this.refreshData();
  58. }
  59. },
  60. onPullDownRefresh() {
  61. this.refreshData();
  62. },
  63. onReachBottom() {
  64. if (this.noMore || this.isLoading) return;
  65. this.loadMore();
  66. },
  67. methods: {
  68. // getTest(){
  69. // // 34352,36153
  70. // wx.request({
  71. // url: `http://218.200.95.251:8081/opac/getExistsBookrecnoList/41534`,
  72. // method: 'POST',
  73. // success: (res) => {
  74. // console.log(res.data || []);
  75. // },
  76. // fail: () => {
  77. // resolve([]);
  78. // }
  79. // });
  80. // },
  81. async loadData() {
  82. this.isLoading = true;
  83. try {
  84. const openId = await getOpenId();
  85. if (!openId) {
  86. uni.showToast({ title: '获取用户信息失败', icon: 'none' });
  87. this.isLoading = false;
  88. return;
  89. }
  90. const res = await FetchFindAllBookCollectionByOpenId({
  91. libcode: config.LIB_CODE,
  92. openId: openId,
  93. page: this.pageNum,
  94. size: this.pageSize,
  95. });
  96. if (res.code === 200) {
  97. this.bookCollectList = res.data.content || [];
  98. this.noMore = (res.data.content || []).length < this.pageSize;
  99. this.hasLoadedAll = this.noMore;
  100. // 加载封面
  101. this.loadCoversForList();
  102. } else {
  103. uni.showToast({ title: res.message || '获取收藏列表失败', icon: 'none' });
  104. }
  105. } catch (err) {
  106. console.error('获取收藏列表失败', err);
  107. uni.showToast({ title: '获取收藏列表失败', icon: 'none' });
  108. } finally {
  109. this.isLoading = false;
  110. }
  111. },
  112. async refreshData() {
  113. this.pageNum = 0;
  114. this.noMore = false;
  115. this.bookCollectList = [];
  116. await this.loadData();
  117. // 滚动条回到顶部
  118. uni.pageScrollTo({
  119. scrollTop: 0,
  120. duration: 300
  121. });
  122. uni.stopPullDownRefresh();
  123. },
  124. async loadMore() {
  125. if (this.noMore || this.isLoading) return;
  126. this.pageNum++;
  127. this.isLoading = true;
  128. try {
  129. const openId = await getOpenId();
  130. if (!openId) {
  131. uni.showToast({ title: '获取用户信息失败', icon: 'none' });
  132. this.isLoading = false;
  133. return;
  134. }
  135. const res = await FetchFindAllBookCollectionByOpenId({
  136. libcode: config.LIB_CODE,
  137. openId: openId,
  138. page: this.pageNum,
  139. size: this.pageSize,
  140. });
  141. console.log('res',res)
  142. console.log('res.data',res.data)
  143. console.log('res.data.content',res.data.content)
  144. if (res.code === 200) {
  145. const newData = res.data.content || [];
  146. this.bookCollectList = [...this.bookCollectList, ...newData];
  147. this.noMore = newData.length < this.pageSize;
  148. // 为新加载的数据加载封面
  149. if (newData.length > 0) {
  150. await this.loadCoversForList();
  151. }
  152. } else {
  153. this.pageNum--;
  154. uni.showToast({ title: res.message || '加载更多失败', icon: 'none' });
  155. }
  156. } catch (err) {
  157. console.error('加载更多收藏失败', err);
  158. this.pageNum--;
  159. uni.showToast({ title: '加载更多失败', icon: 'none' });
  160. } finally {
  161. this.isLoading = false;
  162. }
  163. },
  164. async loadCoversForList() {
  165. await loadBookCovers(this.bookCollectList, (index, coverUrl) => {
  166. console.log('index', index);
  167. console.log('coverUrl', coverUrl);
  168. if (this.bookCollectList[index]) {
  169. // 使用 Vue.set 确保响应式更新
  170. this.$set(this.bookCollectList[index], 'cover', coverUrl);
  171. }
  172. });
  173. },
  174. onItemClick(item) {
  175. console.log('item',item)
  176. uni.navigateTo({
  177. url: "/subpkg/pages/book-detail/book-detail?searchData=" + encodeURIComponent(JSON.stringify(item)) + '&isCollected=true'
  178. })
  179. }
  180. }
  181. }
  182. </script>
  183. <style lang="scss" scoped>
  184. .collection-page {
  185. padding: 10px 0;
  186. background-color: #f7f8fa;
  187. min-height: 100vh;
  188. }
  189. .content-box {
  190. padding: 0 10px;
  191. }
  192. .empty {
  193. padding: 60px 0;
  194. text-align: center;
  195. color: #999;
  196. }
  197. .no-more {
  198. text-align: center;
  199. padding: 20px 0;
  200. color: #999;
  201. font-size: 13px;
  202. }
  203. .recommendation-list {
  204. display: flex;
  205. flex-direction: column;
  206. gap: 12px;
  207. }
  208. .book-item {
  209. display: flex;
  210. background: #fff;
  211. border-radius: 8px;
  212. padding: 12px;
  213. box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
  214. }
  215. .book-cover {
  216. width: 80px;
  217. height: 100px;
  218. border-radius: 4px;
  219. flex-shrink: 0;
  220. background: #f5f5f5;
  221. }
  222. .book-info {
  223. flex: 1;
  224. display: flex;
  225. flex-direction: column;
  226. justify-content: center;
  227. padding-left: 12px;
  228. overflow: hidden;
  229. }
  230. .book-title {
  231. font-size: 15px;
  232. font-weight: 500;
  233. color: #333;
  234. line-height: 1.4;
  235. display: -webkit-box;
  236. -webkit-box-orient: vertical;
  237. -webkit-line-clamp: 2;
  238. overflow: hidden;
  239. }
  240. .book-author {
  241. font-size: 13px;
  242. color: #999;
  243. margin-top: 6px;
  244. }
  245. .book-publisher {
  246. font-size: 12px;
  247. color: #ccc;
  248. margin-top: 4px;
  249. }
  250. </style>