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

582 lines
13 KiB

2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
  1. <template>
  2. <view class="page">
  3. <!-- 自定义导航栏 -->
  4. <view class="custom-navbar">
  5. <view class="navbar-left">
  6. <view class="calendar-icon">
  7. <uv-icon name="calendar" color="#ffffff" size="44rpx"></uv-icon>
  8. </view>
  9. </view>
  10. <view class="navbar-center" @click="toSearch">
  11. <view class="search-box">
  12. <uv-icon name="search" color="#999999" size="32rpx"></uv-icon>
  13. <text class="search-placeholder">请输入搜索内容</text>
  14. </view>
  15. </view>
  16. <view class="navbar-right">
  17. <view class="function-btn">
  18. <uv-icon name="more-dot-fill" color="#ffffff" size="44rpx"></uv-icon>
  19. </view>
  20. <view class="function-btn">
  21. <uv-icon name="chat-fill" color="#ffffff" size="44rpx"></uv-icon>
  22. </view>
  23. </view>
  24. </view>
  25. <view class="content">
  26. <!-- 顶部横幅广告 -->
  27. <view class="banner">
  28. <uv-swiper
  29. :list="bannerList"
  30. keyName="image"
  31. :autoplay="true"
  32. :circular="true"
  33. :interval="3000"
  34. radius="10"
  35. :height="400"
  36. indicatorActiveColor="#ffffff"
  37. indicatorInactiveColor="rgba(255, 255, 255, 0.5)"
  38. @click="clickBanner"
  39. >
  40. <template v-slot:default="{item}">
  41. <view class="swiper-item">
  42. <image class="swiper-image" :src="item.image" mode="aspectFill"></image>
  43. <view class="swiper-content">
  44. <view class="swiper-title">{{item.title}}</view>
  45. <view class="swiper-desc">{{item.desc}}</view>
  46. </view>
  47. </view>
  48. </template>
  49. </uv-swiper>
  50. </view>
  51. <!-- 通知区域 -->
  52. <view class="notice" @click="viewNotice">
  53. <view class="notice-left">
  54. <view class="notice-tag">通讯</view>
  55. <view class="notice-icon">
  56. <image src="https://img95.699pic.com/xsj/0z/ld/62.jpg!/fw/700/watermark/url/L3hzai93YXRlcl9kZXRhaWwyLnBuZw/align/southeast" mode="aspectFill"></image>
  57. </view>
  58. </view>
  59. <view class="notice-center">
  60. <view class="notice-text" @click="viewNotice">
  61. 2025年2月平台福利活动截稿作品公示
  62. </view>
  63. </view>
  64. <view class="notice-right">
  65. <uv-icon name="arrow-right" color="#999" size="24rpx"></uv-icon>
  66. </view>
  67. </view>
  68. <!-- 最近更新 -->
  69. <view class="section">
  70. <view class="section-header">
  71. <text class="section-title">最近更新</text>
  72. </view>
  73. <scroll-view scroll-x style="width: 100%;">
  74. <view class="recommend-list">
  75. <view class="recommend-item"
  76. @click="navigateToDetail(item.id)"
  77. v-for="(item, index) in novelList" :key="index">
  78. <novel-item horizontal :key="index" :book="item" />
  79. </view>
  80. </view>
  81. </scroll-view>
  82. </view>
  83. </view>
  84. <!-- 精品推荐 -->
  85. <view class="section1">
  86. <view class="section-header">
  87. <text class="section-title">精品推荐</text>
  88. <text class="section-more" @click="$utils.navigateTo('/pages/index/category')">查看更多 ></text>
  89. </view>
  90. <view class="novel-list">
  91. <novel-item v-for="(item, index) in novelList"
  92. @click="navigateToDetail(item.id)"
  93. :key="index" :book="item" />
  94. </view>
  95. </view>
  96. <PrivacyAgreementPoup />
  97. <tabber select="home" />
  98. </view>
  99. </template>
  100. <script>
  101. import PrivacyAgreementPoup from '@/components/config/PrivacyAgreementPoup.vue'
  102. import tabber from '@/components/base/tabbar.vue'
  103. import novelItem from '@/components/novel/novelItem.vue'
  104. import {
  105. mapGetters
  106. } from 'vuex'
  107. export default {
  108. components: {
  109. tabber,
  110. PrivacyAgreementPoup,
  111. novelItem,
  112. },
  113. data() {
  114. return {
  115. // 轮播图数据
  116. bannerList: [
  117. {
  118. id: '1',
  119. image: 'https://img95.699pic.com/photo/50136/1544.jpg_wh300.jpg',
  120. title: '慢着,请别叫我昭昭烈帝',
  121. desc: '醒掌天下权,醉卧美人膝,五千年风华烟雨,是非成败转头空!'
  122. },
  123. {
  124. id: '2',
  125. image: 'https://img95.699pic.com/photo/40094/9516.jpg_wh300.jpg',
  126. title: '少年闻天语',
  127. desc: '修仙之路,逆天改命,少年携天命而来'
  128. },
  129. {
  130. id: '3',
  131. image: 'https://img95.699pic.com/photo/50055/5909.jpg_wh300.jpg',
  132. title: '我有一座妖怪城',
  133. desc: '妖怪横行,一座神秘古城,藏着千年秘密'
  134. }
  135. ],
  136. // 小说列表数据
  137. novelList: [
  138. {
  139. id: '1',
  140. title: '我是半妖',
  141. cover: 'https://tse4-mm.cn.bing.net/th/id/OIP-C.iUyxJ_fxLjjX3kEBjteXWwAAAA?rs=1&pid=ImgDetMain',
  142. author: '东方不败',
  143. desc: '都市玄幻小说,主角获得半妖化能力,通过吸收妖气不断变强...',
  144. tags: ['玄幻', '都市', '热血'],
  145. status: '连载中'
  146. },
  147. {
  148. id: '2',
  149. title: '兽王进化',
  150. cover: 'https://tse4-mm.cn.bing.net/th/id/OIP-C.iUyxJ_fxLjjX3kEBjteXWwAAAA?rs=1&pid=ImgDetMain',
  151. author: '天下霸唱',
  152. desc: '一场意外让主角获得兽王血脉,开始了进化之路...',
  153. tags: ['奇幻', '冒险'],
  154. status: '连载中'
  155. },
  156. {
  157. id: '3',
  158. title: '魔法少女纯爷们',
  159. cover: 'https://tse4-mm.cn.bing.net/th/id/OIP-C.iUyxJ_fxLjjX3kEBjteXWwAAAA?rs=1&pid=ImgDetMain',
  160. author: '南派三叔',
  161. desc: '一个普通男孩意外获得魔法少女的力量,开始了奇妙冒险...',
  162. tags: ['搞笑', '奇幻'],
  163. status: '已完结'
  164. },
  165. {
  166. id: '4',
  167. title: '我是一条小青龙',
  168. cover: 'https://tse4-mm.cn.bing.net/th/id/OIP-C.iUyxJ_fxLjjX3kEBjteXWwAAAA?rs=1&pid=ImgDetMain',
  169. author: '辰东',
  170. desc: '重生为一条小青龙,主角在修仙世界中成长的故事...',
  171. tags: ['仙侠', '修真'],
  172. status: '连载中'
  173. },
  174. {
  175. id: '5',
  176. title: '女帝归来',
  177. cover: 'https://tse4-mm.cn.bing.net/th/id/OIP-C.iUyxJ_fxLjjX3kEBjteXWwAAAA?rs=1&pid=ImgDetMain',
  178. author: '猫腻',
  179. desc: '曾经的女帝重生归来,开始了复仇之路...',
  180. tags: ['古代', '女强'],
  181. status: '连载中'
  182. }
  183. ]
  184. }
  185. },
  186. computed: {},
  187. methods: {
  188. // 跳转到搜索页面
  189. toSearch() {
  190. this.$utils.navigateTo('/pages/search/index')
  191. },
  192. // 点击轮播图
  193. clickBanner(index) {
  194. const banner = this.bannerList[index];
  195. console.log('点击了轮播图:', banner.title);
  196. // 跳转到小说详情页
  197. uni.showToast({
  198. title: '正在前往: ' + banner.title,
  199. icon: 'none'
  200. })
  201. setTimeout(() => {
  202. this.$utils.navigateTo(`/pages_order/book/bookDetail?id=${banner.id}`)
  203. }, 500)
  204. },
  205. // 查看公告详情
  206. viewNotice() {
  207. uni.navigateTo({
  208. url: '/pages_order/novel/Allannouncements'
  209. })
  210. },
  211. navigateToDetail(id) {
  212. // 跳转到小说详情页
  213. this.$utils.navigateTo(`/pages_order/novel/novelDetail?id=${id}`)
  214. },
  215. }
  216. }
  217. </script>
  218. <style scoped lang="scss">
  219. .page {
  220. background-color: #f5f5f5;
  221. // min-height: 100vh;
  222. /* 自定义导航栏样式 */
  223. .custom-navbar {
  224. display: flex;
  225. align-items: center;
  226. justify-content: space-between;
  227. padding: 0 20rpx 20rpx 20rpx;
  228. background-color: #001351; /* 深蓝色背景 */
  229. height: 160rpx;
  230. box-sizing: border-box;
  231. position: sticky;
  232. top: 0;
  233. z-index: 99;
  234. padding-top: calc(var(--status-bar-height) + 20rpx);
  235. .navbar-left {
  236. width: 80rpx;
  237. display: flex;
  238. justify-content: center;
  239. .calendar-icon {
  240. width: 50rpx;
  241. height: 50rpx;
  242. display: flex;
  243. align-items: center;
  244. justify-content: center;
  245. }
  246. }
  247. .navbar-center {
  248. flex: 1;
  249. margin: 0 20rpx;
  250. .search-box {
  251. display: flex;
  252. align-items: center;
  253. background-color: rgba(255, 255, 255, 0.95);
  254. border-radius: 40rpx;
  255. padding: 0 30rpx;
  256. height: 70rpx;
  257. box-sizing: border-box;
  258. .search-placeholder {
  259. color: #999;
  260. font-size: 28rpx;
  261. margin-left: 16rpx;
  262. }
  263. }
  264. }
  265. .navbar-right {
  266. display: flex;
  267. align-items: center;
  268. .function-btn {
  269. margin-left: 16rpx;
  270. width: 50rpx;
  271. height: 50rpx;
  272. display: flex;
  273. justify-content: center;
  274. align-items: center;
  275. }
  276. }
  277. }
  278. .content {
  279. padding-bottom: 5rpx;
  280. }
  281. .banner {
  282. padding: 0;
  283. margin: 20rpx;
  284. border-radius: 10rpx;
  285. overflow: hidden;
  286. box-shadow: 0 4rpx 12rpx rgba(0,0,0,0.1);
  287. transition: all 0.3s;
  288. &:active {
  289. transform: scale(0.98);
  290. }
  291. .swiper-item {
  292. position: relative;
  293. width: 100%;
  294. height: 100%;
  295. .swiper-image {
  296. width: 100%;
  297. height: 100%;
  298. border-radius: 10rpx;
  299. }
  300. .swiper-content {
  301. position: absolute;
  302. bottom: 0;
  303. left: 0;
  304. width: 100%;
  305. padding: 30rpx;
  306. background: linear-gradient(to top, rgba(0,0,0,0.8), rgba(0,0,0,0.3), transparent);
  307. border-bottom-left-radius: 10rpx;
  308. border-bottom-right-radius: 10rpx;
  309. .swiper-title {
  310. font-size: 36rpx;
  311. color: #fff;
  312. font-weight: bold;
  313. margin-bottom: 10rpx;
  314. text-shadow: 0 2rpx 4rpx rgba(0,0,0,0.5);
  315. }
  316. .swiper-desc {
  317. font-size: 28rpx;
  318. color: rgba(255,255,255,0.9);
  319. line-height: 1.4;
  320. text-shadow: 0 1rpx 3rpx rgba(0,0,0,0.5);
  321. }
  322. }
  323. }
  324. }
  325. .notice {
  326. display: flex;
  327. align-items: center;
  328. background-color: #fff;
  329. margin: 20rpx;
  330. margin-bottom: 0;
  331. padding: 20rpx;
  332. border-radius: 10rpx;
  333. box-shadow: 0 2rpx 10rpx rgba(0,0,0,0.05);
  334. transition: all 0.2s;
  335. &:active {
  336. background-color: #f9f9f9;
  337. }
  338. .notice-left {
  339. display: flex;
  340. align-items: center;
  341. margin-right: 20rpx;
  342. .notice-tag {
  343. font-size: 22rpx;
  344. color: #666;
  345. background-color: #f5f5f5;
  346. padding: 4rpx 12rpx;
  347. border-radius: 6rpx;
  348. margin-right: 10rpx;
  349. }
  350. .notice-icon {
  351. width: 60rpx;
  352. height: 60rpx;
  353. border-radius: 30rpx;
  354. overflow: hidden;
  355. box-shadow: 0 2rpx 6rpx rgba(0,0,0,0.1);
  356. image {
  357. width: 100%;
  358. height: 100%;
  359. }
  360. }
  361. }
  362. .notice-center {
  363. flex: 1;
  364. .notice-text {
  365. font-size: 28rpx;
  366. color: #333;
  367. overflow: hidden;
  368. white-space: nowrap;
  369. text-overflow: ellipsis;
  370. }
  371. }
  372. .notice-right {
  373. margin-left: 20rpx;
  374. opacity: 0.6;
  375. }
  376. }
  377. .section {
  378. background-color: #fff;
  379. margin: 30rpx 0 0 0;
  380. padding: 10rpx 30rpx;
  381. border-radius: 0;
  382. .section-header {
  383. display: flex;
  384. justify-content: space-between;
  385. align-items: center;
  386. margin-bottom: 20rpx;
  387. .section-title {
  388. font-size: 32rpx;
  389. font-weight: bold;
  390. color: #333;
  391. }
  392. .section-more {
  393. font-size: 24rpx;
  394. color: #999;
  395. }
  396. }
  397. .novel-list {
  398. .novel-item {
  399. display: flex;
  400. padding: 20rpx 0;
  401. border-bottom: 1px solid #eee;
  402. &:last-child {
  403. border-bottom: none;
  404. }
  405. .novel-cover {
  406. width: 160rpx;
  407. height: 200rpx;
  408. border-radius: 8rpx;
  409. margin-right: 20rpx;
  410. }
  411. .novel-info {
  412. flex: 1;
  413. display: flex;
  414. flex-direction: column;
  415. justify-content: space-between;
  416. .novel-title {
  417. font-size: 28rpx;
  418. font-weight: bold;
  419. color: #333;
  420. margin-bottom: 10rpx;
  421. }
  422. .novel-desc {
  423. font-size: 24rpx;
  424. color: #999;
  425. line-height: 1.5;
  426. display: -webkit-box;
  427. -webkit-box-orient: vertical;
  428. -webkit-line-clamp: 3;
  429. overflow: hidden;
  430. }
  431. }
  432. }
  433. }
  434. .recommend-list {
  435. display: flex;
  436. .recommend-item {
  437. width: fit-content;
  438. }
  439. }
  440. }
  441. .section1 {
  442. background-color: #fff;
  443. margin: 0rpx 0 0 0;
  444. padding: 20rpx 30rpx;
  445. border-radius: 0;
  446. .section-header {
  447. display: flex;
  448. justify-content: space-between;
  449. align-items: center;
  450. margin-bottom: 20rpx;
  451. .section-title {
  452. font-size: 32rpx;
  453. font-weight: bold;
  454. color: #333;
  455. }
  456. .section-more {
  457. font-size: 24rpx;
  458. color: #999;
  459. }
  460. }
  461. .novel-list {
  462. .novel-item {
  463. display: flex;
  464. padding: 20rpx 0;
  465. border-bottom: 1px solid #eee;
  466. &:last-child {
  467. border-bottom: none;
  468. }
  469. .novel-cover {
  470. width: 160rpx;
  471. height: 200rpx;
  472. border-radius: 8rpx;
  473. margin-right: 20rpx;
  474. }
  475. .novel-info {
  476. flex: 1;
  477. display: flex;
  478. flex-direction: column;
  479. justify-content: space-between;
  480. .novel-title {
  481. font-size: 28rpx;
  482. font-weight: bold;
  483. color: #333;
  484. margin-bottom: 10rpx;
  485. }
  486. .novel-desc {
  487. font-size: 24rpx;
  488. color: #999;
  489. line-height: 1.5;
  490. display: -webkit-box;
  491. -webkit-box-orient: vertical;
  492. -webkit-line-clamp: 3;
  493. overflow: hidden;
  494. }
  495. }
  496. }
  497. }
  498. .recommend-list {
  499. display: flex;
  500. flex-wrap: wrap;
  501. justify-content: space-between;
  502. .recommend-item {
  503. width: 30%;
  504. margin-bottom: 20rpx;
  505. .recommend-cover {
  506. width: 100%;
  507. height: 200rpx;
  508. border-radius: 8rpx;
  509. margin-bottom: 10rpx;
  510. }
  511. .recommend-title {
  512. font-size: 24rpx;
  513. color: #333;
  514. overflow: hidden;
  515. white-space: nowrap;
  516. text-overflow: ellipsis;
  517. }
  518. }
  519. }
  520. }
  521. }
  522. </style>