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

952 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
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. // 先设置数据,再调用处理方法
  343. this.pricePreviewList = getApp().globalData.pricePreviewList || []
  344. this.bannerList = getApp().globalData.bannerList || []
  345. this.getAreaList()
  346. this.getPricePreview()
  347. this.getRecentGoods()
  348. this.getFreeCityList()
  349. // 监听数据更新事件
  350. uni.$on('pricePreviewListUpdated', () => {
  351. this.pricePreviewList = getApp().globalData.pricePreviewList || []
  352. this.getPricePreview()
  353. })
  354. uni.$on('bannerListUpdated', () => {
  355. this.bannerList = getApp().globalData.bannerList || []
  356. })
  357. },
  358. },
  359. onLoad(query) {
  360. // 保存query参数
  361. this.queryParams = query
  362. // 检查App数据是否已经准备好
  363. if (!getApp().globalData.isAppDataReady) {
  364. // 显示加载状态
  365. uni.showLoading({
  366. title: '加载中...',
  367. mask: true
  368. })
  369. // 监听App数据准备完成事件
  370. uni.$on('appDataReady', () => {
  371. uni.hideLoading()
  372. this.initializePageData()
  373. })
  374. } else {
  375. // App数据已经准备好,直接初始化页面数据
  376. this.initializePageData()
  377. }
  378. },
  379. onUnload() {
  380. uni.$off('pricePreviewListUpdated')
  381. uni.$off('bannerListUpdated')
  382. uni.$off('configDataUpdated', this.updateCionData)
  383. },
  384. onShow() {
  385. this.updateCionData();
  386. // 监听全局数据更新
  387. uni.$on('configDataUpdated', this.updateCionData);
  388. this.getPricePreview();
  389. this.getRecyclingDestination()
  390. },
  391. }
  392. </script>
  393. <style lang="scss" scoped>
  394. .container {
  395. min-height: 100vh;
  396. background-color: #f8f8f8;
  397. display: flex;
  398. flex-direction: column;
  399. padding-bottom: calc(var(--window-bottom) + 70px);
  400. }
  401. .safe-area {
  402. padding-bottom: constant(safe-area-inset-bottom);
  403. padding-bottom: env(safe-area-inset-bottom);
  404. }
  405. .banner {
  406. width: 100%;
  407. height: 330rpx;
  408. position: relative;
  409. overflow: hidden;
  410. border-radius: 0 0 30rpx 30rpx;
  411. image {
  412. width: 100%;
  413. height: 100%;
  414. }
  415. }
  416. .content {
  417. // flex: 1;
  418. width: 90%;
  419. margin: -70rpx auto 0;
  420. position: relative;
  421. z-index: 3;
  422. padding-bottom: 20rpx;
  423. }
  424. .Xiadan-section {
  425. display: flex;
  426. // justify-content: space-around;
  427. align-items: center;
  428. margin-bottom: 20rpx;
  429. background: linear-gradient(to bottom, #fff3db 0%, #fffefb 50%);
  430. image {
  431. width: 80rpx;
  432. height: 80rpx;
  433. }
  434. .left-text {
  435. font-family: PingFang SC;
  436. font-weight: 400;
  437. font-size: 12px;
  438. line-height: 140%;
  439. letter-spacing: 0%;
  440. }
  441. .right {
  442. display: flex;
  443. // flex-direction: row-reverse;
  444. box-sizing: border-box;
  445. align-items: center;
  446. justify-content: center;
  447. background-color: #fff0d2;
  448. color: #da7143;
  449. font-size: 24rpx;
  450. // flex-grow: 2;
  451. border: 1px solid #da7143;
  452. border-radius: 10rpx;
  453. width: 25%;
  454. image {
  455. width: 40rpx;
  456. height: 40rpx;
  457. }
  458. }
  459. }
  460. .section-header {
  461. display: flex;
  462. // justify-content: space-around;
  463. align-items: center;
  464. margin-bottom: 20rpx;
  465. .title {
  466. font-size: 32rpx;
  467. font-weight: bold;
  468. color: #333;
  469. }
  470. .more {
  471. // justify-content: right;
  472. display: flex;
  473. flex-direction: row-reverse;
  474. align-items: center;
  475. color: #999;
  476. font-size: 24rpx;
  477. flex-grow: 2;
  478. // width: 100%;
  479. // margin-right: 0 auto;
  480. }
  481. }
  482. .process-section {
  483. background: #fff;
  484. border-radius: 50rpx;
  485. padding: 30rpx;
  486. margin-bottom: 20rpx;
  487. background: linear-gradient(to bottom, #fff5e1 0%, #fffefb 30%);
  488. .contact-service {
  489. display: flex;
  490. align-items: center;
  491. font-size: 24rpx;
  492. color: #666;
  493. border: 1px solid #da7143;
  494. background-color: #fff0d2;
  495. .service-icon {
  496. width: 32rpx;
  497. height: 32rpx;
  498. margin-right: 8rpx;
  499. }
  500. }
  501. .process-grid {
  502. display: grid;
  503. grid-template-columns: repeat(4, 1fr);
  504. gap: 20rpx;
  505. margin: 30rpx 0;
  506. border: none;
  507. }
  508. .process-item {
  509. position: relative;
  510. display: flex;
  511. flex-direction: column;
  512. align-items: center;
  513. background-color: #fff8ea;
  514. // left: 0; right: 0;
  515. .process-icon {
  516. width: 80rpx;
  517. height: 80rpx;
  518. margin-bottom: 10rpx;
  519. }
  520. .process-text {
  521. font-size: 24rpx;
  522. color: #333;
  523. }
  524. .process-number {
  525. position: absolute;
  526. top: -10rpx;
  527. left: 50%;
  528. transform: translateX(-50%);
  529. font-size: 24rpx;
  530. color: #999;
  531. }
  532. }
  533. .submit-btn {
  534. background: linear-gradient(to right, #ffd01e, #ff8917);
  535. border-radius: 70rpx;
  536. padding: 20rpx;
  537. text-align: center;
  538. position: relative;
  539. border: none;
  540. display: flex;
  541. flex-direction: column;
  542. overflow: visible;
  543. text {
  544. color: #ffffff;
  545. font-size: 32rpx;
  546. font-weight: bold;
  547. line-height: 40rpx;
  548. // display: block;
  549. }
  550. .btn-desc {
  551. font-size: 24rpx;
  552. font-weight: normal;
  553. // margin-top: 4rpx;
  554. }
  555. .arrow-icon {
  556. position: absolute;
  557. right: 10rpx;
  558. top: 10%;
  559. transform: translateY(-50%);
  560. width: 40rpx;
  561. height: 40rpx;
  562. // z-index: 5;
  563. }
  564. .arrow-icon-left {
  565. position: absolute;
  566. left: 1rpx;
  567. top: 90%;
  568. transform: translateY(-50%);
  569. width: 40rpx;
  570. height: 40rpx;
  571. // z-index: 4;
  572. }
  573. }
  574. .submit-btn::after {
  575. border: none !important;
  576. }
  577. }
  578. .city-section {
  579. background: #fff;
  580. border-radius: 20rpx;
  581. padding: 30rpx;
  582. margin-bottom: 20rpx;
  583. .city-header {
  584. display: flex;
  585. justify-content: space-between;
  586. align-items: center;
  587. font-size: 28rpx;
  588. color: #333;
  589. margin-bottom: 10rpx;
  590. }
  591. .city-list {
  592. font-size: 24rpx;
  593. color: #999;
  594. }
  595. }
  596. .price-section {
  597. background: #f0f9eb;
  598. border-radius: 20rpx;
  599. padding: 30rpx;
  600. margin-bottom: 20rpx;
  601. background-color: #fffefb;
  602. background: linear-gradient(to bottom, #fff3db 0%, #fffefb 5%);
  603. .section-header {
  604. margin-bottom: 40rpx;
  605. }
  606. .price-grid {
  607. display: grid;
  608. grid-template-columns: repeat(2, 1fr);
  609. gap: 20rpx;
  610. }
  611. .price-item {
  612. display: flex;
  613. flex-direction: column;
  614. align-items: center;
  615. background: #fff;
  616. border-radius: 16rpx;
  617. padding: 30rpx;
  618. background-color: #fff8ea;
  619. .item-icon {
  620. width: 100rpx;
  621. height: 100rpx;
  622. margin-bottom: 10rpx;
  623. &.placeholder {
  624. width: 80rpx;
  625. height: 80rpx;
  626. margin-bottom: 10rpx;
  627. background: #f5f5f5;
  628. border-radius: 16rpx;
  629. }
  630. }
  631. .item-name {
  632. font-size: 26rpx;
  633. color: #333;
  634. margin-bottom: 6rpx;
  635. }
  636. .item-price {
  637. font-family: PingFang SC;
  638. font-weight: 400;
  639. font-size: 24rpx;
  640. line-height: 140%;
  641. letter-spacing: 0%;
  642. text-align: center;
  643. .item-price-right {
  644. text-align: center;
  645. font-size: 24rpx;
  646. color: #666;
  647. line-height: 140%;
  648. letter-spacing: 0%;
  649. }
  650. }
  651. }
  652. }
  653. .recent-section {
  654. background: #f0f9eb;
  655. border-radius: 20rpx;
  656. padding: 30rpx;
  657. margin-bottom: 20rpx;
  658. background-color: #fffefb;
  659. background: linear-gradient(to bottom, #e8ffe0 0%, #fffefb 15%);
  660. .records-grid {
  661. display: grid;
  662. grid-template-columns: repeat(3, 1fr);
  663. gap: 20rpx;
  664. }
  665. .record-item {
  666. display: flex;
  667. flex-direction: column;
  668. align-items: center;
  669. background: linear-gradient(to top, #e8ffe0 0%, #fffefb 100%);
  670. border-radius: 16rpx;
  671. padding: 10rpx;
  672. background-color: #fff8ea;
  673. image {
  674. width: 60rpx;
  675. height: 60rpx;
  676. border-radius: 50%;
  677. }
  678. .location {
  679. font-size: 28rpx;
  680. color: #333;
  681. font-weight: bold;
  682. }
  683. .amount {
  684. font-size: 30rpx;
  685. color: #13ac47;
  686. font-weight: bold;
  687. margin: 6rpx 0;
  688. }
  689. .user-id {
  690. font-family: PingFang SC;
  691. font-weight: 500;
  692. font-size: 24rpx;
  693. line-height: 140%;
  694. letter-spacing: 0%;
  695. text-align: center;
  696. color: #183c5c;
  697. }
  698. .user-id-f {
  699. font-family: PingFang SC;
  700. font-weight: 400;
  701. font-size: 22rpx;
  702. line-height: 140%;
  703. letter-spacing: 0%;
  704. text-align: center;
  705. color: #9b9b9b;
  706. }
  707. }
  708. }
  709. .destination-section {
  710. // background: #fff;
  711. border-radius: 20rpx;
  712. padding: 30rpx;
  713. margin-bottom: 20rpx;
  714. background: linear-gradient(to bottom, #f2f0fc 0%, #fffefb 10%);
  715. padding-bottom: calc(var(--window-bottom) + 60px);
  716. .destination-grid {
  717. display: grid;
  718. grid-template-columns: repeat(2, 1fr);
  719. gap: 20rpx;
  720. }
  721. .destination-item {
  722. display: flex;
  723. align-items: center;
  724. // background: #fff9f9;
  725. border-radius: 16rpx;
  726. padding: 20rpx;
  727. .dest-icon {
  728. width: 60rpx;
  729. height: 60rpx;
  730. margin-right: 16rpx;
  731. }
  732. .dest-info {
  733. flex: 1;
  734. .dest-title {
  735. font-size: 26rpx;
  736. color: #333;
  737. margin-bottom: 4rpx;
  738. }
  739. .dest-desc {
  740. font-size: 22rpx;
  741. color: #999;
  742. }
  743. }
  744. }
  745. }
  746. .destination-item1 {
  747. background: linear-gradient(to top, #ffebeb, #fffefb);
  748. }
  749. .destination-item2 {
  750. background: linear-gradient(to top, #ebf8ff, #fffefb);
  751. }
  752. .destination-item3 {
  753. background: linear-gradient(to top, #ebedff, #fffefb);
  754. }
  755. .destination-item4 {
  756. background: linear-gradient(to top, #ebfff2, #fffefb);
  757. }
  758. .about-section {
  759. background: linear-gradient(to bottom, #fff3db 0%, #fffefb 30%);
  760. border-radius: 20rpx;
  761. padding: 30rpx;
  762. display: flex;
  763. justify-content: space-between;
  764. flex-direction: column;
  765. .about-footer {
  766. display: flex;
  767. flex-direction: row;
  768. align-items: center;
  769. justify-content: center;
  770. }
  771. .about-header {
  772. display: flex;
  773. align-items: center;
  774. .logo {
  775. width: 60rpx;
  776. height: 60rpx;
  777. margin-right: 16rpx;
  778. }
  779. .about-title {
  780. font-size: 28rpx;
  781. color: #333;
  782. }
  783. }
  784. .about-content {
  785. flex: 1;
  786. margin-left: 20rpx;
  787. text {
  788. display: block;
  789. font-size: 26rpx;
  790. color: #333;
  791. }
  792. .about-desc {
  793. font-size: 22rpx;
  794. color: #999;
  795. margin-top: 4rpx;
  796. }
  797. }
  798. }
  799. .tab-bar {
  800. position: fixed;
  801. bottom: 0;
  802. left: 0;
  803. right: 0;
  804. height: 100rpx;
  805. background-color: #fff;
  806. display: flex;
  807. justify-content: space-around;
  808. align-items: center;
  809. border-top: 1rpx solid #f5f5f5;
  810. box-shadow: 0 -2rpx 10rpx rgba(0, 0, 0, 0.05);
  811. .tab-item {
  812. display: flex;
  813. flex-direction: column;
  814. align-items: center;
  815. padding: 10rpx 0;
  816. transition: all 0.3s ease;
  817. .tab-icon {
  818. width: 48rpx;
  819. height: 48rpx;
  820. margin-bottom: 6rpx;
  821. }
  822. text {
  823. font-size: 22rpx;
  824. color: #666;
  825. transition: color 0.3s ease;
  826. }
  827. &.active {
  828. text {
  829. color: #ff5e00;
  830. }
  831. }
  832. &:active {
  833. transform: scale(0.95);
  834. }
  835. }
  836. }
  837. @keyframes fadeInUp {
  838. from {
  839. opacity: 0;
  840. transform: translateY(20rpx);
  841. }
  842. to {
  843. opacity: 1;
  844. transform: translateY(0);
  845. }
  846. }
  847. @keyframes fadeInScale {
  848. from {
  849. opacity: 0;
  850. transform: scale(0.8);
  851. }
  852. to {
  853. opacity: 1;
  854. transform: scale(1);
  855. }
  856. }
  857. </style>