index.vue 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837
  1. <script setup lang="ts">
  2. import { ref, computed } from 'vue'
  3. import { onLoad, onPageScroll, onShow } from '@dcloudio/uni-app'
  4. import {
  5. getParkServiceOil,
  6. getParkServicePower,
  7. getParkServiceShopList,
  8. getParkServiceScenicList,
  9. getParkServiceFacility,
  10. getParkServiceNoticeList,
  11. getBannerApi
  12. } from '@/api/home'
  13. import { h5PhoneLoginApi } from '@/api/login'
  14. import { useListLoader } from '@/composables/useListLoader'
  15. import { useGlobal } from '@/composables/index'
  16. import { user } from '@/stores/modules/user'
  17. const { minioUrl, pathPre } = useGlobal()
  18. const userStore = user()
  19. const angle = ref(45)
  20. // 监听页面滚动
  21. onPageScroll((e) => {
  22. if (e.scrollTop > 80) {
  23. angle.value = 90
  24. } else {
  25. angle.value = 45
  26. }
  27. })
  28. // 轮播图数据
  29. const list = ref([`${minioUrl}/home_banner.png`])
  30. const tabs = ref([{ name: '加油' }, { name: '充电' }])
  31. const tabActive = ref(0)
  32. // 金刚区列表
  33. const navList = ref([
  34. { image: `${minioUrl}/icon_nav_01.png`, text: '我要加油', path: '/base/common/refuel', w: '53rpx', h: '53rpx' },
  35. { image: `${minioUrl}/icon_nav_02.png`, text: '我要充电', path: '/base/common/charge', w: '60rpx', h: '53rpx' },
  36. { image: `${minioUrl}/icon_nav_03.png`, text: '我要吃饭', path: '/base/shop/meal', w: '57rpx', h: '57rpx' },
  37. { image: `${minioUrl}/icon_nav_04.png`, text: '我要修车', path: '/base/common/repair', w: '60rpx', h: '56rpx' },
  38. { image: `${minioUrl}/icon_nav_05.png`, text: '投诉建议', path: '/base/suggest/index', w: '59rpx', h: '53rpx' },
  39. { image: `${minioUrl}/icon_nav_06.png`, text: '一键救援', path: '', w: '76rpx', h: '76rpx', type: 'popup' },
  40. { image: `${minioUrl}/icon_nav_07.png`, text: '司机之家', path: '/base/common/driversHome', w: '76rpx', h: '76rpx' },
  41. { image: `${minioUrl}/icon_nav_08.png`, text: '母婴室', path: '/base/common/nursingRoom', w: '76rpx', h: '76rpx' },
  42. { image: `${minioUrl}/icon_nav_09.png`, text: '失物招领', path: '', w: '76rpx', h: '76rpx', type: 'popup' },
  43. { image: `${minioUrl}/icon_nav_10.png`, text: '招商加盟', path: '/base/common/join', w: '76rpx', h: '76rpx' }
  44. ])
  45. const selectedValue = ref('')
  46. // 一键救援弹窗展示
  47. const isRescueShow = ref(false)
  48. // 失物招领弹窗展示
  49. const isLostFoundShow = ref(false)
  50. onLoad((options) => {
  51. const m = options?.m || ''
  52. if (m) {
  53. h5PhoneLoginApi(m).then((res: any) => {
  54. const token = res.data.token || ''
  55. if (token) {
  56. uni.setStorageSync('token', token)
  57. userStore.setToken(token)
  58. }
  59. })
  60. }
  61. // 页面加载时从本地缓存获取园区ID
  62. const cachedParkId = uni.getStorageSync('parkId')
  63. if (cachedParkId) {
  64. selectedValue.value = cachedParkId
  65. params.value.parkId = cachedParkId
  66. }
  67. })
  68. const init = () => {
  69. // 获取我要加油数据
  70. getOilList()
  71. // 获取我要充电数据
  72. getPowerList()
  73. // 获取精选商家数据
  74. getShopList()
  75. // 获取服务设施数据
  76. getFacilityList()
  77. // 获取出行提醒数据
  78. getNoticeList()
  79. // 获取banner数据
  80. // getBannerList()
  81. }
  82. // 处理园区选择变化
  83. const handleParkChange = () => {
  84. params.value.parkId = selectedValue.value
  85. oilInfo.value = {}
  86. listOli.value = []
  87. powerInfo.value = {}
  88. // 初始化数据
  89. init()
  90. // 重新加载列表数据
  91. handleSearch()
  92. }
  93. onShow(() => {
  94. // 初始化数据
  95. init()
  96. })
  97. // 获取banner数据
  98. const bannerList = ref<any>([])
  99. const getBannerList = async () => {
  100. const res = (await getBannerApi()) as any
  101. if (res.data) {
  102. bannerList.value = res.data.map((item: any) => item.imageInfo?.url)
  103. }
  104. }
  105. // 获取我要加油数据
  106. const oilInfo = ref<any>({})
  107. const listOli = ref<any>([])
  108. const getOilList = async () => {
  109. const res = (await getParkServiceOil(selectedValue.value)) as any
  110. if (res.data) {
  111. oilInfo.value = JSON.parse(res.data.content)
  112. const {
  113. oil92ActivityPrice,
  114. oil92OriginalPrice,
  115. oil95ActivityPrice,
  116. oil95OriginalPrice,
  117. oil89ActivityPrice,
  118. oil89OriginalPrice,
  119. dieselActivityPrice,
  120. dieselOriginalPrice
  121. } = oilInfo.value
  122. const _list = [
  123. { name: '92#', activityPrice: oil92ActivityPrice, originalPrice: oil92OriginalPrice },
  124. { name: '95#', activityPrice: oil95ActivityPrice, originalPrice: oil95OriginalPrice },
  125. { name: '89#', activityPrice: oil89ActivityPrice, originalPrice: oil89OriginalPrice },
  126. { name: '柴油#', activityPrice: dieselActivityPrice, originalPrice: dieselOriginalPrice }
  127. ]
  128. listOli.value = _list
  129. }
  130. }
  131. // 获取我要充电数据
  132. const powerInfo = ref<any>({})
  133. const getPowerList = async () => {
  134. const res = (await getParkServicePower(selectedValue.value)) as any
  135. if (res.data) {
  136. powerInfo.value = JSON.parse(res.data.content)
  137. }
  138. }
  139. // 获取精选商家数据
  140. const shopList = ref<any>([])
  141. const getShopList = async () => {
  142. const res = (await getParkServiceShopList({ parkId: selectedValue.value })) as any
  143. shopList.value = res.rows.slice(0, 5).map((item: any) => ({
  144. ...item,
  145. content: JSON.parse(item.content)
  146. }))
  147. }
  148. // 获取服务设施数据
  149. const facilityList = ref<any>([])
  150. const getFacilityList = async () => {
  151. const res = (await getParkServiceFacility({
  152. parkId: selectedValue.value
  153. })) as any
  154. facilityList.value = res.rows
  155. .slice(0, 6)
  156. .reverse()
  157. .map((item: any) => ({
  158. ...item,
  159. content: JSON.parse(item.content)
  160. }))
  161. }
  162. // 获取附近景区数据
  163. const scenicList = computed(() => {
  164. return listData.value.map((item: any) => ({
  165. ...item,
  166. content: JSON.parse(item.content)
  167. }))
  168. })
  169. // 获取出行提醒数据
  170. const noticeList = ref<any>([])
  171. const getNoticeList = async () => {
  172. const res = (await getParkServiceNoticeList({
  173. top: 1
  174. })) as any
  175. noticeList.value = res.rows.map((v: any) => v.title)
  176. }
  177. // 列表加载
  178. const { listData, upCallback, downCallback, handleSearch, mescrollInit, params } = useListLoader({
  179. apiFn: getParkServiceScenicList,
  180. initialParams: {
  181. parkId: selectedValue.value
  182. }
  183. })
  184. // 金刚区点击事件
  185. const navClick = (item: { path: string; type?: string; text?: string }) => {
  186. if (item.type === 'popup') {
  187. // 弹窗展示
  188. if (item.text === '一键救援') {
  189. isRescueShow.value = true
  190. } else if (item.text === '失物招领') {
  191. isLostFoundShow.value = true
  192. }
  193. return
  194. }
  195. uni.navigateTo({
  196. url: item.path
  197. })
  198. }
  199. // 出行提示点击事件
  200. const navigateToTips = () => {
  201. uni.navigateTo({
  202. url: '/base/travel/tips'
  203. })
  204. }
  205. // 精选商家点击事件
  206. const navigateToShop = () => {
  207. uni.navigateTo({
  208. url: '/base/shop/index'
  209. })
  210. }
  211. // 精选商家详情点击事件
  212. const navigateToShopDetail = (id: string) => {
  213. uni.navigateTo({
  214. url: '/base/shop/detailsShop?id=' + id
  215. })
  216. }
  217. // 景点点击事件
  218. const navigateToSpot = (id: string) => {
  219. uni.navigateTo({
  220. url: '/base/common/spot?id=' + id
  221. })
  222. }
  223. // 导航功能
  224. const goToNavigation = (longitude: string, latitude: string, name: string) => {
  225. uni.openLocation({
  226. latitude: Number(latitude),
  227. longitude: Number(longitude),
  228. name: name,
  229. success: () => {
  230. console.log('导航功能调用成功')
  231. }
  232. })
  233. }
  234. // 拨打电话
  235. const callPhone = (phone: string) => {
  236. uni.makePhoneCall({
  237. phoneNumber: phone
  238. })
  239. }
  240. </script>
  241. <template>
  242. <mescroll-body
  243. @init="mescrollInit"
  244. :down="{ use: false, minAngle: angle }"
  245. :bottombar="false"
  246. :up="{ bgColor: '#f6f7fb', textColor: '#999', empty: { use: false } }"
  247. @down="downCallback"
  248. @up="upCallback"
  249. >
  250. <view class="index-container">
  251. <!-- 头部背景 -->
  252. <view class="header-bg" :style="{ backgroundImage: 'url(' + minioUrl + '/index_bg.png)' }"></view>
  253. <!-- header -->
  254. <view class="index-header-wrapper">
  255. <image :src="minioUrl + '/logo.png'" mode="aspectFill" class="logo" />
  256. <view class="header-right-wrap">
  257. <view class="top-title-box">
  258. <HySelect v-model="selectedValue" @change="handleParkChange" />
  259. </view>
  260. <image class="star-img" :src="minioUrl + '/star.png'" mode="aspectFill" />
  261. <view class="bottom-box">
  262. <!-- 天气 -->
  263. <iframe
  264. scrolling="no"
  265. src="https://widget.tianqiapi.com/?style=tv&skin=cucumber&color=333"
  266. frameborder="0"
  267. width="130"
  268. height="25"
  269. allowtransparency="true"
  270. ></iframe>
  271. <!-- 营业状态 -->
  272. <view class="bottom-tag-item">正常营业</view>
  273. </view>
  274. </view>
  275. </view>
  276. <!-- 轮播图 -->
  277. <u-swiper :height="306" :list="list"></u-swiper>
  278. <!-- 金刚区 -->
  279. <view class="index-nav-wrapper">
  280. <view class="nav-item" v-for="(item, index) in navList" :key="index" @click="navClick(item)">
  281. <view class="nav-image">
  282. <image :src="item.image" mode="aspectFill" :style="{ width: item.w, height: item.h }" />
  283. </view>
  284. <view class="nav-item-text">{{ item.text }}</view>
  285. </view>
  286. </view>
  287. <!-- 出行提示 -->
  288. <view class="index-tips-wrapper" @click="navigateToTips">
  289. <image class="tips-img" :src="minioUrl + '/icon_chuxing.png'" mode="scaleToFill" />
  290. <view class="tips-line"></view>
  291. <u-notice-bar
  292. mode="vertical"
  293. style="width: 100%"
  294. :list="noticeList"
  295. :volume-icon="false"
  296. type="none"
  297. padding="10rpx"
  298. font-size="25"
  299. color="#333"
  300. ></u-notice-bar>
  301. </view>
  302. <!-- 加油充电 -->
  303. <view class="index-tabs-wrapper">
  304. <u-tabs
  305. v-model="tabActive"
  306. :list="tabs"
  307. active-color="#333"
  308. :font-size="31"
  309. :height="60"
  310. :gutter="20"
  311. :bar-style="{
  312. width: '30rpx',
  313. height: '6rpx',
  314. backgroundImage: 'linear-gradient(90deg, #0f91f8 0%, #32a9c8 68%, #54c197 100%), linear-gradient(#6c85fc, #6c85fc)',
  315. backgroundBlendMode: 'normal, normal',
  316. borderRadius: '2rpx'
  317. }"
  318. ></u-tabs>
  319. <template v-if="tabActive === 0">
  320. <view class="tab-station-wrap" v-if="listOli.length > 0">
  321. <HyStation v-for="(item, index) in listOli" :key="index" :item="item"></HyStation>
  322. </view>
  323. <view class="no-data-wrap" v-else>
  324. <u-empty />
  325. </view>
  326. </template>
  327. <template v-if="tabActive === 1">
  328. <view class="tab-station-wrap column" v-if="powerInfo?.fastChargeTotal > 0">
  329. <HyCharge
  330. title="快充"
  331. :freeNum="powerInfo?.fastChargeFree"
  332. :totalNum="powerInfo?.fastChargeTotal"
  333. :status="powerInfo?.fastChargeStatus"
  334. />
  335. <HyCharge
  336. title="慢充"
  337. :freeNum="powerInfo?.slowChargeFree"
  338. :totalNum="powerInfo?.slowChargeTotal"
  339. :status="powerInfo?.slowChargeStatus"
  340. />
  341. </view>
  342. <view class="no-data-wrap" v-else>
  343. <u-empty />
  344. </view>
  345. </template>
  346. </view>
  347. <!-- 服务设施 -->
  348. <HyCard title="服务设施" :marginBottom="24">
  349. <view class="index-service-wrapper" v-if="facilityList.length > 0">
  350. <HyService v-for="(item, index) in facilityList" :key="index" :item="item"></HyService>
  351. </view>
  352. <view class="no-data-wrap" v-else>
  353. <u-empty text="暂无服务设施数据" />
  354. </view>
  355. </HyCard>
  356. <!-- 人气优选商家 -->
  357. <HyCard title="人气优选商家" rightText="更多商家" isShowRight :marginBottom="24" @clickRight="navigateToShop">
  358. <view class="index-shop-wrapper" v-if="shopList.length > 0">
  359. <view class="shop-item" v-for="(item, index) in shopList" :key="index" @click="navigateToShopDetail(item.id)">
  360. <view class="img-wrap">
  361. <image :src="pathPre + item.content.image" mode="aspectFill" />
  362. </view>
  363. <view class="item-text u-line-1">{{ item.title }}</view>
  364. </view>
  365. </view>
  366. <view class="no-data-wrap" v-else>
  367. <u-empty text="暂无商家数据" />
  368. </view>
  369. </HyCard>
  370. <!-- 附近景点 -->
  371. <HyCard title="附近景点" isBg :bgImg="minioUrl + '/index_spot_bg.png'">
  372. <view class="index-spot-wrapper" v-if="scenicList.length > 0">
  373. <view class="spot-item" v-for="(item, index) in scenicList" :key="index" @click="navigateToSpot(item.id)">
  374. <view class="spot-img-wrap">
  375. <image :src="pathPre + item.content.image" mode="aspectFill" />
  376. </view>
  377. <view class="spot-right-wrap">
  378. <view class="right-header">
  379. <view class="title">{{ item.title }}</view>
  380. <view class="price">{{ item.content.isFree === 1 ? '免费' : item.content.price + '元' }}</view>
  381. </view>
  382. <view class="right-tag-box">
  383. <view class="s-tag-green" v-for="(tag, index) in item.content.tags" :key="index">{{ tag }}</view>
  384. </view>
  385. <view class="right-location-box">
  386. <view class="left">
  387. <image class="icon-address" :src="minioUrl + '/icon_address.png'" mode="aspectFill" />
  388. <view class="address-text-wrap"
  389. >距您<text>{{ item.content.distance }}</text
  390. >公里,驾车预计<text>{{ item.content.driveTime }}</text
  391. >分钟</view
  392. >
  393. </view>
  394. <view class="right-go-icon" @click.stop="goToNavigation(item.content.longitude, item.content.latitude, item.title)">
  395. <image :src="minioUrl + '/icon_go.png'" mode="aspectFill" />
  396. </view>
  397. </view>
  398. </view>
  399. </view>
  400. </view>
  401. <view class="no-data-wrap" v-else>
  402. <u-empty text="暂无景点数据" />
  403. </view>
  404. </HyCard>
  405. <!-- 一键救援 -->
  406. <HyPopup v-model="isRescueShow" width="700rpx" showClose>
  407. <view class="popup-content-wrapper">
  408. <view class="popup-content-item" @click="callPhone('96659')">
  409. <view class="p-item-left">
  410. <view class="left-title">车辆救援</view>
  411. <view class="left-sub-title">山东高速集团出行服务热线</view>
  412. </view>
  413. <view class="p-item-right">
  414. <view class="mobile">96659</view>
  415. <view class="icon-box">
  416. <u-icon name="phone-fill" color="#fff" size="24"></u-icon>
  417. </view>
  418. </view>
  419. </view>
  420. <view class="popup-content-item" @click="callPhone('12122')">
  421. <view class="p-item-left">
  422. <view class="left-title">事故报警</view>
  423. <view class="left-sub-title">山东高速交警报警热线</view>
  424. </view>
  425. <view class="p-item-right">
  426. <view class="mobile">12122</view>
  427. <view class="icon-box">
  428. <u-icon name="phone-fill" color="#fff" size="24"></u-icon>
  429. </view>
  430. </view>
  431. </view>
  432. </view>
  433. </HyPopup>
  434. <!-- 失物招领 -->
  435. <HyPopup v-model="isLostFoundShow" width="700rpx" showClose>
  436. <view class="popup-content-wrapper">
  437. <view class="popup-content-item column" @click="callPhone('0532-8889999')">
  438. <view class="column-title">失物招领</view>
  439. <view class="column-mobile">0532-8889999</view>
  440. <view class="icon-box">
  441. <u-icon name="phone-fill" color="#fff" size="24"></u-icon>
  442. </view>
  443. </view>
  444. </view>
  445. </HyPopup>
  446. </view>
  447. </mescroll-body>
  448. </template>
  449. <style lang="scss" scoped>
  450. .no-data-wrap {
  451. width: 100%;
  452. height: 400rpx;
  453. display: flex;
  454. align-items: center;
  455. justify-content: center;
  456. box-sizing: border-box;
  457. }
  458. .popup-content-wrapper {
  459. height: 330rpx;
  460. background-color: #fff;
  461. border-radius: 14rpx;
  462. .popup-content-item {
  463. width: 100%;
  464. display: flex;
  465. align-items: center;
  466. justify-content: space-between;
  467. box-sizing: border-box;
  468. padding: 48rpx 48rpx 24rpx 48rpx;
  469. &.column {
  470. flex-direction: column;
  471. justify-content: center;
  472. .column-title {
  473. font-size: 28rpx;
  474. color: #607f2f;
  475. }
  476. .column-mobile {
  477. font-size: 42rpx;
  478. color: #333;
  479. font-weight: 600;
  480. margin: 40rpx 0;
  481. }
  482. .icon-box {
  483. width: 48rpx;
  484. height: 48rpx;
  485. background-color: #247d54;
  486. display: flex;
  487. align-items: center;
  488. justify-content: center;
  489. border-radius: 50%;
  490. margin-left: 16rpx;
  491. }
  492. }
  493. .p-item-left {
  494. display: flex;
  495. flex-direction: column;
  496. .left-title {
  497. font-size: 28rpx;
  498. color: #607f2f;
  499. }
  500. .left-sub-title {
  501. font-size: 24rpx;
  502. color: #999;
  503. margin-top: 8rpx;
  504. }
  505. }
  506. .p-item-right {
  507. display: flex;
  508. align-items: center;
  509. .mobile {
  510. font-size: 42rpx;
  511. color: #333;
  512. font-weight: 600;
  513. }
  514. .icon-box {
  515. width: 48rpx;
  516. height: 48rpx;
  517. background-color: #247d54;
  518. display: flex;
  519. align-items: center;
  520. justify-content: center;
  521. border-radius: 50%;
  522. margin-left: 16rpx;
  523. }
  524. }
  525. }
  526. }
  527. :deep(.mescroll-upwarp) {
  528. padding-top: 0;
  529. }
  530. .index-container {
  531. width: 100%;
  532. min-height: 100dvh;
  533. position: relative;
  534. box-sizing: border-box;
  535. padding: 24rpx;
  536. background-color: #f6f7fb;
  537. .header-bg {
  538. width: 100%;
  539. height: 494rpx;
  540. background-position: center center;
  541. background-repeat: no-repeat;
  542. background-size: 100% 494rpx;
  543. position: absolute;
  544. top: 0;
  545. left: 0;
  546. z-index: 1;
  547. }
  548. .index-header-wrapper {
  549. display: flex;
  550. align-items: center;
  551. box-sizing: border-box;
  552. padding-left: 33rpx;
  553. position: relative;
  554. z-index: 2;
  555. margin-bottom: 24rpx;
  556. .logo {
  557. width: 105rpx;
  558. height: 92rpx;
  559. }
  560. .header-right-wrap {
  561. display: flex;
  562. flex-direction: column;
  563. margin-left: 24rpx;
  564. .top-title-box {
  565. display: flex;
  566. align-items: center;
  567. .title-text {
  568. font-size: 30rpx;
  569. color: #3b3c3b;
  570. font-weight: 600;
  571. }
  572. image {
  573. width: 13rpx;
  574. height: 10rpx;
  575. margin-left: 8rpx;
  576. }
  577. }
  578. .star-img {
  579. width: 146rpx;
  580. height: 27rpx;
  581. }
  582. .bottom-box {
  583. display: flex;
  584. align-items: center;
  585. margin-top: 10rpx;
  586. .bottom-tag-item {
  587. font-size: 17rpx;
  588. color: #fff;
  589. box-sizing: border-box;
  590. padding: 0 12rpx;
  591. background-color: #3bb0b9;
  592. border-radius: 8rpx;
  593. line-height: 40rpx;
  594. margin-top: -15rpx;
  595. }
  596. }
  597. }
  598. }
  599. :deep(.u-swiper-wrap) {
  600. position: relative;
  601. z-index: 1;
  602. }
  603. .index-nav-wrapper {
  604. display: flex;
  605. align-items: center;
  606. flex-wrap: wrap;
  607. justify-content: space-around;
  608. margin-top: 40rpx;
  609. .nav-item {
  610. display: flex;
  611. flex-direction: column;
  612. align-items: center;
  613. width: 20%;
  614. .nav-image {
  615. width: 76rpx;
  616. height: 76rpx;
  617. display: flex;
  618. align-items: center;
  619. justify-content: center;
  620. margin-bottom: 14rpx;
  621. }
  622. &:nth-child(-n + 5) {
  623. margin-bottom: 50rpx;
  624. }
  625. }
  626. }
  627. .index-tips-wrapper {
  628. width: 100%;
  629. height: 84rpx;
  630. border-radius: 14rpx;
  631. background-color: #fff;
  632. margin: 24rpx 0;
  633. box-sizing: border-box;
  634. padding: 0 30rpx;
  635. display: flex;
  636. align-items: center;
  637. .tips-img {
  638. width: 53rpx;
  639. height: 48rpx;
  640. }
  641. .tips-line {
  642. width: 4rpx;
  643. height: 34rpx;
  644. background-color: #3866ae;
  645. margin: -1rpx 0 0 24rpx;
  646. }
  647. .tips-content {
  648. font-size: 25rpx;
  649. color: #333;
  650. font-weight: 500;
  651. line-height: 40rpx;
  652. }
  653. }
  654. .index-tabs-wrapper {
  655. width: 100%;
  656. background-color: #fff;
  657. border-radius: 14rpx;
  658. box-sizing: border-box;
  659. padding: 22rpx;
  660. margin-bottom: 24rpx;
  661. .tab-station-wrap {
  662. display: flex;
  663. align-items: center;
  664. justify-content: space-around;
  665. margin-top: 24rpx;
  666. &.column {
  667. flex-direction: column;
  668. }
  669. }
  670. }
  671. .index-service-wrapper {
  672. margin-top: 24rpx;
  673. display: flex;
  674. flex-wrap: wrap;
  675. justify-content: space-between;
  676. :deep(.service-item-wrapper) {
  677. margin-bottom: 20rpx;
  678. &:nth-child(5) {
  679. margin-bottom: 0;
  680. }
  681. &:nth-child(6) {
  682. margin-bottom: 0;
  683. }
  684. }
  685. }
  686. .index-shop-wrapper {
  687. margin-top: 26rpx;
  688. display: flex;
  689. align-items: center;
  690. // justify-content: space-between;
  691. .shop-item {
  692. display: flex;
  693. flex-direction: column;
  694. margin-right: 28rpx;
  695. &:last-child {
  696. margin-right: 0;
  697. }
  698. .img-wrap {
  699. width: 104rpx;
  700. height: 104rpx;
  701. border-radius: 8rpx;
  702. background-color: #f0f6ff;
  703. image {
  704. width: 104rpx;
  705. height: 104rpx;
  706. border-radius: 8rpx;
  707. }
  708. }
  709. .item-text {
  710. width: 100rpx;
  711. text-align: center;
  712. margin-top: 12rpx;
  713. font-size: 24rpx;
  714. }
  715. }
  716. }
  717. .index-spot-wrapper {
  718. margin-top: 24rpx;
  719. .spot-item {
  720. display: flex;
  721. align-items: center;
  722. margin-bottom: 40rpx;
  723. &:last-child {
  724. margin-bottom: 0;
  725. }
  726. .spot-img-wrap {
  727. width: 196rpx;
  728. height: 151rpx;
  729. background-color: #f6f7fb;
  730. border-radius: 8rpx;
  731. image {
  732. width: 196rpx;
  733. height: 151rpx;
  734. border-radius: 8rpx;
  735. }
  736. }
  737. .spot-right-wrap {
  738. width: 100%;
  739. flex: 1;
  740. margin-left: 28rpx;
  741. .right-header {
  742. display: flex;
  743. align-items: center;
  744. justify-content: space-between;
  745. .title {
  746. font-size: 28rpx;
  747. color: #333;
  748. font-weight: 600;
  749. }
  750. .price {
  751. font-size: 21rpx;
  752. color: #fc9b0d;
  753. }
  754. }
  755. .right-tag-box {
  756. display: flex;
  757. align-items: center;
  758. flex-wrap: wrap;
  759. margin-top: 6rpx;
  760. .s-tag-green {
  761. width: 125rpx;
  762. height: 32rpx;
  763. background-color: #e2f3e4;
  764. border-radius: 16rpx;
  765. display: flex;
  766. align-items: center;
  767. justify-content: center;
  768. font-size: 21rpx;
  769. color: #239450;
  770. margin-right: 16rpx;
  771. margin-bottom: 10rpx;
  772. }
  773. }
  774. .right-location-box {
  775. margin-top: 8rpx;
  776. display: flex;
  777. align-items: center;
  778. justify-content: space-between;
  779. .left {
  780. display: flex;
  781. align-items: center;
  782. .icon-address {
  783. width: 18rpx;
  784. height: 22rpx;
  785. }
  786. .address-text-wrap {
  787. font-size: 21rpx;
  788. color: #c3c3c3;
  789. margin-left: 8rpx;
  790. text {
  791. color: #fc9904;
  792. }
  793. }
  794. }
  795. .right-go-icon {
  796. width: 40rpx;
  797. height: 40rpx;
  798. image {
  799. width: 40rpx;
  800. height: 40rpx;
  801. }
  802. }
  803. }
  804. }
  805. }
  806. }
  807. }
  808. </style>