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

932 lines
22 KiB

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