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

245 lines
7.1 KiB

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