checkInRoute.vue 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821
  1. <template>
  2. <page-layout>
  3. <nav-bar title="逛展打卡路线" @init="onInitNavbar"></nav-bar>
  4. <scroll-view id="scrollContainer" scroll-with-animation="true" :scroll-top="scroll_top" :scroll-y="true"
  5. style="height: 100vh" :scroll-into-view="scrollIntoViewId">
  6. <view class="outter">
  7. <view class="body">
  8. <view class="theme-title">
  9. <text class="title">逛展打卡路线</text>
  10. <image mode="aspectFit" class="title-bg"
  11. src="https://www.productronicachina.com.cn/resources/files/0221/67b7dd27b30b7/标题星星.png"></image>
  12. </view>
  13. <view class="pagination">
  14. <view class="page-change">
  15. <view @click="current_page=true" :class="['page-item',current_page?'active':'']">活动介绍</view>
  16. <view @click="current_page=false" :class="['page-item',current_page?'':'active']">活动规则</view>
  17. </view>
  18. <view class="page">
  19. <view v-show="current_page" class="page-item">
  20. <mp-html :content="routeInfoData.description"></mp-html>
  21. </view>
  22. <view v-show="!current_page" class="page-item">
  23. <view style="margin-bottom: 24rpx;">2025慕尼黑上海电子展展会现场将设有9条热门路线。观众可参与打卡调整。
  24. <text style="font-weight: bold;color: #E57519;">
  25. 打卡满任意2条,5条,8条分别获对应礼品。满9条路线完成终极挑战,除获得对应礼品以外,更有机会参与抽奖,赢取幸运大奖。
  26. </text>
  27. </view>
  28. <view style="margin-bottom: 16rpx;">
  29. <text style="font-weight: bold;">活动时间:</text>
  30. 2025年3月26日-3月28日
  31. </view>
  32. <view style="margin-bottom: 16rpx;">
  33. <text style="font-weight: bold;">参与人员:</text>
  34. 2025慕尼黑上海电子生产设备展现场观众
  35. </view>
  36. <view style="margin-bottom: 24rpx;">
  37. <text style="font-weight: bold;">奖品兑换区:</text>
  38. 展会现场礼品发放处【展位号待定】
  39. </view>
  40. <view style="margin-bottom: 16rpx;">① 展会期间,每人可领取完成最高线路的对应奖品,每人仅有一次兑奖机会。
  41. </view>
  42. <view style="margin-bottom: 16rpx;">② 礼品数量有限,仅限展会期间领取,先到先得,一旦赠完即止。</view>
  43. <view style="margin-bottom: 16rpx;">③
  44. 【我的奖品】页面可了解获奖详情。点击【可领取奖品】至展会现场礼品发放处【展位号待定】进行奖品核销与兑换。
  45. </view>
  46. <view>④ 满9条路线的观众可将名片放置抽奖箱,获奖结果将于展后公布。</view>
  47. </view>
  48. <view class="light" :style="{transform:current_page?'translateX(-100%)':'translateX(100%)'}"></view>
  49. </view>
  50. </view>
  51. <van-collapse custom-class="check_list" :border="false" v-model="activeNames" @change="onChange">
  52. <van-collapse-item :custom-class="activeNames.includes(r_index) ? 'expand_item' : ''" :border="false"
  53. class="router-item" v-for="(route,r_index) in routeInfoData.routes" :key="r_index"
  54. :name="r_index">
  55. <view slot="title" class="item-head" :id="'module' + r_index">
  56. <view class="route-name">{{ route.name }}</view>
  57. <view class="product-type">
  58. <view class="text">{{ route.description }}</view>
  59. <view class="button" @click.stop="showOverlayEvent(route.map_url)">
  60. {{ route.map_btn_name }}
  61. <text class="iconfont icon-Search"></text>
  62. </view>
  63. </view>
  64. <view class="progress">
  65. <view class="text" v-if="getProcess(route.exhibitors,true)">
  66. 打卡已完成{{ getProcess(route.exhibitors, false) }}
  67. </view>
  68. <view class="text disable_text" v-else>未开始{{ getProcess(route.exhibitors, false) }}</view>
  69. <view class="inner">
  70. <view :style="{width:getProcess(route.exhibitors,true)*100+'%'}" class="inner-process">
  71. <view class="text" :style="{width:'calc(100% / '+getProcess(route.exhibitors,true)+')'}">
  72. 打卡已完成{{ getProcess(route.exhibitors, false) }}
  73. </view>
  74. </view>
  75. </view>
  76. </view>
  77. </view>
  78. <view class="iconfont icon-Down" @click="onChangeVanItem(r_index)"></view>
  79. <view class="item-body">
  80. <view v-for="(exhibit,e_index) in route.exhibitors"
  81. :id="'module' + r_index + '_' + e_index"
  82. :class="['exhibit-item',exhibit.checkin_status === 1 ?'checked':'']">
  83. <image mode="aspectFit" class="logo" :src="exhibit.logo"></image>
  84. <view class="name">{{ exhibit.name_zh_cn }}</view>
  85. <view class="code">
  86. <text class="text">展位号:</text>
  87. <text class="code-inner">{{ exhibit.hall_booth_no }}</text>
  88. </view>
  89. <view class="button" @click="scanCodeEvent(route,r_index,e_index,exhibit)">
  90. <text :class="['iconfont',exhibit.checkin_status === 1 ?'icon-Check':'icon-saoyisao_1']"></text>
  91. <text class="text">打卡</text>
  92. </view>
  93. </view>
  94. </view>
  95. </van-collapse-item>
  96. </van-collapse>
  97. <view class="side-button">
  98. <view @click="gotoPrizes()" class="button">
  99. <text style="font-size: 50rpx;" class="iconfont icon-jiangpin"></text>
  100. <text class="title">我的奖品</text>
  101. </view>
  102. <view @click="gotoRule()" class="button">
  103. <text class="iconfont icon-xiaochengxu-canguandengjiicon"></text>
  104. <text class="title">活动规则</text>
  105. </view>
  106. <view class="button">
  107. <button open-type="share"></button>
  108. <text style="font-size: 56rpx;" class="iconfont icon-zhuanfa"></text>
  109. <text class="title">分享</text>
  110. </view>
  111. </view>
  112. </view>
  113. </view>
  114. </scroll-view>
  115. <van-overlay :show="mapShow">
  116. <view class="overlay_wrapper">
  117. <image :src="mapUrl" style="width: 90%;" mode="widthFix"></image>
  118. <view class="iconfont icon-Cancel-copy" @click="hideOverlay"></view>
  119. </view>
  120. </van-overlay>
  121. <van-dialog id="van-dialog"/>
  122. </page-layout>
  123. </template>
  124. <script>
  125. import PageLayout from "@/components/layout/page-layout";
  126. import NavBar from "@/components/layout/nav-bar";
  127. import UScrollView from "@/components/common/u-scroll-view";
  128. import {getRouteList, qrcodeDecode} from "@/api/checkIn";
  129. import Dialog from "@/wxcomponents/vant/dialog/dialog";
  130. import VanOverlay from '@/wxcomponents/vant/overlay/index'
  131. import VanCollapse from '@/wxcomponents/vant/collapse/index'
  132. import VanCollapseItem from '@/wxcomponents/vant/collapse-item/index'
  133. import Toast from '@/wxcomponents/vant/toast/toast';
  134. import store from "@/store";
  135. export default {
  136. components: {
  137. PageLayout,
  138. NavBar,
  139. UScrollView,
  140. VanOverlay,
  141. VanCollapse,
  142. VanCollapseItem
  143. },
  144. data() {
  145. return {
  146. scrollIntoViewId: '',
  147. scene: '',
  148. activeNames: [0],
  149. mapShow: false,
  150. mapUrl: '',
  151. current_page: true,
  152. current_unfold: -1,
  153. scroll_top: 0,
  154. is_receipts: null,
  155. routeInfoData: []
  156. };
  157. },
  158. mounted() {
  159. this.getRouteListEvent()
  160. },
  161. methods: {
  162. initSceneEvent() {
  163. //微信扫码进入
  164. if (this.scene) {
  165. const sceneParams = this.getSceneParamsEvent(this.scene)
  166. console.log(sceneParams)
  167. this.getRouteListEvent(() => {
  168. let item = {
  169. index: 0,
  170. child_index: 0
  171. }
  172. this.routeInfoData.routes.forEach((route_item, route_index) => {
  173. if (route_item.exhibitors && route_item.exhibitors.length > 0) {
  174. route_item.exhibitors.forEach((exhibitors_item, exhibitors_index) => {
  175. if (exhibitors_item.exhibitor_id === sceneParams.a) {
  176. item.index = route_index
  177. item.child_index = exhibitors_index
  178. }
  179. })
  180. }
  181. })
  182. this.qrcodeDecodeEvent(this.scene, async () => {
  183. /* */
  184. this.scrollIntoViewId = '#module' + item.index;
  185. if (!(this.activeNames.includes(item.index))) {
  186. this.activeNames.push(item.index)
  187. }
  188. setTimeout(async () => {
  189. // this.scrollIntoViewId = '#module' + item.index + '_' + item.child_index;
  190. }, 500)
  191. this.$set(this.routeInfoData.routes[item.index].exhibitors[item.child_index], 'checkin_status', 1)
  192. })
  193. })
  194. }
  195. },
  196. onChangeVanItem(val) {
  197. let index = this.activeNames.indexOf(val); // 查找数组中元素1的索引
  198. if (index !== -1) {
  199. // 如果找到了元素1,则使用splice方法删除它
  200. this.activeNames.splice(index, 1);
  201. } else {
  202. // 如果没有找到元素1,则将其添加到数组的末尾
  203. this.activeNames.push(val);
  204. }
  205. }
  206. ,
  207. onChange(event) {
  208. this.activeNames = event.detail
  209. this.$forceUpdate()
  210. }
  211. ,
  212. hideOverlay() {
  213. this.mapShow = false
  214. this.mapUrl = ''
  215. }
  216. ,
  217. showOverlayEvent(map_url) {
  218. this.mapShow = true
  219. this.mapUrl = map_url
  220. }
  221. ,
  222. getSceneParamsEvent(finalStr) {
  223. const {a, t} = finalStr.split('&').reduce((obj, pair) => {
  224. const [key, value] = pair.split('=');
  225. obj[key] = Number(value) || null; // 自动转数字
  226. return obj;
  227. }, {});
  228. return {a: a, t: t}
  229. }
  230. ,
  231. scanCodeEvent(route, r_index, e_index, exhibit) {
  232. if (exhibit.checkin_status === 1) {
  233. return false
  234. }
  235. if (this.is_receipts > 0) {
  236. Dialog.alert({
  237. message: '已经确认领取奖品,不能继续打卡',
  238. }).then(() => {
  239. });
  240. return false
  241. }
  242. let that = this
  243. wx.scanCode({
  244. onlyFromCamera: true,
  245. success(res) {
  246. console.log(res, 'qrcode_res')
  247. let scene = res.path.split('scene=')
  248. const decoded = decodeURIComponent(scene[1])
  249. .replace(/\%/g, '%25'); // 防止二次解码丢失%
  250. const finalStr = decodeURIComponent(decoded);
  251. const params = that.getSceneParamsEvent(finalStr)
  252. console.log(finalStr)
  253. if (that.routeInfoData.routes[r_index].exhibitors[e_index].exhibitor_id !== params.a) {
  254. Dialog.alert({
  255. message: '该展商和打卡二维码数据不一致',
  256. }).then(() => {
  257. });
  258. } else {
  259. that.qrcodeDecodeEvent(finalStr, () => {
  260. that.$set(that.routeInfoData.routes[r_index].exhibitors[e_index], 'checkin_status', 1)
  261. })
  262. }
  263. }
  264. })
  265. }
  266. ,
  267. qrcodeDecodeEvent(scene, callback) {
  268. qrcodeDecode({scene: scene}).then(res => {
  269. if (res.code === 0) {
  270. Toast.success('打卡成功');
  271. if (callback) {
  272. callback()
  273. }
  274. }
  275. })
  276. }
  277. ,
  278. getRouteListEvent(callback) {
  279. getRouteList().then(res => {
  280. this.is_receipts = res.data.is_receipts
  281. this.routeInfoData = res.data
  282. if (callback) {
  283. callback()
  284. }
  285. })
  286. }
  287. ,
  288. navigateBack() {
  289. uni.navigateBack(1)
  290. }
  291. ,
  292. gotoRule() {
  293. this.current_page = false
  294. this.scroll_top = 1
  295. this.$nextTick(function () {
  296. this.scroll_top = 0
  297. });
  298. }
  299. ,
  300. gotoPrizes() {
  301. uni.navigateTo({
  302. url: '/pages/user/award'
  303. })
  304. }
  305. ,
  306. onShareAppMessage() {
  307. return {
  308. title: '逛展会,领福利!',
  309. path: '/pages/checkIn/index',
  310. imageUrl: 'https://www.productronicachina.com.cn/resources/files/0221/67b7e5190bd22/share.png'
  311. }
  312. }
  313. ,
  314. /**
  315. * 返回完成进度
  316. * @param {Object} item exhibitors_list内的数据
  317. * @param {Boolean} per 是否返回百分比 true:返回0~1之间的小数;false:返回n/n格式分数。
  318. */
  319. getProcess(item, per) {
  320. if (!item) {
  321. return 0
  322. }
  323. let length = item.length
  324. let process = 0
  325. item.forEach((value, index) => {
  326. if (value.checkin_status)
  327. process++
  328. })
  329. if (per) {
  330. return process / length
  331. } else {
  332. return process + '/' + length
  333. }
  334. }
  335. },
  336. onLoad(option) {
  337. console.log(option, 'option')
  338. if (!store.getters.user) {
  339. this.navigateTo('/pages/user/login?redirect=' + encodeURIComponent('/pages/checkIn/checkInRoute?scene=' + option.scene))
  340. return false
  341. }
  342. this.scene = decodeURIComponent(option.scene || '');
  343. console.log(this.scene, 'option_this.scene')
  344. this.initSceneEvent()
  345. if (option.rule === 'true')
  346. this.gotoRule()
  347. }
  348. ,
  349. }
  350. </script>
  351. <style lang="scss">
  352. ::v-deep {
  353. .van-hairline--top, .item-index--van-hairline--top {
  354. border: none;
  355. //background-color: unset;
  356. box-shadow: unset;
  357. .item-index--van-cell {
  358. border: none;
  359. //background-color: unset;
  360. box-shadow: unset;
  361. }
  362. &:after {
  363. content: unset;
  364. }
  365. &:before {
  366. content: unset;
  367. }
  368. }
  369. }
  370. </style>
  371. <style lang="scss" scoped>
  372. ::v-deep {
  373. .van-cell, .van-collapse-item__content {
  374. border-radius: 20rpx;
  375. }
  376. .van-cell {
  377. padding-top: 66rpx;
  378. }
  379. .van-cell__right-icon-wrap {
  380. display: none;
  381. }
  382. .van-collapse-item {
  383. position: relative;
  384. padding-bottom: 48rpx;
  385. &.expand_item {
  386. .icon-Down {
  387. transform: rotate(180deg);
  388. }
  389. }
  390. .icon-Down {
  391. position: absolute;
  392. left: 0;
  393. right: 0;
  394. bottom: 0;
  395. margin: 0 auto;
  396. text-align: center;
  397. }
  398. }
  399. }
  400. .overlay_wrapper {
  401. display: flex;
  402. justify-content: center;
  403. align-items: center;
  404. width: 100%;
  405. height: 100%;
  406. position: relative;
  407. .iconfont {
  408. position: absolute;
  409. right: 30rpx;
  410. top: 250rpx;
  411. color: #ffffff;
  412. font-size: 40rpx;
  413. }
  414. }
  415. .outter {
  416. height: 100%;
  417. position: relative;
  418. .head_title {
  419. width: 100%;
  420. background: linear-gradient(270deg, #332968 9%, #435797 44%, #382E73 92%), rgba(0, 0, 0, 0.2);
  421. padding-bottom: 15px;
  422. display: flex;
  423. align-items: flex-end;
  424. padding-left: 28rpx;
  425. .title {
  426. display: flex;
  427. align-items: center;
  428. color: white;
  429. font-size: 32rpx;
  430. .iconfont {
  431. font-size: 36rpx;
  432. margin-right: 8rpx;
  433. }
  434. }
  435. }
  436. .body {
  437. overflow: hidden;
  438. overflow-y: auto;
  439. background: linear-gradient(180deg, #015A92 0%, #56A3E9 24%, #106591 98%);
  440. .router-item {
  441. position: relative;
  442. //padding: 60rpx 37rpx;
  443. border-radius: 20rpx;
  444. margin: 0 30rpx 56rpx;
  445. background-color: white;
  446. display: grid;
  447. transition-duration: 300ms;
  448. //overflow: hidden;
  449. &.fold {
  450. .item-body {
  451. padding-top: 0;
  452. }
  453. }
  454. .item-body {
  455. transition-duration: 300ms;
  456. padding-top: 40rpx;
  457. display: grid;
  458. grid-template-columns: 1fr 1fr 1fr;
  459. grid-gap: 70rpx 30rpx;
  460. //overflow: hidden;
  461. color: #333333;
  462. .exhibit-item {
  463. position: relative;
  464. background-color: white;
  465. box-shadow: 0 4rpx 20rpx 0 rgba(0, 0, 0, 0.15);
  466. border-radius: 10rpx;
  467. padding: 60rpx 16rpx 16rpx;
  468. transition-duration: 300ms;
  469. &.checked {
  470. background-color: #4085C7;
  471. color: white;
  472. .code {
  473. .text, .code-inner {
  474. color: white;
  475. }
  476. }
  477. .button {
  478. width: 38rpx;
  479. grid-gap: 0;
  480. border: 2rpx solid white;
  481. background-color: white;
  482. color: #4085C7;
  483. .text {
  484. width: 0;
  485. height: 0;
  486. }
  487. .iconfont {
  488. font-size: 30rpx;
  489. }
  490. }
  491. animation: checked 300ms;
  492. }
  493. @keyframes checked {
  494. 0% {
  495. transform: scale(1) rotate(0deg);
  496. }
  497. 50% {
  498. transform: scale(0.92) rotate(6deg);
  499. }
  500. 100% {
  501. transform: scale(1) rotate(0deg);
  502. }
  503. }
  504. .logo {
  505. background-color: white;
  506. position: absolute;
  507. left: 50%;
  508. transform: translate(-50%, -50%);
  509. top: 0;
  510. width: 76rpx;
  511. height: 76rpx;
  512. border: 1rpx solid #E1E1E1;
  513. border-radius: 6rpx;
  514. padding: 2rpx;
  515. }
  516. .name {
  517. font-size: 20rpx;
  518. font-weight: bold;
  519. margin-bottom: 10rpx;
  520. min-height: 60rpx;
  521. }
  522. .code {
  523. transition-duration: 300ms;
  524. margin-bottom: 10rpx;
  525. display: flex;
  526. align-items: center;
  527. .text {
  528. transition-duration: 300ms;
  529. color: #555555;
  530. font-size: 16rpx;
  531. }
  532. .code-inner {
  533. transition-duration: 300ms;
  534. color: #E57519;
  535. font-size: 24rpx;
  536. font-weight: bold;
  537. flex: 1;
  538. min-width: 1rpx;
  539. padding-left: 5rpx;
  540. }
  541. }
  542. .button {
  543. transition-duration: 300ms;
  544. margin: auto;
  545. width: 100%;
  546. height: 40rpx;
  547. font-size: 20rpx;
  548. border: 2rpx solid #D9D9D9;
  549. border-radius: 60rpx;
  550. display: flex;
  551. align-items: center;
  552. justify-content: center;
  553. grid-gap: 8rpx;
  554. .text {
  555. font-size: 20rpx;
  556. transition-duration: 300ms;
  557. overflow: hidden;
  558. margin-top: -4rpx;
  559. }
  560. .iconfont {
  561. transition-duration: 300ms;
  562. font-size: inherit;
  563. }
  564. }
  565. }
  566. }
  567. .item-head {
  568. .route-name {
  569. position: absolute;
  570. left: 30rpx;
  571. top: -16rpx;
  572. color: white;
  573. border: solid 6rpx white;
  574. background-color: #FF9A00;
  575. font-size: 30rpx;
  576. font-weight: bold;
  577. padding: 15rpx 30rpx;
  578. border-radius: 60rpx;
  579. width: fit-content;
  580. }
  581. .product-type {
  582. display: flex;
  583. justify-content: space-between;
  584. align-items: center;
  585. margin-top: 16rpx;
  586. .text {
  587. font-size: 32rpx;
  588. font-weight: bold;
  589. flex: 1;
  590. min-width: 1rpx;
  591. }
  592. .button {
  593. color: #4085C7;
  594. border: solid 3rpx #4085C7;
  595. border-radius: 60rpx;
  596. font-size: 20rpx;
  597. padding: 10rpx 20rpx;
  598. line-height: 1;
  599. .iconfont {
  600. font-size: inherit;
  601. margin-left: 6rpx;
  602. }
  603. }
  604. }
  605. .progress {
  606. position: relative;
  607. margin-top: 24rpx;
  608. height: 36rpx;
  609. width: 100%;
  610. background-color: #EBEBEB;
  611. border-radius: 18rpx;
  612. .inner {
  613. height: 100%;
  614. width: 100%;
  615. position: relative;
  616. .inner-process {
  617. transition-duration: 300ms;
  618. position: relative;
  619. overflow: hidden;
  620. height: 100%;
  621. width: 50%;
  622. background-color: #E57519;
  623. border-radius: 18rpx;
  624. .text {
  625. transition-duration: 300ms;
  626. color: white;
  627. }
  628. }
  629. }
  630. .text {
  631. position: absolute;
  632. width: 100%;
  633. height: 100%;
  634. left: 0;
  635. top: 0;
  636. color: #555555;
  637. font-size: 20rpx;
  638. line-height: 36rpx;
  639. text-align: center;
  640. /*&.disable_text {
  641. text-align: left;
  642. left: 24rpx;
  643. }*/
  644. }
  645. }
  646. }
  647. }
  648. .pagination {
  649. margin-bottom: 57rpx;
  650. .page {
  651. overflow: hidden;
  652. position: relative;
  653. background-color: white;
  654. padding: 40rpx 50rpx;
  655. border-radius: 20rpx;
  656. margin: 0 30rpx;
  657. .page-item {
  658. font-size: 24rpx;
  659. line-height: 1.6;
  660. }
  661. .light {
  662. transition-duration: 300ms;
  663. position: absolute;
  664. background: linear-gradient(75deg, #ffffff00, #ffffff 50%, #ffffff00 100%);
  665. width: 100%;
  666. height: 100%;
  667. left: 0;
  668. top: 0;
  669. }
  670. }
  671. .page-change {
  672. display: flex;
  673. justify-content: center;
  674. .page-item {
  675. transition-duration: 300ms;
  676. font-weight: bold;
  677. font-size: 24rpx;
  678. padding: 14rpx 40rpx;
  679. background: linear-gradient(#2D2B76 50%, #FF9A00 50%);
  680. background-position: 0 0;
  681. background-size: 100% 200%;
  682. color: #ffffff99;
  683. border-radius: 20rpx 20rpx 0 0;
  684. &.active {
  685. background-position: 0 100%;
  686. color: white;
  687. }
  688. }
  689. }
  690. }
  691. .theme-title {
  692. margin-top: 54rpx;
  693. margin-bottom: 32rpx;
  694. position: relative;
  695. height: 130rpx;
  696. display: flex;
  697. justify-content: center;
  698. align-items: center;
  699. .title {
  700. color: white;
  701. font-size: 55rpx;
  702. font-weight: bold;
  703. }
  704. .title-bg {
  705. position: absolute;
  706. left: 0;
  707. top: 0;
  708. height: 100%;
  709. }
  710. }
  711. }
  712. .side-button {
  713. position: fixed;
  714. right: 32rpx;
  715. bottom: 32rpx;
  716. display: flex;
  717. flex-direction: column;
  718. grid-gap: 17rpx;
  719. .button {
  720. background-color: white;
  721. width: 125rpx;
  722. height: 125rpx;
  723. border-radius: 50%;
  724. box-shadow: 0px 0px 20px 0px rgba(0, 0, 0, 0.25);
  725. display: flex;
  726. flex-direction: column;
  727. justify-content: center;
  728. align-items: center;
  729. grid-gap: 6rpx;
  730. padding-bottom: 6rpx;
  731. position: relative;
  732. button {
  733. width: 100%;
  734. height: 100%;
  735. opacity: 0;
  736. left: 0;
  737. top: 0;
  738. position: absolute;
  739. }
  740. .title {
  741. color: #94A3B8;
  742. font-size: 24rpx;
  743. }
  744. .iconfont {
  745. font-size: 60rpx;
  746. color: #016BF3;
  747. }
  748. }
  749. }
  750. }
  751. </style>