小说小程序前端代码仓库(小程序)
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.

233 lines
4.9 KiB

  1. <template>
  2. <view class="chapter-popup-container" :class="{'dark-mode': isDarkMode}">
  3. <uv-popup ref="popup" :round="30" :customStyle="popupStyle">
  4. <view class="catalog-popup-fullscreen theme-transition">
  5. <view class="catalog-header theme-transition">
  6. <view class="header-left" @click.stop="close">
  7. <uv-icon name="arrow-down" size="46" :color="isDarkMode ? '#ccc' : '#333'"/>
  8. </view>
  9. <view class="header-title theme-transition">目录</view>
  10. <view class="header-right theme-transition" @click.stop="orderAsc = !orderAsc">
  11. {{ orderAsc ? '倒序' : '正序' }}
  12. </view>
  13. </view>
  14. <scroll-view scroll-y class="catalog-list">
  15. <view v-for="(item, idx) in (orderAsc ? chapterList : [...chapterList].reverse())" :key="item.id"
  16. @click="selectChapter(item, idx)"
  17. :class="['catalog-item theme-transition', {active: idx == currentIndex}]">
  18. <view class="item-main">
  19. <text class="item-title theme-transition">{{ item.title }}</text>
  20. <text v-if="item.isPay == 'Y' && item.pay" class="paid-tag theme-transition">已付费</text>
  21. <text v-else-if="item.isPay == 'Y'" class="vip-tag theme-transition">付费</text>
  22. </view>
  23. </view>
  24. <uv-empty mode="list" v-if="chapterList.length == 0"></uv-empty>
  25. </scroll-view>
  26. </view>
  27. </uv-popup>
  28. </view>
  29. </template>
  30. <script>
  31. import themeMixin from '@/mixins/themeMode.js'
  32. export default {
  33. props : {
  34. 'bookId' : {
  35. default : 0
  36. },
  37. 'currentIndex' : {
  38. // default : 0
  39. },
  40. 'chapterList' : {
  41. default : []
  42. }
  43. },
  44. mixins: [themeMixin],
  45. data() {
  46. return {
  47. chapterCount: 2814,
  48. orderAsc : true,
  49. // chapterList: [],
  50. }
  51. },
  52. computed: {
  53. popupStyle() {
  54. return {
  55. height: '70vh',
  56. background: this.isDarkMode ? '#222' : '#fff'
  57. }
  58. }
  59. },
  60. methods: {
  61. open() {
  62. this.$refs.popup.open('bottom')
  63. // 获取章节
  64. // this.$fetch('getBookCatalogList', {
  65. // bookId : this.bookId,
  66. // pageNo : 1,
  67. // pageSize : 9999999,
  68. // reverse : this.orderAsc ? 1 : 0,
  69. // }).then(res => {
  70. // this.chapterList = res.records
  71. // })
  72. },
  73. close() {
  74. this.$refs.popup.close()
  75. },
  76. selectChapter(item, index) {
  77. this.close()
  78. this.$emit('selectChapter', {item, index})
  79. },
  80. }
  81. }
  82. </script>
  83. <style scoped lang="scss">
  84. .chapter-popup-container {
  85. .catalog-popup-fullscreen {
  86. position: relative;
  87. height: 100%;
  88. width: 100vw;
  89. background: #fff;
  90. display: flex;
  91. flex-direction: column;
  92. overflow: hidden;
  93. .catalog-header {
  94. display: flex;
  95. align-items: center;
  96. justify-content: space-between;
  97. padding: 0 24rpx;
  98. height: 96rpx;
  99. border-bottom: 1px solid #eee;
  100. position: sticky;
  101. top: 0;
  102. background: #fff;
  103. z-index: 2;
  104. }
  105. .header-left {
  106. width: 60rpx;
  107. display: flex;
  108. align-items: center;
  109. justify-content: flex-start;
  110. }
  111. .header-title {
  112. flex: 1;
  113. text-align: center;
  114. font-size: 32rpx;
  115. font-weight: bold;
  116. color: #222;
  117. }
  118. .header-right {
  119. color: #223a7a;
  120. font-size: 28rpx;
  121. font-weight: 500;
  122. min-width: 80rpx;
  123. text-align: right;
  124. }
  125. .catalog-list {
  126. height: calc(100% - 180rpx);
  127. overflow: auto;
  128. padding-bottom: 40rpx;
  129. }
  130. .catalog-item {
  131. padding: 0 32rpx;
  132. min-height: 80rpx;
  133. display: flex;
  134. flex-direction: column;
  135. justify-content: center;
  136. border-bottom: 1px solid #f5f5f5;
  137. background: #fff;
  138. color: #222;
  139. font-size: 30rpx;
  140. position: relative;
  141. }
  142. .catalog-item.active {
  143. color: #ff5a5f;
  144. background: #fff7f7;
  145. }
  146. .item-main {
  147. display: flex;
  148. align-items: center;
  149. gap: 16rpx;
  150. }
  151. .item-title {
  152. font-size: 30rpx;
  153. }
  154. .vip-tag {
  155. background: #ffe1b2;
  156. color: #ff9900;
  157. border-radius: 20rpx;
  158. font-size: 24rpx;
  159. padding: 2rpx 18rpx;
  160. margin-left: 16rpx;
  161. }
  162. .paid-tag {
  163. background: #e8f5e8;
  164. color: #4caf50;
  165. border-radius: 20rpx;
  166. font-size: 24rpx;
  167. padding: 2rpx 18rpx;
  168. margin-left: 16rpx;
  169. }
  170. }
  171. }
  172. /* 暗色主题样式 */
  173. .chapter-popup-container.dark-mode {
  174. .catalog-popup-fullscreen {
  175. background: $dark-bg-color-secondary;
  176. .catalog-header {
  177. background: $dark-bg-color-secondary;
  178. border-bottom: 1px solid $dark-border-color;
  179. .header-title {
  180. color: $dark-text-color-primary;
  181. }
  182. .header-right {
  183. color: $dark-accent-color;
  184. }
  185. }
  186. .catalog-list {
  187. .catalog-item {
  188. background: $dark-bg-color-secondary;
  189. color: $dark-text-color-secondary;
  190. border-bottom: 1px solid $dark-border-color;
  191. &.active {
  192. color: #ff5a5f;
  193. background: rgba(255, 90, 95, 0.1);
  194. }
  195. .item-title {
  196. color: $dark-text-color-secondary;
  197. }
  198. .vip-tag {
  199. background: rgba(255, 153, 0, 0.2);
  200. color: #ff9900;
  201. }
  202. .paid-tag {
  203. background: rgba(76, 175, 80, 0.2);
  204. color: #4caf50;
  205. }
  206. }
  207. }
  208. }
  209. }
  210. </style>