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

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