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

148 lines
3.3 KiB

2 months ago
1 month ago
1 month ago
1 month 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
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. <template>
  2. <view class="item-container" @click="$emit('click')">
  3. <view class="item-box">
  4. <view class="item-box-left">
  5. <image
  6. class="img-item"
  7. :src="actualCover"
  8. mode="scaleToFill"
  9. @error="onImgError"
  10. ></image>
  11. </view>
  12. <view class="item-box-right">
  13. <view class="item-title line-clamp-2">{{ data.title || data.name || '暂无标题' }}</view>
  14. <text class="item-author">{{ data.author || '佚名' }}</text>
  15. <text class="item-publish">{{ data.publisher || '暂无出版社数据' }}</text>
  16. </view>
  17. </view>
  18. </view>
  19. </template>
  20. <script>
  21. export default {
  22. name: "book-list-item",
  23. props: {
  24. data: {
  25. type: Object,
  26. required: true
  27. }
  28. },
  29. computed: {
  30. actualCover() {
  31. // 优先使用 cover
  32. if (this.data.cover) {
  33. return this.data.cover;
  34. }
  35. // 其次使用 base64Cover(兼容推荐页面)
  36. if (this.data.base64Cover) {
  37. return this.data.base64Cover;
  38. }
  39. // 最后使用默认图片
  40. return '/static/images/default-book.png';
  41. }
  42. },
  43. methods: {
  44. /**
  45. * 检查封面链接是否有效
  46. * @param {string} coverlink - 封面链接
  47. * @returns {boolean} - 是否有效
  48. */
  49. isValidCoverLink(coverlink) {
  50. if (!coverlink || typeof coverlink !== 'string') {
  51. return false;
  52. }
  53. // 支持 base64 图片格式
  54. if (coverlink.indexOf('data:image/') === 0) {
  55. return true;
  56. }
  57. // 检查是否包含 http
  58. if (coverlink.indexOf('http') === -1) {
  59. return false;
  60. }
  61. // 已知无法访问的域名列表
  62. const blockedDomains = [
  63. 'doubanio.com',
  64. 'douban.com'
  65. ];
  66. // 检查是否包含被阻止的域名
  67. for (const domain of blockedDomains) {
  68. if (coverlink.includes(domain)) {
  69. return false;
  70. }
  71. }
  72. return true;
  73. },
  74. /**
  75. * 图片加载失败处理
  76. */
  77. onImgError(e) {
  78. e.target.src = "/static/images/default-book.png";
  79. }
  80. }
  81. };
  82. </script>
  83. <style lang="scss" scoped>
  84. .item-container {
  85. padding-bottom: 10px;
  86. .item-box {
  87. display: flex;
  88. justify-content: flex-start;
  89. align-items: flex-start;
  90. padding: 10px;
  91. background-color: #fff;
  92. border-radius: 6px;
  93. border-bottom: 1px solid #f4f4f4;
  94. .item-box-left {
  95. margin-right: 8px;
  96. .img-item{
  97. width: 64px;
  98. height: 90px;
  99. margin: 0 12px 0 0;
  100. border-radius: 5px;
  101. }
  102. }
  103. .item-box-right {
  104. display: flex;
  105. flex-direction: column;
  106. justify-content: flex-start;
  107. flex: 1;
  108. .item-title {
  109. font-size: 15px;
  110. font-weight: bold;
  111. color: #000;
  112. padding-bottom: 10px;
  113. }
  114. .item-author,
  115. .item-publish {
  116. font-size: 12px;
  117. color: #888;
  118. padding-bottom: 10px;
  119. }
  120. .hot-text {
  121. font-size: 12px;
  122. color: #ff4444;
  123. }
  124. .item-desc {
  125. padding-top: 5px;
  126. font-size: 13px;
  127. color: #666;
  128. line-height: 1.4;
  129. }
  130. .item-bottom-box {
  131. margin-top: 8px;
  132. display: flex;
  133. justify-content: space-between;
  134. align-items: center;
  135. }
  136. }
  137. }
  138. }
  139. </style>