ScanBookList.vue 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. <template>
  2. <view class="wrapper">
  3. <scroll-view
  4. scroll-y
  5. @scroll="onScroll"
  6. :refresher-enabled="isAtTop"
  7. :refresher-triggered="isRefreshing"
  8. @refresherrefresh="onRefresh"
  9. @scrolltoupper="scrollToUpper"
  10. upper-threshold="5"
  11. class="book-scroll"
  12. >
  13. <view class="scan-book-list">
  14. <!-- 顶部提示 -->
  15. <view class="tip-text">
  16. 套装书(相同ISBN相同的系列书籍)只需扫描其中一本,扫描价即套装价;需用户将整个套装全部寄出,缺册不予回收。
  17. </view>
  18. <!-- 书籍列表 -->
  19. <view class="book-list">
  20. <BookItem
  21. v-for="book in bookList"
  22. :key="book.isbn"
  23. :book="book"
  24. @delete="handleDeleteBook"
  25. @quantity-change="handleQuantityChange"
  26. @upsell="handleUpsell"
  27. />
  28. </view>
  29. <view class="link-wrap flex-a">
  30. <text class="link-btn flex-1" @click="goToScannedBooks"
  31. >扫过的书 ></text
  32. >
  33. <text class="link-btn flex-1" @click="goToRules"
  34. >卖书规则 ></text
  35. >
  36. </view>
  37. </view>
  38. </scroll-view>
  39. </view>
  40. </template>
  41. <script>
  42. import BookItem from "./BookItem.vue";
  43. export default {
  44. components: {
  45. BookItem,
  46. },
  47. props: {
  48. bookList: {
  49. type: Array,
  50. default: () => [],
  51. },
  52. },
  53. data() {
  54. return {
  55. books: [],
  56. isRefreshing: false,
  57. isAtTop: true, // 是否在顶部,默认为true
  58. scrollTop: 0,
  59. };
  60. },
  61. watch: {
  62. bookList: {
  63. handler(newVal) {
  64. this.books = newVal;
  65. },
  66. deep: true,
  67. immediate: true,
  68. },
  69. },
  70. methods: {
  71. // 滚动事件
  72. onScroll(e) {
  73. // 记录滚动位置
  74. this.scrollTop = e.detail.scrollTop;
  75. // 只有在最顶部时才能触发下拉刷新
  76. this.isAtTop = this.scrollTop < 5;
  77. },
  78. // 滚动到顶部事件
  79. scrollToUpper() {
  80. this.isAtTop = true;
  81. },
  82. // 下拉刷新
  83. onRefresh() {
  84. console.log("onRefresh");
  85. this.isRefreshing = true;
  86. // 触发父组件的刷新事件
  87. this.$emit("refresh");
  88. // 模拟刷新完成
  89. setTimeout(() => {
  90. this.isRefreshing = false;
  91. }, 600);
  92. },
  93. // 加价
  94. handleUpsell(book) {
  95. this.$emit("upsell", book);
  96. },
  97. handleDeleteBook(book) {
  98. this.$emit("deleted", book);
  99. },
  100. handleQuantityChange(data) {
  101. const book = this.books.find((book) => book.isbn === data.isbn);
  102. if (book) {
  103. book.num = data.num;
  104. }
  105. this.$emit("updateBooks", this.books, book);
  106. },
  107. onNext() {
  108. this.$emit("next");
  109. },
  110. goToScannedBooks() {
  111. uni.navigateTo({
  112. url: "/pages-home/pages/scaned-book",
  113. });
  114. },
  115. goToRules() {
  116. uni.navigateTo({
  117. url: "/pages-mine/pages/rules-for-sellbooks",
  118. });
  119. },
  120. },
  121. };
  122. </script>
  123. <style lang="scss">
  124. .wrapper {
  125. height: 100%;
  126. width: 100%;
  127. position: relative;
  128. }
  129. .book-scroll {
  130. height: calc(100vh - 240px);
  131. }
  132. .scan-book-list {
  133. padding: 20rpx;
  134. display: flex;
  135. flex-direction: column;
  136. .tip-text {
  137. font-family: Source Han Sans CN;
  138. font-weight: 400;
  139. font-size: 24rpx;
  140. color: #ff8a4b;
  141. line-height: 36rpx;
  142. }
  143. .link-wrap {
  144. gap: 20rpx;
  145. box-sizing: border-box;
  146. margin-top: 20rpx;
  147. .link-btn {
  148. height: 80rpx;
  149. background: #ffffff;
  150. border-radius: 10rpx;
  151. display: flex;
  152. align-items: center;
  153. justify-content: center;
  154. font-family: PingFang SC;
  155. font-weight: 500;
  156. font-size: 32rpx;
  157. color: #666666;
  158. }
  159. }
  160. }
  161. </style>