爱简收旧衣按件回收前端代码仓库
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.

950 lines
22 KiB

2 months ago
1 month ago
2 months ago
1 month ago
2 months ago
1 month ago
2 months ago
1 month ago
2 months ago
1 month ago
2 months ago
1 month ago
2 months ago
1 month ago
2 months ago
1 month ago
2 months ago
1 month ago
2 months ago
1 month ago
2 months ago
1 month ago
2 months ago
1 month ago
2 months ago
1 month ago
2 months ago
1 month ago
2 months ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
2 months ago
1 month ago
  1. <template>
  2. <view class="container safe-area">
  3. <!-- 顶部banner -->
  4. <view class="banner">
  5. <swiper :indicator-dots="false" :autoplay="true" :interval="3000" :duration="500" circular
  6. style="width: 100%; height: 320rpx;">
  7. <swiper-item v-for="(item, index) in bannerList" :key="item.id || index">
  8. <video v-if="item.type == 1" :src="item.voUrl" autoplay muted loop :controls="false"
  9. :show-play-btn="false" :show-center-play-btn="false" object-fit="cover"
  10. style="width: 100%; height: 100%;"></video>
  11. <image v-else :src="item.image" mode="aspectFill" style="width: 100%; height: 100%;" />
  12. </swiper-item>
  13. </swiper>
  14. </view>
  15. <view class="content">
  16. <!-- 回收流程 -->
  17. <view class="process-section">
  18. <view class="section-header">
  19. <text class="title">回收流程</text>
  20. </view>
  21. <view class="process-grid">
  22. <view class="process-item" v-for="(item, index) in processes" :key="index">
  23. <image :src="item.icon" mode="aspectFit" class="process-icon"></image>
  24. <text class="process-text">{{item.text}}</text>
  25. <!-- <text class="process-number">{{index + 1}}</text> -->
  26. </view>
  27. </view>
  28. <button class="submit-btn" hover-class="submit-btn-hover" @click="getPickupto">
  29. <text class="submit-btn-hearder">快速免费上门</text>
  30. <text class="btn-desc">点击开始预约</text>
  31. <image src="/static/home/1745478917401 3.png" mode="aspectFit" class="arrow-icon"></image>
  32. <image src="/static/home/1745478917401 4.png" mode="aspectFit" class="arrow-icon-left"></image>
  33. </button>
  34. </view>
  35. <uv-divider :dashed="true"></uv-divider>
  36. <!-- 服务城市 -->
  37. <view class="city-section" @click="goCity">
  38. <view class="city-header">
  39. <text>已开通包邮服务城市有哪些</text>
  40. <uni-icons type="right" size="16" color="#999"></uni-icons>
  41. </view>
  42. <text class="city-list">{{ cityListStr }}</text>
  43. </view>
  44. <view class="Xiadan-section">
  45. <image :src="addressCion" alt="" class="process-icon" />
  46. <text class="left-text">不会下单联系客服了解回收流程</text>
  47. <view class="right" @click="goService">
  48. <image src="/static/home/联系客服.png" mode=""></image>
  49. <text>联系客服</text>
  50. </view>
  51. </view>
  52. <!-- 关于我们 -->
  53. <view class="about-section">
  54. <view class="section-header">
  55. <text class="title">关于我们</text>
  56. </view>
  57. <view class="about-footer" @click="goAbout">
  58. <view class="about-header">
  59. <image :src="sbkCion" mode="aspectFit" class="logo"></image>
  60. <!-- <text class="about-title">关于我们</text> -->
  61. </view>
  62. <view class="about-content">
  63. <text>免费寄送件验秒到账助环保</text>
  64. <text class="about-desc">让二手交易更轻松让地球多一份绿意</text>
  65. </view>
  66. <uni-icons type="right" size="16" color="#999"></uni-icons>
  67. </view>
  68. </view>
  69. <!-- 价格概览 -->
  70. <view class="price-section">
  71. <view class="section-header" @click="getPickupto">
  72. <text class="title">价格概览</text>
  73. <view class="more">
  74. <uni-icons type="right" size="14" color="#999"></uni-icons>
  75. <text>查看更多</text>
  76. </view>
  77. </view>
  78. <view class="price-grid">
  79. <view class="price-item" v-for="(item, index) in priceList" :key="item.id || index"
  80. @tap="goToRecycleCategory(item.id)">
  81. <image v-if="item.icon" :src="item.icon" mode="aspectFit" class="item-icon"></image>
  82. <view v-else class="item-icon placeholder"></view>
  83. <text class="item-name">{{item.name}}</text>
  84. <text class="item-price">¥ {{item.price}}
  85. <text class="item-price-right">/{{item.unit}}</text>
  86. </text>
  87. </view>
  88. </view>
  89. </view>
  90. <!-- 最近回收 -->
  91. <view class="recent-section">
  92. <view class="section-header">
  93. <text class="title">最近回收</text>
  94. </view>
  95. <view class="records-grid">
  96. <view class="record-item" v-for="(item, index) in records" :key="index"
  97. @tap="goToInspectionReport(item)">
  98. <image :src="item.image" mode="aspectFill"></image>
  99. <text class="location">{{item.name}}</text>
  100. <text class="user-id">****{{item.phone ? item.phone.slice(-4) : ''}}</text>
  101. <text class="user-id-f">成功完成衣物回收已到账</text>
  102. <text class="amount">+ ¥{{item.price}}</text>
  103. </view>
  104. </view>
  105. </view>
  106. <!-- 回收去向 -->
  107. <view class="destination-section">
  108. <view class="section-header">
  109. <text class="title">回收去向</text>
  110. </view>
  111. <view class="destination-grid">
  112. <view class="destination-item "
  113. @click="$utils.navigateTo('/pages/mine/recyclingDestination?id=' + item.id)"
  114. :class="`destination-item${index + 1}`" v-for="(item, index) in destinations" :key="index">
  115. <image :src="item.icon" mode="aspectFit" class="dest-icon"></image>
  116. <view class="dest-info">
  117. <text class="dest-title">{{item.title}}</text>
  118. <text class="dest-desc">{{item.description}}</text>
  119. </view>
  120. </view>
  121. </view>
  122. </view>
  123. </view>
  124. <!-- 根据角色显示不同的导航栏 -->
  125. <uv-tabbar :value="value" :fixed="true" @change="changeTo">
  126. <uv-tabbar-item text="首页">
  127. <template v-slot:active-icon>
  128. <image class="icon" src="/static/home/首页-点击.png"></image>
  129. </template>
  130. <template v-slot:inactive-icon>
  131. <image class="icon" src="/static/home/首页-未点击.png"></image>
  132. </template>
  133. </uv-tabbar-item>
  134. <uv-tabbar-item text="回收">
  135. <template v-slot:active-icon>
  136. <image class="icon" src="/static/home/回收-点击.png"></image>
  137. </template>
  138. <template v-slot:inactive-icon>
  139. <image class="icon" src="/static/home/回收-未点击.png"></image>
  140. </template>
  141. </uv-tabbar-item>
  142. <uv-tabbar-item text="我的">
  143. <template v-slot:active-icon>
  144. <image class="icon" src="/static/home/我的-点击.png"></image>
  145. </template>
  146. <template v-slot:inactive-icon>
  147. <image class="icon" src="/static/home/我的-未点击.png"></image>
  148. </template>
  149. </uv-tabbar-item>
  150. </uv-tabbar>
  151. </view>
  152. </template>
  153. <script>
  154. import pullRefreshMixin from '../mixins/pullRefreshMixin.js'
  155. export default {
  156. mixins: [pullRefreshMixin],
  157. data() {
  158. return {
  159. value: 0,
  160. processes: [],
  161. priceList: [],
  162. records: [],
  163. destinations: [{
  164. icon: '/static/home/爱心援乡.png',
  165. title: '爱心援乡',
  166. description: '精准帮扶贫困群体'
  167. },
  168. {
  169. icon: '/static/home/回塑新源.png',
  170. title: '回塑新源',
  171. description: '塑料的第二次成型'
  172. },
  173. {
  174. icon: '/static/home/织物出海.png',
  175. title: '织物出海',
  176. description: '分拣出最高价值'
  177. },
  178. {
  179. icon: '/static/home/碳循再生.png',
  180. title: '碳循再生',
  181. description: '减碳从出发生系统'
  182. }
  183. ],
  184. bannerList: [],
  185. pricePreviewList: [],
  186. cityList: [],
  187. addressCion: '',
  188. sbkCion: '',
  189. queryParams: {},
  190. }
  191. },
  192. computed: {
  193. cityListStr() {
  194. // 只取前8个城市,超出用...结尾
  195. const names = this.cityList.map(c => c.name)
  196. const max = 8
  197. if (names.length > max) {
  198. return names.slice(0, max).join('、') + '...'
  199. }
  200. return names.join('、')
  201. },
  202. address_cion() {
  203. console.log(getApp().globalData.configData, 'home-getApp().globalData.configData')
  204. const item = getApp().globalData.configData.find(i => i.keyName === 'address_cion')
  205. return item ? item.keyContent : ''
  206. },
  207. sbk_cion() {
  208. const item = getApp().globalData.configData.find(i => i.keyName === 'sbk_cion')
  209. return item ? item.keyContent : ''
  210. }
  211. },
  212. methods: {
  213. changeTo(e) {
  214. this.value = e
  215. console.log(e, '111')
  216. if (e == 1) {
  217. uni.reLaunch({
  218. url: '/pages/component/recycle'
  219. }, true);
  220. } else if (e == 2) {
  221. uni.reLaunch({
  222. url: '/pages/component/my'
  223. }, true);
  224. }
  225. },
  226. goAbout() {
  227. uni.navigateTo({
  228. url: '/pages/subcomponent/about'
  229. })
  230. },
  231. goCity() {
  232. uni.navigateTo({
  233. url: '/pages/baoyou-city/baoyou-city'
  234. })
  235. },
  236. getPickupto() {
  237. uni.switchTab({
  238. url: '/pages/component/recycle'
  239. })
  240. },
  241. async onRefresh() {
  242. await new Promise(resolve => setTimeout(resolve, 1000))
  243. },
  244. getAreaList() {
  245. this.$api('getAreaList', {}, (res) => {
  246. console.log(res, 'getAreaList');
  247. if (res.code == 200 && Array.isArray(res.result)) {
  248. // 按sort升序排序
  249. const sorted = res.result.slice().sort((a, b) => a.sort - b.sort)
  250. this.processes = sorted.map(item => ({
  251. // id: item.id,
  252. icon: item.image,
  253. text: item.title
  254. }))
  255. }
  256. })
  257. },
  258. goService() {
  259. uni.navigateTo({
  260. url: '/pages/subcomponent/admin_faq'
  261. })
  262. },
  263. goToRecycleCategory(id) {
  264. getApp().globalData.targetRecycleCategoryId = id
  265. console.log(getApp().globalData.targetRecycleCategoryId, 'getApp().globalData.targetRecycleCategoryId')
  266. uni.switchTab({
  267. url: '/pages/component/recycle'
  268. })
  269. },
  270. getPricePreview() {
  271. const resList = this.pricePreviewList || []
  272. if (Array.isArray(resList)) {
  273. // 只取一级分类,按sort升序
  274. const firstLevel = resList.filter(item => item.pid == '0').sort((a, b) => a.sort - b.sort)
  275. // console.log(firstLevel,'firstLevel');
  276. this.priceList = firstLevel.map(item => {
  277. // 从静态表中找图片和价格
  278. // const staticItem = this.priceListStatic.find(s => s.name.replace(/\s/g, '') === item.title.replace(/\s/g, ''))
  279. // console.log(item,'item');
  280. return {
  281. id: item.id, // 保证有id
  282. icon: item.icon ? item.icon : '',
  283. name: item.title,
  284. price: item.priceNo ? item.priceNo : '',
  285. unit: item.unit ? item.unit : ''
  286. }
  287. })
  288. }
  289. },
  290. getRecentGoods() {
  291. this.$api('getRecentGoodsList', {}, res => {
  292. if (res && res.code === 200 && Array.isArray(res.result) && res.result.length > 0) {
  293. this.records = res.result.map(item => ({
  294. id: item.id,
  295. image: item.image,
  296. name: item.name,
  297. orderId: item.orderId,
  298. phone: item.phone,
  299. price: item.price
  300. }))
  301. } else {
  302. this.records = []
  303. }
  304. })
  305. },
  306. getRecyclingDestination() {
  307. this.$api('getRecyclingDestination')
  308. .then(res => {
  309. this.destinations = res.result
  310. })
  311. },
  312. goToInspectionReport(item) {
  313. uni.navigateTo({
  314. url: `/pages/subcomponent/inspection-report?id=${item.orderId}`
  315. })
  316. },
  317. getFreeCityList() {
  318. this.$api('getFreeCityList', {}, res => {
  319. if (res && res.code === 200 && Array.isArray(res.result)) {
  320. // 只取一级城市(有children的name)
  321. this.cityList = res.result.map(item => ({
  322. name: item.name
  323. })).filter(item => item.name)
  324. } else {
  325. this.cityList = []
  326. }
  327. })
  328. },
  329. updateCionData() {
  330. const configData = getApp().globalData.configData || [];
  331. const address = configData.find(i => i.keyName === 'address_cion');
  332. const sbk = configData.find(i => i.keyName === 'sbk_cion');
  333. this.addressCion = address ? address.keyContent : '';
  334. this.sbkCion = sbk ? sbk.keyContent : '';
  335. },
  336. // 初始化页面数据的方法
  337. initializePageData() {
  338. const query = this.queryParams || {}
  339. if (query.shareId) {
  340. uni.setStorageSync('shareId', query.shareId)
  341. }
  342. this.getAreaList()
  343. this.getPricePreview()
  344. this.getRecentGoods()
  345. this.pricePreviewList = getApp().globalData.pricePreviewList || []
  346. this.bannerList = getApp().globalData.bannerList || []
  347. this.getFreeCityList()
  348. // 监听数据更新事件
  349. uni.$on('pricePreviewListUpdated', () => {
  350. this.pricePreviewList = getApp().globalData.pricePreviewList || []
  351. this.getPricePreview()
  352. })
  353. uni.$on('bannerListUpdated', () => {
  354. this.bannerList = getApp().globalData.bannerList || []
  355. })
  356. },
  357. },
  358. onLoad(query) {
  359. // 保存query参数
  360. this.queryParams = query
  361. // 检查App数据是否已经准备好
  362. if (!getApp().globalData.isAppDataReady) {
  363. // 显示加载状态
  364. uni.showLoading({
  365. title: '加载中...',
  366. mask: true
  367. })
  368. // 监听App数据准备完成事件
  369. uni.$on('appDataReady', () => {
  370. uni.hideLoading()
  371. this.initializePageData()
  372. })
  373. } else {
  374. // App数据已经准备好,直接初始化页面数据
  375. this.initializePageData()
  376. }
  377. },
  378. onUnload() {
  379. uni.$off('pricePreviewListUpdated')
  380. uni.$off('bannerListUpdated')
  381. uni.$off('configDataUpdated', this.updateCionData)
  382. },
  383. onShow() {
  384. this.updateCionData();
  385. // 监听全局数据更新
  386. uni.$on('configDataUpdated', this.updateCionData);
  387. this.getPricePreview();
  388. this.getRecyclingDestination()
  389. },
  390. }
  391. </script>
  392. <style lang="scss" scoped>
  393. .container {
  394. min-height: 100vh;
  395. background-color: #f8f8f8;
  396. display: flex;
  397. flex-direction: column;
  398. padding-bottom: calc(var(--window-bottom) + 70px);
  399. }
  400. .safe-area {
  401. padding-bottom: constant(safe-area-inset-bottom);
  402. padding-bottom: env(safe-area-inset-bottom);
  403. }
  404. .banner {
  405. width: 100%;
  406. height: 330rpx;
  407. position: relative;
  408. overflow: hidden;
  409. border-radius: 0 0 30rpx 30rpx;
  410. image {
  411. width: 100%;
  412. height: 100%;
  413. }
  414. }
  415. .content {
  416. // flex: 1;
  417. width: 90%;
  418. margin: -70rpx auto 0;
  419. position: relative;
  420. z-index: 3;
  421. padding-bottom: 20rpx;
  422. }
  423. .Xiadan-section {
  424. display: flex;
  425. // justify-content: space-around;
  426. align-items: center;
  427. margin-bottom: 20rpx;
  428. background: linear-gradient(to bottom, #fff3db 0%, #fffefb 50%);
  429. image {
  430. width: 80rpx;
  431. height: 80rpx;
  432. }
  433. .left-text {
  434. font-family: PingFang SC;
  435. font-weight: 400;
  436. font-size: 12px;
  437. line-height: 140%;
  438. letter-spacing: 0%;
  439. }
  440. .right {
  441. display: flex;
  442. // flex-direction: row-reverse;
  443. box-sizing: border-box;
  444. align-items: center;
  445. justify-content: center;
  446. background-color: #fff0d2;
  447. color: #da7143;
  448. font-size: 24rpx;
  449. // flex-grow: 2;
  450. border: 1px solid #da7143;
  451. border-radius: 10rpx;
  452. width: 25%;
  453. image {
  454. width: 40rpx;
  455. height: 40rpx;
  456. }
  457. }
  458. }
  459. .section-header {
  460. display: flex;
  461. // justify-content: space-around;
  462. align-items: center;
  463. margin-bottom: 20rpx;
  464. .title {
  465. font-size: 32rpx;
  466. font-weight: bold;
  467. color: #333;
  468. }
  469. .more {
  470. // justify-content: right;
  471. display: flex;
  472. flex-direction: row-reverse;
  473. align-items: center;
  474. color: #999;
  475. font-size: 24rpx;
  476. flex-grow: 2;
  477. // width: 100%;
  478. // margin-right: 0 auto;
  479. }
  480. }
  481. .process-section {
  482. background: #fff;
  483. border-radius: 50rpx;
  484. padding: 30rpx;
  485. margin-bottom: 20rpx;
  486. background: linear-gradient(to bottom, #fff5e1 0%, #fffefb 30%);
  487. .contact-service {
  488. display: flex;
  489. align-items: center;
  490. font-size: 24rpx;
  491. color: #666;
  492. border: 1px solid #da7143;
  493. background-color: #fff0d2;
  494. .service-icon {
  495. width: 32rpx;
  496. height: 32rpx;
  497. margin-right: 8rpx;
  498. }
  499. }
  500. .process-grid {
  501. display: grid;
  502. grid-template-columns: repeat(4, 1fr);
  503. gap: 20rpx;
  504. margin: 30rpx 0;
  505. border: none;
  506. }
  507. .process-item {
  508. position: relative;
  509. display: flex;
  510. flex-direction: column;
  511. align-items: center;
  512. background-color: #fff8ea;
  513. // left: 0; right: 0;
  514. .process-icon {
  515. width: 80rpx;
  516. height: 80rpx;
  517. margin-bottom: 10rpx;
  518. }
  519. .process-text {
  520. font-size: 24rpx;
  521. color: #333;
  522. }
  523. .process-number {
  524. position: absolute;
  525. top: -10rpx;
  526. left: 50%;
  527. transform: translateX(-50%);
  528. font-size: 24rpx;
  529. color: #999;
  530. }
  531. }
  532. .submit-btn {
  533. background: linear-gradient(to right, #ffd01e, #ff8917);
  534. border-radius: 70rpx;
  535. padding: 20rpx;
  536. text-align: center;
  537. position: relative;
  538. border: none;
  539. display: flex;
  540. flex-direction: column;
  541. overflow: visible;
  542. text {
  543. color: #ffffff;
  544. font-size: 32rpx;
  545. font-weight: bold;
  546. line-height: 40rpx;
  547. // display: block;
  548. }
  549. .btn-desc {
  550. font-size: 24rpx;
  551. font-weight: normal;
  552. // margin-top: 4rpx;
  553. }
  554. .arrow-icon {
  555. position: absolute;
  556. right: 10rpx;
  557. top: 10%;
  558. transform: translateY(-50%);
  559. width: 40rpx;
  560. height: 40rpx;
  561. // z-index: 5;
  562. }
  563. .arrow-icon-left {
  564. position: absolute;
  565. left: 1rpx;
  566. top: 90%;
  567. transform: translateY(-50%);
  568. width: 40rpx;
  569. height: 40rpx;
  570. // z-index: 4;
  571. }
  572. }
  573. .submit-btn::after {
  574. border: none !important;
  575. }
  576. }
  577. .city-section {
  578. background: #fff;
  579. border-radius: 20rpx;
  580. padding: 30rpx;
  581. margin-bottom: 20rpx;
  582. .city-header {
  583. display: flex;
  584. justify-content: space-between;
  585. align-items: center;
  586. font-size: 28rpx;
  587. color: #333;
  588. margin-bottom: 10rpx;
  589. }
  590. .city-list {
  591. font-size: 24rpx;
  592. color: #999;
  593. }
  594. }
  595. .price-section {
  596. background: #f0f9eb;
  597. border-radius: 20rpx;
  598. padding: 30rpx;
  599. margin-bottom: 20rpx;
  600. background-color: #fffefb;
  601. background: linear-gradient(to bottom, #fff3db 0%, #fffefb 5%);
  602. .section-header {
  603. margin-bottom: 40rpx;
  604. }
  605. .price-grid {
  606. display: grid;
  607. grid-template-columns: repeat(2, 1fr);
  608. gap: 20rpx;
  609. }
  610. .price-item {
  611. display: flex;
  612. flex-direction: column;
  613. align-items: center;
  614. background: #fff;
  615. border-radius: 16rpx;
  616. padding: 30rpx;
  617. background-color: #fff8ea;
  618. .item-icon {
  619. width: 100rpx;
  620. height: 100rpx;
  621. margin-bottom: 10rpx;
  622. &.placeholder {
  623. width: 80rpx;
  624. height: 80rpx;
  625. margin-bottom: 10rpx;
  626. background: #f5f5f5;
  627. border-radius: 16rpx;
  628. }
  629. }
  630. .item-name {
  631. font-size: 26rpx;
  632. color: #333;
  633. margin-bottom: 6rpx;
  634. }
  635. .item-price {
  636. font-family: PingFang SC;
  637. font-weight: 400;
  638. font-size: 24rpx;
  639. line-height: 140%;
  640. letter-spacing: 0%;
  641. text-align: center;
  642. .item-price-right {
  643. text-align: center;
  644. font-size: 24rpx;
  645. color: #666;
  646. line-height: 140%;
  647. letter-spacing: 0%;
  648. }
  649. }
  650. }
  651. }
  652. .recent-section {
  653. background: #f0f9eb;
  654. border-radius: 20rpx;
  655. padding: 30rpx;
  656. margin-bottom: 20rpx;
  657. background-color: #fffefb;
  658. background: linear-gradient(to bottom, #e8ffe0 0%, #fffefb 15%);
  659. .records-grid {
  660. display: grid;
  661. grid-template-columns: repeat(3, 1fr);
  662. gap: 20rpx;
  663. }
  664. .record-item {
  665. display: flex;
  666. flex-direction: column;
  667. align-items: center;
  668. background: linear-gradient(to top, #e8ffe0 0%, #fffefb 100%);
  669. border-radius: 16rpx;
  670. padding: 10rpx;
  671. background-color: #fff8ea;
  672. image {
  673. width: 60rpx;
  674. height: 60rpx;
  675. border-radius: 50%;
  676. }
  677. .location {
  678. font-size: 28rpx;
  679. color: #333;
  680. font-weight: bold;
  681. }
  682. .amount {
  683. font-size: 30rpx;
  684. color: #13ac47;
  685. font-weight: bold;
  686. margin: 6rpx 0;
  687. }
  688. .user-id {
  689. font-family: PingFang SC;
  690. font-weight: 500;
  691. font-size: 24rpx;
  692. line-height: 140%;
  693. letter-spacing: 0%;
  694. text-align: center;
  695. color: #183c5c;
  696. }
  697. .user-id-f {
  698. font-family: PingFang SC;
  699. font-weight: 400;
  700. font-size: 22rpx;
  701. line-height: 140%;
  702. letter-spacing: 0%;
  703. text-align: center;
  704. color: #9b9b9b;
  705. }
  706. }
  707. }
  708. .destination-section {
  709. // background: #fff;
  710. border-radius: 20rpx;
  711. padding: 30rpx;
  712. margin-bottom: 20rpx;
  713. background: linear-gradient(to bottom, #f2f0fc 0%, #fffefb 10%);
  714. padding-bottom: calc(var(--window-bottom) + 60px);
  715. .destination-grid {
  716. display: grid;
  717. grid-template-columns: repeat(2, 1fr);
  718. gap: 20rpx;
  719. }
  720. .destination-item {
  721. display: flex;
  722. align-items: center;
  723. // background: #fff9f9;
  724. border-radius: 16rpx;
  725. padding: 20rpx;
  726. .dest-icon {
  727. width: 60rpx;
  728. height: 60rpx;
  729. margin-right: 16rpx;
  730. }
  731. .dest-info {
  732. flex: 1;
  733. .dest-title {
  734. font-size: 26rpx;
  735. color: #333;
  736. margin-bottom: 4rpx;
  737. }
  738. .dest-desc {
  739. font-size: 22rpx;
  740. color: #999;
  741. }
  742. }
  743. }
  744. }
  745. .destination-item1 {
  746. background: linear-gradient(to top, #ffebeb, #fffefb);
  747. }
  748. .destination-item2 {
  749. background: linear-gradient(to top, #ebf8ff, #fffefb);
  750. }
  751. .destination-item3 {
  752. background: linear-gradient(to top, #ebedff, #fffefb);
  753. }
  754. .destination-item4 {
  755. background: linear-gradient(to top, #ebfff2, #fffefb);
  756. }
  757. .about-section {
  758. background: linear-gradient(to bottom, #fff3db 0%, #fffefb 30%);
  759. border-radius: 20rpx;
  760. padding: 30rpx;
  761. display: flex;
  762. justify-content: space-between;
  763. flex-direction: column;
  764. .about-footer {
  765. display: flex;
  766. flex-direction: row;
  767. align-items: center;
  768. justify-content: center;
  769. }
  770. .about-header {
  771. display: flex;
  772. align-items: center;
  773. .logo {
  774. width: 60rpx;
  775. height: 60rpx;
  776. margin-right: 16rpx;
  777. }
  778. .about-title {
  779. font-size: 28rpx;
  780. color: #333;
  781. }
  782. }
  783. .about-content {
  784. flex: 1;
  785. margin-left: 20rpx;
  786. text {
  787. display: block;
  788. font-size: 26rpx;
  789. color: #333;
  790. }
  791. .about-desc {
  792. font-size: 22rpx;
  793. color: #999;
  794. margin-top: 4rpx;
  795. }
  796. }
  797. }
  798. .tab-bar {
  799. position: fixed;
  800. bottom: 0;
  801. left: 0;
  802. right: 0;
  803. height: 100rpx;
  804. background-color: #fff;
  805. display: flex;
  806. justify-content: space-around;
  807. align-items: center;
  808. border-top: 1rpx solid #f5f5f5;
  809. box-shadow: 0 -2rpx 10rpx rgba(0, 0, 0, 0.05);
  810. .tab-item {
  811. display: flex;
  812. flex-direction: column;
  813. align-items: center;
  814. padding: 10rpx 0;
  815. transition: all 0.3s ease;
  816. .tab-icon {
  817. width: 48rpx;
  818. height: 48rpx;
  819. margin-bottom: 6rpx;
  820. }
  821. text {
  822. font-size: 22rpx;
  823. color: #666;
  824. transition: color 0.3s ease;
  825. }
  826. &.active {
  827. text {
  828. color: #ff5e00;
  829. }
  830. }
  831. &:active {
  832. transform: scale(0.95);
  833. }
  834. }
  835. }
  836. @keyframes fadeInUp {
  837. from {
  838. opacity: 0;
  839. transform: translateY(20rpx);
  840. }
  841. to {
  842. opacity: 1;
  843. transform: translateY(0);
  844. }
  845. }
  846. @keyframes fadeInScale {
  847. from {
  848. opacity: 0;
  849. transform: scale(0.8);
  850. }
  851. to {
  852. opacity: 1;
  853. transform: scale(1);
  854. }
  855. }
  856. </style>