四零语境前端代码仓库
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.

383 lines
8.8 KiB

1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
  1. <template>
  2. <view class="search-container">
  3. <!-- 状态栏安全区域 -->
  4. <uv-status-bar></uv-status-bar>
  5. <!-- 顶部搜索栏 -->
  6. <view class="search-header">
  7. <uv-search
  8. v-model="searchKeyword"
  9. placeholder="请输入内容"
  10. :show-action="true"
  11. action-text="搜索"
  12. :action-style="{
  13. color: '#fff',
  14. backgroundColor: '#FFA500',
  15. borderRadius: '198rpx',
  16. width: '100rpx',
  17. height: '64rpx',
  18. textAlign: 'center',
  19. fontSize: '26rpx',
  20. lineHeight: '64rpx',
  21. }"
  22. :customStyle="{
  23. width: '500rpx',
  24. }"
  25. @search="handleSearch"
  26. @custom="handleSearch"
  27. @clear="handleSearch"
  28. ></uv-search>
  29. </view>
  30. <!-- 分类标签栏 -->
  31. <view class="category-tabs">
  32. <scroll-view scroll-x class="tab-scroll">
  33. <view class="tab-list">
  34. <view
  35. v-for="(tab, index) in categoryTabs"
  36. :key="index"
  37. class="tab-item"
  38. :class="{ active: currentTab === index }"
  39. @click="switchTab(index)"
  40. >
  41. {{ tab.title }}
  42. </view>
  43. </view>
  44. </scroll-view>
  45. </view>
  46. <!-- 搜索结果列表 -->
  47. <view class="search-results">
  48. <view
  49. v-for="(book, index) in list"
  50. :key="index"
  51. class="book-item"
  52. @click="goToDetail(book)"
  53. >
  54. <view class="book-cover">
  55. <image :src="book.booksImg" mode="aspectFill"></image>
  56. </view>
  57. <view class="book-info">
  58. <view class="book-title">{{ book.booksName }}</view>
  59. <view class="book-author">{{ book.booksAuthor }}</view>
  60. <view class="book-meta">
  61. <view class="book-duration">
  62. <image src="/static/播放图标.png" mode="aspectFill" class="book-icon"></image>
  63. <text>{{ book.duration }}</text>
  64. </view>
  65. <view class="book-membership" :class="classMap[book.vipInfo.title]">
  66. {{ book.vipInfo.title }}
  67. </view>
  68. </view>
  69. </view>
  70. </view>
  71. <uv-loading-icon text="加载中" textSize="30rpx" v-if="isLoading" ></uv-loading-icon>
  72. <uv-empty v-else-if="list.length === 0" ></uv-empty>
  73. </view>
  74. </view>
  75. </template>
  76. <script>
  77. import MixinList from '@/mixins/list.js'
  78. export default {
  79. mixins: [MixinList],
  80. data() {
  81. return {
  82. mixinListApi: 'book.list',
  83. // 自定义onShow
  84. mixinListConfig: {
  85. customOnShow: true,
  86. },
  87. searchKeyword: '',
  88. label : '',
  89. currentTab: 0,
  90. categoryTabs: [ ],
  91. // 类型引射表
  92. classMap: {
  93. '盛放会员': 'book-membership-premium',
  94. vip: 'book-membership-vip',
  95. basic: 'book-membership-basic',
  96. },
  97. bookList: [
  98. {
  99. cover: '/static/主页图标.png',
  100. title: '短文全脑孩子:12项革命性策略...',
  101. author: 'Daniel J. Siegel / Tina Payne Bryson / Del...',
  102. duration: '03:24',
  103. membership: '蕾朵会员',
  104. membershipType: 'premium'
  105. },
  106. {
  107. cover: '/static/默认图片.png',
  108. title: '精讲短文',
  109. author: 'Daniel J. Siegel / Tina Payne Bryson / Del...',
  110. duration: '03:24',
  111. membership: '盛放会员',
  112. membershipType: 'vip'
  113. },
  114. {
  115. cover: '/static/默认图片.png',
  116. title: '精讲短文',
  117. author: 'Daniel J. Siegel / Tina Payne Bryson / Del...',
  118. duration: '03:24',
  119. membership: '蕾朵会员',
  120. membershipType: 'premium'
  121. },
  122. {
  123. cover: '/static/默认图片.png',
  124. title: '精讲短文',
  125. author: 'Daniel J. Siegel / Tina Payne Bryson / Del...',
  126. duration: '03:24',
  127. membership: '盛放会员',
  128. membershipType: 'vip'
  129. },
  130. {
  131. cover: '/static/默认图片.png',
  132. title: '精讲短文',
  133. author: 'Daniel J. Siegel / Tina Payne Bryson / Del...',
  134. duration: '03:24',
  135. membership: '萌芽会员',
  136. membershipType: 'basic'
  137. },
  138. {
  139. cover: '/static/默认图片.png',
  140. title: '精讲短文',
  141. author: 'Daniel J. Siegel / Tina Payne Bryson / Del...',
  142. duration: '03:24',
  143. membership: '萌芽会员',
  144. membershipType: 'basic'
  145. },
  146. {
  147. cover: '/static/默认图片.png',
  148. title: '精讲短文',
  149. author: 'Daniel J. Siegel / Tina Payne Bryson / Del...',
  150. duration: '03:24',
  151. membership: '萌芽会员',
  152. membershipType: 'basic'
  153. },
  154. {
  155. cover: '/static/默认图片.png',
  156. title: '精讲短文',
  157. author: 'Daniel J. Siegel / Tina Payne Bryson / Del...',
  158. duration: '03:24',
  159. membership: '萌芽会员',
  160. membershipType: 'basic'
  161. },
  162. ]
  163. }
  164. },
  165. methods: {
  166. mixinSetParams(){
  167. const params = {
  168. category: this.categoryTabs[this.currentTab].id,
  169. }
  170. if(this.label){
  171. params.label = this.label
  172. }
  173. if(this.searchKeyword){
  174. params.title = this.searchKeyword
  175. }
  176. return params
  177. },
  178. handleSearch() {
  179. console.log('搜索:', this.searchKeyword)
  180. this.list = []
  181. this.initPage()
  182. this.getList(true)
  183. // 这里添加搜索逻辑
  184. },
  185. switchTab(index) {
  186. this.currentTab = index
  187. console.log('切换分类:', this.categoryTabs[index])
  188. this.list = []
  189. this.initPage()
  190. this.getList(true)
  191. // 这里添加分类切换逻辑
  192. },
  193. goToDetail(book) {
  194. uni.navigateTo({
  195. url: '/subPages/home/directory?id=' + book.id
  196. })
  197. },
  198. // 获取书籍分类
  199. async getCategory() {
  200. const categoryRes = await this.$api.book.category()
  201. if (categoryRes.code === 200){
  202. this.categoryTabs = categoryRes.result.map(item => ({
  203. title:item.title,
  204. id: item.id
  205. }))
  206. }
  207. },
  208. },
  209. onLoad(options) {
  210. if (options.label){
  211. this.label = options.label
  212. }
  213. },
  214. async onShow() {
  215. await this.getCategory()
  216. this.getList()
  217. }
  218. }
  219. </script>
  220. <style scoped lang="scss">
  221. .search-container {
  222. background: #fff;
  223. min-height: 100vh;
  224. }
  225. .search-header {
  226. padding: 10rpx 32rpx 20rpx;
  227. background: #fff;
  228. }
  229. .category-tabs {
  230. background: #fff;
  231. // border-bottom: 1rpx solid #f0f0f0;
  232. .tab-scroll {
  233. white-space: nowrap;
  234. }
  235. .tab-list {
  236. display: flex;
  237. padding: 0 32rpx;
  238. }
  239. .tab-item {
  240. flex-shrink: 0;
  241. padding: 24rpx 22rpx;
  242. font-size: 32rpx;
  243. color: $secondary-text-color;
  244. position: relative;
  245. &.active {
  246. color: $primary-text-color;
  247. font-weight: 600;
  248. &::after {
  249. content: '';
  250. position: absolute;
  251. bottom: 0;
  252. left: 50%;
  253. transform: translateX(-50%);
  254. width: 22rpx;
  255. height: 4rpx;
  256. background: $primary-text-color;
  257. border-radius: 2rpx;
  258. }
  259. }
  260. }
  261. }
  262. .search-results {
  263. padding: 32rpx;
  264. display: flex;
  265. flex-direction: column;
  266. gap: 32rpx;
  267. }
  268. .book-item {
  269. display: flex;
  270. align-items: center;
  271. // border-bottom: 1rpx solid #f5f5f5;
  272. background: #F8F8F8;
  273. // width: 686rpx;
  274. height: 212rpx;
  275. gap: 16rpx;
  276. border-radius: 16rpx;
  277. padding: 0rpx 16rpx;
  278. &:last-child {
  279. border-bottom: none;
  280. }
  281. .book-cover {
  282. width: 136rpx;
  283. height: 180rpx;
  284. border-radius: 16rpx;
  285. overflow: hidden;
  286. margin-right: 16rpx;
  287. image {
  288. width: 100%;
  289. height: 100%;
  290. }
  291. }
  292. .book-info {
  293. flex: 1;
  294. display: flex;
  295. flex-direction: column;
  296. justify-content: space-between;
  297. }
  298. .book-title {
  299. font-size: 32rpx;
  300. font-weight: 600;
  301. color: $primary-text-color;
  302. line-height: 48rpx;
  303. letter-spacing: 0;
  304. margin-bottom: 12rpx;
  305. overflow: hidden;
  306. text-overflow: ellipsis;
  307. }
  308. .book-author {
  309. font-size: 24rpx;
  310. color: $secondary-text-color;
  311. margin-bottom: 16rpx;
  312. overflow: hidden;
  313. text-overflow: ellipsis;
  314. white-space: nowrap;
  315. }
  316. .book-meta {
  317. display: flex;
  318. align-items: center;
  319. justify-content: space-between;
  320. }
  321. .book-duration {
  322. display: flex;
  323. align-items: center;
  324. font-size: 22rpx;
  325. color: #999;
  326. .book-icon{
  327. width: 18rpx;
  328. height: 18rpx;
  329. }
  330. text {
  331. margin-left: 8rpx;
  332. }
  333. }
  334. .book-membership {
  335. padding: 8rpx 16rpx;
  336. border-radius: 8rpx;
  337. font-size: 24rpx;
  338. color: #211508;
  339. }
  340. }
  341. .book-membership-premium {
  342. background: #E9F1FF;
  343. border: 2rpx solid #C4DAFF
  344. }
  345. .book-membership-vip {
  346. background: #FFF4E9;
  347. border: 2rpx solid #FFE2C4
  348. }
  349. .book-membership-basic {
  350. background: #FFE9E9;
  351. border: 2rpx solid #FFDBC4
  352. }
  353. </style>