图书馆小程序
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.

299 lines
7.6 KiB

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
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
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
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
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
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. <template>
  2. <view class="lending-container">
  3. <!-- 固定只有两个 tab -->
  4. <view class="tab-sticky">
  5. <my-tabs
  6. :tabData="tabData"
  7. :defaultIndex="currentIndex"
  8. :config="{ textColor: '#333' }"
  9. @tabClick="tabClick"
  10. />
  11. </view>
  12. <swiper
  13. class="swiper"
  14. :current="currentIndex"
  15. :style="{ height: currentSwiperHeight + 'px' }"
  16. @animationfinish="onSwiperEnd"
  17. @change="onSwiperChange"
  18. >
  19. <!-- 全部历史借阅 -->
  20. <swiper-item>
  21. <view class="list-wrapper">
  22. <uni-load-more status="loading" v-if="loadingAll" />
  23. <view class="empty" v-else-if="allList.length === 0">
  24. 暂无全部记录
  25. </view>
  26. <lending-list-item
  27. class="list-item-all"
  28. v-for="(item, index) in allList"
  29. :key="index"
  30. :data="item"
  31. :is-lending="false"
  32. />
  33. <uni-load-more
  34. v-if="allList.length > 0 && hasMoreAll"
  35. :status="loadMoreStatusAll"
  36. />
  37. </view>
  38. </swiper-item>
  39. <!-- 在借中 -->
  40. <swiper-item>
  41. <view class="list-wrapper">
  42. <uni-load-more status="loading" v-if="loadingLending" />
  43. <view class="empty" v-else-if="lendingList.length === 0">
  44. 暂无在借记录
  45. </view>
  46. <lending-list-item
  47. class="list-item-lending"
  48. v-for="(item, index) in lendingList"
  49. :key="index"
  50. :data="item"
  51. :is-lending="true"
  52. />
  53. </view>
  54. </swiper-item>
  55. </swiper>
  56. </view>
  57. </template>
  58. <script>
  59. import { FetchInitScreenSetting } from '@/api/user';
  60. import { FetchHistoryloan, FetchRdloanlist, FetchCoverByISBN } from '@/api/book';
  61. import myTabs from "@/components/my-tabs/my-tabs.vue";
  62. import lendingListItem from "@/components/lending-list-item/lending-list-item.vue";
  63. export default {
  64. components: { myTabs, lendingListItem },
  65. data() {
  66. return {
  67. screenConfig: {},
  68. tabData: [
  69. { label: '历史借阅', status: 'all' },
  70. { label: '在借中', status: 'lending' },
  71. ],
  72. currentIndex: 0,
  73. // 全部(历史)独立数据
  74. allList: [],
  75. loadingAll: false,
  76. pageAll: 1,
  77. hasMoreAll: true,
  78. loadMoreStatusAll: '',
  79. // 在借中 独立数据
  80. lendingList: [],
  81. loadingLending: false,
  82. swiperHeightData: {},
  83. currentSwiperHeight: 400,
  84. };
  85. },
  86. onLoad() {
  87. this.getScreenSetting();
  88. },
  89. onShow() {
  90. const tabIndex = uni.getStorageSync('switch_tab_index');
  91. if (tabIndex !== '') {
  92. this.currentIndex = Number(tabIndex);
  93. uni.removeStorageSync('switch_tab_index');
  94. }
  95. },
  96. onPullDownRefresh() {
  97. if (this.currentIndex === 0) {
  98. this.getAllList(true);
  99. } else {
  100. this.getLendingList();
  101. }
  102. },
  103. onReachBottom() {
  104. if (this.currentIndex === 0 && this.hasMoreAll) {
  105. this.getAllList();
  106. }
  107. },
  108. methods: {
  109. // 获取封面(你要的格式)
  110. async getBookListWithCovers(bookList) {
  111. const bookWithCovers = await Promise.all(
  112. bookList.map(async (item) => {
  113. if (!item.isbn) return { ...item, cover: '' };
  114. const isbn = item.isbn.replace(/\-/g, '').trim();
  115. try {
  116. const coverRes = await FetchCoverByISBN({ isbn });
  117. return { ...item, cover: coverRes || '' };
  118. } catch (e) {
  119. console.error(`获取ISBN:${isbn}封面失败`, e);
  120. return { ...item, cover: '' };
  121. }
  122. })
  123. );
  124. return bookWithCovers;
  125. },
  126. async getScreenSetting() {
  127. try {
  128. const res = await FetchInitScreenSetting({ libcode: '1201' });
  129. const data = res.data;
  130. this.screenConfig = {
  131. thirdUrl: data.open_lib_http?.context || '',
  132. thirdAppid: data.open_lib_appId?.context || '',
  133. thirdSecret: data.open_lib_secret?.context || '',
  134. sm4Key: data.sm4_key?.context || ''
  135. };
  136. // 默认加载第一个 tab
  137. this.getAllList(true);
  138. } catch (err) {}
  139. },
  140. async getAllList(isRefresh = false) {
  141. if (this.loadingAll) return;
  142. this.loadingAll = true;
  143. if (isRefresh) {
  144. this.pageAll = 1;
  145. this.allList = [];
  146. this.hasMoreAll = true;
  147. this.loadMoreStatusAll = '';
  148. }
  149. try {
  150. const params = {
  151. ...this.screenConfig,
  152. rdid: uni.getStorageSync('currentReaderCard'),
  153. logtype: '30002',
  154. page: this.pageAll,
  155. rows: 10,
  156. };
  157. const res = await FetchHistoryloan(params);
  158. const result = typeof res.data === 'string' ? JSON.parse(res.data) : res.data;
  159. let list = result.hloanlist || [];
  160. // 插入封面
  161. // list = await this.getBookListWithCovers(list);
  162. this.allList = [...this.allList, ...list];
  163. this.hasMoreAll = list.length === 10;
  164. this.loadMoreStatusAll = this.hasMoreAll ? '' : 'no-more';
  165. if (this.hasMoreAll) this.pageAll++;
  166. } catch (err) {
  167. } finally {
  168. this.loadingAll = false;
  169. uni.stopPullDownRefresh();
  170. setTimeout(() => {
  171. this.calcHeight('all');
  172. }, 100);
  173. }
  174. },
  175. async getLendingList() {
  176. this.loadingLending = true;
  177. try {
  178. const params = {
  179. ...this.screenConfig,
  180. rdid: uni.getStorageSync('currentReaderCard'),
  181. };
  182. const res = await FetchRdloanlist(params);
  183. const result = typeof res.data === 'string' ? JSON.parse(res.data) : res.data;
  184. let list = result.loanlist || [];
  185. // 插入封面
  186. // list = await this.getBookListWithCovers(list);
  187. this.lendingList = list.map(item => ({
  188. ...item,
  189. loantime: item.loandate || '',
  190. returntime: item.returndate || '',
  191. }));
  192. } catch (err) {
  193. } finally {
  194. this.loadingLending = false;
  195. uni.stopPullDownRefresh();
  196. setTimeout(() => {
  197. this.calcHeight('lending');
  198. }, 100);
  199. }
  200. },
  201. // 高度自适应(修复版)
  202. calcHeight(type) {
  203. const selector = `.list-item-${type}`;
  204. const query = uni.createSelectorQuery().in(this);
  205. query.selectAll(selector).boundingClientRect((res) => {
  206. let totalHeight = 200;
  207. if (res && res.length > 0) {
  208. totalHeight = res.reduce((sum, rect) => sum + rect.height, 0);
  209. totalHeight += res.length * 10 + 40;
  210. }
  211. this.swiperHeightData[type] = totalHeight;
  212. this.currentSwiperHeight = totalHeight;
  213. }).exec();
  214. },
  215. tabClick(index) {
  216. this.currentIndex = index;
  217. if (index === 0) {
  218. if (this.allList.length === 0) {
  219. this.getAllList(true);
  220. } else {
  221. this.currentSwiperHeight = this.swiperHeightData.all || 600;
  222. }
  223. } else {
  224. if (this.lendingList.length === 0) {
  225. this.getLendingList();
  226. } else {
  227. this.currentSwiperHeight = this.swiperHeightData.lending || 600;
  228. }
  229. }
  230. },
  231. onSwiperChange(e) {
  232. if (e.detail.source === 'touch') this.currentIndex = e.detail.current;
  233. },
  234. onSwiperEnd() {
  235. this.tabClick(this.currentIndex);
  236. },
  237. }
  238. };
  239. </script>
  240. <style lang="scss" scoped>
  241. .lending-container {
  242. background: #f5f5f5;
  243. min-height: 100vh;
  244. }
  245. .tab-sticky {
  246. position: sticky;
  247. top: 0;
  248. z-index: 99;
  249. background: #fff;
  250. }
  251. .swiper {
  252. width: 100%;
  253. transition: height 0.2s ease;
  254. }
  255. .list-wrapper {
  256. padding: 10px;
  257. box-sizing: border-box;
  258. }
  259. .empty {
  260. text-align: center;
  261. padding: 100px 0;
  262. color: #999;
  263. }
  264. </style>