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

184 lines
5.5 KiB

1 month ago
  1. /**
  2. * 获取已加载的 bookrecno 缓存
  3. * @returns {Set} - 已加载的 bookrecno 集合
  4. */
  5. function getLoadedBookrecnos() {
  6. const loadedList = wx.getStorageSync('loadedBookrecnos') || [];
  7. return new Set(loadedList);
  8. }
  9. /**
  10. * 标记 bookrecno 已加载
  11. * @param {Array} bookrecnoList - 已加载的 bookrecno 列表
  12. */
  13. function markBookrecnoLoaded(bookrecnoList) {
  14. const loadedSet = getLoadedBookrecnos();
  15. bookrecnoList.forEach(bookrecno => loadedSet.add(bookrecno));
  16. wx.setStorageSync('loadedBookrecnos', Array.from(loadedSet));
  17. }
  18. /**
  19. * 通过远程接口获取封面基于 ISBN
  20. * @param {Array} isbnList - ISBN 列表
  21. * @returns {Promise<Object>} - 封面数据映射 { isbn: coverUrl }
  22. */
  23. export async function fetchCoversByISBN(isbnList) {
  24. if (!isbnList || isbnList.length === 0) {
  25. return {};
  26. }
  27. // 移除 ISBN 中的连字符
  28. const cleanIsbns = isbnList.map(isbn => isbn.replace(/-/g, ''));
  29. const isbns = cleanIsbns.join(',');
  30. const url = `https://book-resource.dataesb.com/websearch/metares?glc=EGD0755036&cmdACT=getImages&type=0&isbns=${isbns}`;
  31. return new Promise((resolve) => {
  32. wx.request({
  33. url: url,
  34. method: 'GET',
  35. success: (res) => {
  36. const result = {};
  37. let list = [];
  38. try {
  39. // 获取响应数据
  40. let responseData = res.data;
  41. // 如果是字符串,尝试解析为 JSON
  42. if (typeof responseData === 'string') {
  43. // 移除可能的 JSONP 包装括号 ({"result":...})
  44. const trimmed = responseData.trim();
  45. if (trimmed.startsWith('(') && trimmed.endsWith(')')) {
  46. responseData = trimmed.slice(1, -1);
  47. }
  48. responseData = JSON.parse(responseData);
  49. }
  50. // 获取 result 数组
  51. if (responseData && responseData.result && Array.isArray(responseData.result)) {
  52. list = responseData.result;
  53. }
  54. } catch (error) {
  55. console.error('解析封面数据失败:', error);
  56. list = [];
  57. }
  58. list.forEach(item => {
  59. if (item.isbn && item.coverlink && item.coverlink.indexOf('http') !== -1) {
  60. // 存储时移除连字符,便于匹配
  61. result[item.isbn.replace(/-/g, '')] = item.coverlink;
  62. }
  63. });
  64. resolve(result);
  65. },
  66. fail: () => {
  67. resolve({});
  68. }
  69. });
  70. });
  71. }
  72. /**
  73. * 获取服务器存在的 bookrecno 列表
  74. * @param {Array} bookrecnoList - bookrecno 列表
  75. * @returns {Promise<Object>} - 存在的 bookrecno 映射 { bookrecno: coverUrl }
  76. */
  77. export async function fetchCoversByBookrecno(bookrecnoList) {
  78. if (!bookrecnoList || bookrecnoList.length === 0) {
  79. return {};
  80. }
  81. const bookrecnos = bookrecnoList.join(',');
  82. return new Promise((resolve) => {
  83. wx.request({
  84. url: `http://218.200.95.251:8081/opac/getExistsBookrecnoList/${bookrecnos}`,
  85. method: 'POST',
  86. success: (res) => {
  87. const result = {};
  88. console.log('bookrecnoList',res)
  89. const existsList = res.data || [];
  90. console.log('existsList',existsList)
  91. existsList.forEach(bookrecno => {
  92. const timestamp = new Date().getTime();
  93. result[bookrecno] = `http://218.200.95.251:8081/opac/bscover/${bookrecno}?timestamp=${timestamp}`;
  94. });
  95. // 标记已加载
  96. markBookrecnoLoaded(existsList);
  97. resolve(result);
  98. },
  99. fail: () => {
  100. resolve({});
  101. }
  102. });
  103. });
  104. }
  105. /**
  106. * 加载图书封面核心方法
  107. * @param {Array} bookList - 图书数据列表
  108. * @param {Function} callback - 回调函数接收 (index, coverUrl) 参数
  109. * @returns {Promise<void>}
  110. */
  111. export async function loadBookCovers(bookList, callback) {
  112. if (!bookList || bookList.length === 0 || typeof callback !== 'function') {
  113. return;
  114. }
  115. try {
  116. // 分离需要查询的 ISBN 和 bookrecno
  117. const loadedSet = getLoadedBookrecnos();
  118. const isbnMap = new Map(); // index -> isbn
  119. const bookrecnoMap = new Map(); // index -> bookrecno(未加载过的)
  120. bookList.forEach((book, index) => {
  121. if (book.isbn) {
  122. isbnMap.set(index, book.isbn.replace(/-/g, ''));
  123. }
  124. if (book.bookrecno && !loadedSet.has(book.bookrecno)) {
  125. bookrecnoMap.set(index, book.bookrecno);
  126. }
  127. });
  128. // 并行请求 ISBN 和 bookrecno 的封面
  129. const [isbnCovers, bookrecnoCovers] = await Promise.all([
  130. fetchCoversByISBN(Array.from(isbnMap.values())),
  131. fetchCoversByBookrecno(Array.from(bookrecnoMap.values()))
  132. ]);
  133. // 更新封面
  134. bookList.forEach((book, index) => {
  135. let coverUrl = null;
  136. // 优先使用 ISBN 获取的封面
  137. const isbn = book.isbn ? book.isbn.replace(/-/g, '') : null;
  138. if (isbn && isbnCovers[isbn]) {
  139. coverUrl = isbnCovers[isbn];
  140. }
  141. // 如果 ISBN 没获取到,尝试 bookrecno
  142. else if (book.bookrecno && bookrecnoCovers[book.bookrecno]) {
  143. coverUrl = bookrecnoCovers[book.bookrecno];
  144. }
  145. if (coverUrl) {
  146. callback(index, coverUrl);
  147. }
  148. });
  149. } catch (error) {
  150. console.error('加载图书封面失败:', error);
  151. }
  152. }
  153. /**
  154. * 清除封面加载缓存
  155. */
  156. export function clearCoverCache() {
  157. wx.removeStorageSync('loadedBookrecnos');
  158. }
  159. export default {
  160. loadBookCovers,
  161. clearCoverCache,
  162. fetchCoversByISBN,
  163. fetchCoversByBookrecno
  164. };