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

937 lines
24 KiB

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
1 month ago
2 months ago
1 month ago
1 month ago
2 months 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
1 month ago
2 months ago
1 month ago
1 month ago
1 month ago
2 months ago
2 months ago
1 month ago
2 months ago
2 months ago
2 months ago
1 month ago
2 months ago
1 month ago
1 month 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
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
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. <template>
  2. <view class="promotion-page">
  3. <!-- 顶部渐变导航栏 -->
  4. <view class="nav-bar" :style="{height: navBarTotalHeight + 'px', paddingTop: statusBarHeight + 'px'}">
  5. <view class="nav-bar-inner">
  6. <view class="back-icon" @tap="navigateBack">
  7. <uni-icons type="left" size="22" color="#222" />
  8. </view>
  9. <view class="nav-bar-title">爱简收·推客联盟</view>
  10. <view class="nav-bar-right">
  11. <uni-icons type="more-filled" size="22" color="#222" />
  12. </view>
  13. </view>
  14. </view>
  15. <!-- 打钩标签区 -->
  16. <view class="feature-tags" :style="{marginTop: navBarTotalHeight+statusBarHeight + 'px'}">
  17. <view class="tag" v-for="(t, i) in featureTags" :key="i">
  18. <text class="check"></text>
  19. <text class="text">{{t}}</text>
  20. </view>
  21. </view>
  22. <!-- 主内容区卡片悬浮覆盖打钩区 -->
  23. <view class="main-content">
  24. <!-- 用户卡片 -->
  25. <view class="user-card">
  26. <view class="user-info-row">
  27. <view class="avatar-box">
  28. <view class="avatar-frame">
  29. <image class="avatar-img" :src="userInfo.avatar" mode="aspectFill" />
  30. <view class="avatar-badge" :class="userTypeBadgeClass">{{ userTypeText }}</view>
  31. </view>
  32. </view>
  33. <view class="user-meta">
  34. <view class="nickname">{{userInfo.name}}</view>
  35. <view class="userid">ID: {{userInfo.intentioCode}}</view>
  36. </view>
  37. <view class="user-count">推广人数</view>
  38. </view>
  39. <view class="user-stats-row">
  40. <view class="stat-block">
  41. <view class="stat-label">可提现佣金()</view>
  42. <view class="stat-value main">{{userInfo.money}}</view>
  43. <button class="withdraw-btn" @click="goWithdraw">提现</button>
  44. </view>
  45. <view class="stat-divider"></view>
  46. <view class="stat-block">
  47. <view class="stat-label">累计提现()</view>
  48. <view class="stat-value">{{userInfo.integerPrice}}</view>
  49. <button class="record-btn" @click="goWithdrawRecord">提现记录</button>
  50. </view>
  51. </view>
  52. <view class="bottom-menu-row">
  53. <view class="menu-item" @tap="goProfitDetail">
  54. <view class="menu-icon red">
  55. <uni-icons type="wallet" size="32" color="#fff" />
  56. </view>
  57. <text class="menu-text">收益明细</text>
  58. </view>
  59. <view class="menu-item" @tap="goTeam">
  60. <view class="menu-icon blue">
  61. <uni-icons type="person" size="32" color="#fff" />
  62. </view>
  63. <text class="menu-text">我的团队</text>
  64. </view>
  65. </view>
  66. </view>
  67. <!-- 推广排行榜 -->
  68. <view class="rank-section">
  69. <view class="rank-title">推广排行榜</view>
  70. <view class="rank-list">
  71. <view class="rank-item" v-for="(item, idx) in rankList.slice(0, 5)" :key="idx">
  72. <view class="rank-icon">
  73. <image v-if="idx<3" :src="getRankIcon(idx+1)" class="crown" mode="aspectFit" />
  74. <image v-else :src="getRankIcon(idx+1)" class="num-icon" mode="aspectFit" />
  75. </view>
  76. <image class="rank-avatar" :src="item.headImage" mode="aspectFill" />
  77. <text class="rank-phone">{{item.nickName}}</text>
  78. <text class="rank-amount">¥{{item.price}}</text>
  79. </view>
  80. </view>
  81. </view>
  82. <!-- 权益说明表格 -->
  83. <view class="rights-section">
  84. <view class="rights-title">权益说明</view>
  85. <image :src="indexLvxingUrl" mode="widthFix" class="rights-image" />
  86. </view>
  87. <!-- 联系客服二维码 -->
  88. <view class="qrcode-section">
  89. <view class="qrcode-title">联系客服</view>
  90. <image class="qrcode-img" :src="qrcodeUrl" mode="aspectFit" @click="openQrcodeModal" />
  91. <text class="qrcode-modal-benefit">添加客服可以获取更多推广福利</text>
  92. </view>
  93. </view>
  94. <!-- 底部按钮区 -->
  95. <view class="bottom-btns">
  96. <button class="btn gray" @tap="goQrcode">我的二维码</button>
  97. <button class="btn green" @tap="goUpgrade" v-if="status== 3">立即升级推广官</button>
  98. <button class="btn gray" v-if="status==0" @tap="showProgressModal = true">查看申请进度</button>
  99. </view>
  100. <!-- 申请进度弹窗 -->
  101. <view v-if="showProgressModal" class="progress-modal-mask">
  102. <view class="progress-modal-box">
  103. <view class="progress-modal-title">联系运营商\n升级解锁更多权益</view>
  104. <view class="progress-modal-list">
  105. <view class="progress-modal-item" @tap="goToFaq">
  106. <text>在线客服</text>
  107. <uni-icons type="right" size="22" color="#bbb" />
  108. </view>
  109. <view class="progress-modal-item" @tap="goToFaq">
  110. <text>客服电话</text>
  111. <uni-icons type="right" size="22" color="#bbb" />
  112. </view>
  113. </view>
  114. <button class="progress-modal-btn" @tap="showProgressModal = false">我知道了</button>
  115. </view>
  116. </view>
  117. <!-- 客服二维码放大弹窗 -->
  118. <view v-if="showQrcodeModal" class="qrcode-modal-mask" @click="closeQrcodeModal">
  119. <view class="qrcode-modal-content" @click.stop>
  120. <view class="qrcode-modal-header">
  121. <text class="qrcode-modal-title">联系客服</text>
  122. <view class="qrcode-modal-close" @click="closeQrcodeModal">
  123. <uni-icons type="close" size="24" color="#999"></uni-icons>
  124. </view>
  125. </view>
  126. <view class="qrcode-modal-body">
  127. <image
  128. v-if="qrcodeUrl"
  129. :src="qrcodeUrl"
  130. mode="aspectFit"
  131. class="qrcode-modal-img"
  132. :show-menu-by-longpress="true"
  133. @longpress="onQrcodeLongPress"
  134. />
  135. <view v-else class="qrcode-placeholder">
  136. <text>二维码加载中...</text>
  137. </view>
  138. <text class="qrcode-modal-tip">长按识别二维码添加客服微信</text>
  139. <text class="qrcode-modal-benefit">添加客服可以获取更多推广福利</text>
  140. </view>
  141. </view>
  142. </view>
  143. </view>
  144. </template>
  145. <script>
  146. import pullRefreshMixin from '@/pages/mixins/pullRefreshMixin.js'
  147. export default {
  148. mixins: [pullRefreshMixin],
  149. data() {
  150. return {
  151. statusBarHeight: 0,
  152. navBarHeight: 44, // px
  153. navBarTotalHeight: 44, // px
  154. featureTags: ['收益高', '品类全', '到账快', '城市多'],
  155. userInfo: {
  156. avatar: '',
  157. name: '',
  158. id: '',
  159. type: '',
  160. balance: '',
  161. totalWithdraw: '',
  162. },
  163. tabActive: 0,
  164. rankList: [
  165. ],
  166. status: 0,
  167. showProgressModal: false,
  168. showQrcodeModal: false
  169. }
  170. },
  171. computed: {
  172. qrcodeUrl() {
  173. console.log(getApp().globalData.configData,'getApp().globalData.configData')
  174. const item = getApp().globalData.configData.find(i => i.keyName === 'kefu_code')
  175. return item ? item.keyContent : ''
  176. },
  177. indexLvxingUrl() {
  178. console.log(getApp().globalData.configData,'getApp().globalData.configData')
  179. const item = getApp().globalData.configData.find(i => i.keyName === 'index_lvxing')
  180. return item ? item.keyContent : ''
  181. },
  182. userTypeText() {
  183. return this.userInfo.isTuiTypeTitle || '用户'
  184. },
  185. userTypeBadgeClass() {
  186. switch (this.userInfo.isTuiTypeTitle) {
  187. case '推广达人':
  188. return 'avatar-badge-expert'
  189. case '推广大使':
  190. return 'avatar-badge-ambassador'
  191. default:
  192. return 'avatar-badge-user'
  193. }
  194. },
  195. },
  196. onLoad() {
  197. const sysInfo = uni.getSystemInfoSync()
  198. this.statusBarHeight = sysInfo.statusBarHeight
  199. this.navBarHeight = 44
  200. this.navBarTotalHeight = this.statusBarHeight + this.navBarHeight
  201. this.getUserInfoByToken()
  202. this.getRankList()
  203. this.getMyPromotionInfo()
  204. },
  205. onShow(){
  206. this.getMyPromotionInfo()
  207. },
  208. onPullDownRefresh() {
  209. this.getUserInfoByToken()
  210. uni.stopPullDownRefresh()
  211. },
  212. methods: {
  213. async onRefresh() {
  214. // 模拟刷新数据
  215. await new Promise(resolve => setTimeout(resolve, 1000))
  216. uni.stopPullRefresh()
  217. },
  218. navigateBack() {
  219. uni.navigateBack()
  220. },
  221. getRankIcon(idx) {
  222. return `/static/tui/${idx}.png`
  223. },
  224. goQrcode() {
  225. uni.navigateTo({ url: '/pages/subcomponent/promo-qrcode' })
  226. },
  227. goUpgrade() {
  228. uni.navigateTo({ url: '/pages/subcomponent/upgrad' })
  229. },
  230. getUserInfoByToken() {
  231. this.$api('getUserByToken', {}, (res) => {
  232. if (res && res.success && res.result) {
  233. this.userInfo.avatar = res.result.headImage || ''
  234. this.userInfo.name = res.result.nickName || ''
  235. this.userInfo.id = res.result.id || ''
  236. this.userInfo.intentioCode = res.result.intentioCode || ''
  237. this.userInfo.money = res.result.money || ''
  238. this.userInfo.integerPrice = res.result.integerPrice || ''
  239. this.userInfo.isTuiTypeTitle = res.result.isTuiTypeTitle ||''
  240. // 你可以根据实际接口补充type、balance、totalWithdraw等字段
  241. }
  242. })
  243. },
  244. goWithdrawRecord() {
  245. uni.navigateTo({ url: '/pages/subcomponent/promotion-withdraw-record' })
  246. },
  247. goWithdraw() {
  248. uni.navigateTo({ url: '/pages/subcomponent/withdraw?fromPromotion=true' })
  249. },
  250. goProfitDetail() {
  251. uni.navigateTo({ url: '/pages/subcomponent/promotion-profit-detail' })
  252. },
  253. goTeam() {
  254. uni.navigateTo({ url: '/pages/subcomponent/promotion-team' })
  255. },
  256. getRankList(){
  257. this.$api('getRankList', {}, (res) => {
  258. if (res && res.success && res.result) {
  259. this.rankList = res.result.records || []
  260. }
  261. })
  262. },
  263. getMyPromotionInfo(){
  264. this.$api('getMyPromotionInfo', {}, (res) => {
  265. if (res && res.success && res.result) {
  266. if (res.result.status == 0) {
  267. this.status = res.result.status
  268. console.log(this.status,'this.status')
  269. }
  270. }else{
  271. this.status = 3
  272. console.log(this.status,'this.status')
  273. }
  274. })
  275. },
  276. goToFaq() {
  277. uni.navigateTo({ url: '/pages/subcomponent/admin_faq' })
  278. },
  279. // 显示客服二维码弹窗
  280. openQrcodeModal() {
  281. this.showQrcodeModal = true;
  282. },
  283. // 关闭二维码弹窗
  284. closeQrcodeModal() {
  285. this.showQrcodeModal = false;
  286. },
  287. // 处理二维码长按事件
  288. onQrcodeLongPress() {
  289. console.log('长按二维码');
  290. // 在微信小程序中,show-menu-by-longpress="true" 会自动处理长按识别
  291. // 这里可以添加一些反馈提示
  292. uni.showToast({
  293. title: '长按识别二维码',
  294. icon: 'none',
  295. duration: 1500
  296. });
  297. }
  298. }
  299. }
  300. </script>
  301. <style lang="scss" scoped>
  302. .promotion-page {
  303. min-height: 100vh;
  304. background: linear-gradient(to right, #b2f08d 0%, #39e9d2 100%);
  305. padding-bottom: calc(env(safe-area-inset-bottom) + 120rpx);
  306. }
  307. .nav-bar {
  308. position: fixed;
  309. top: 0;
  310. left: 0;
  311. right: 0;
  312. z-index: 1000;
  313. width: 100vw;
  314. background: linear-gradient(to right, #b2f08d 0%, #39e9d2 100%);
  315. box-shadow: 0 2rpx 12rpx rgba(0,0,0,0.03);
  316. .nav-bar-inner {
  317. display: flex;
  318. align-items: center;
  319. height: 44px;
  320. width: 100vw;
  321. position: relative;
  322. }
  323. .back-icon {
  324. width: 44px;
  325. height: 44px;
  326. display: flex;
  327. align-items: center;
  328. justify-content: center;
  329. position: absolute;
  330. left: 0;
  331. top: 0;
  332. }
  333. .nav-bar-title {
  334. flex: 1;
  335. text-align: center;
  336. font-size: 36rpx;
  337. font-weight: bold;
  338. color: #222;
  339. letter-spacing: 2rpx;
  340. line-height: 44px;
  341. }
  342. .nav-bar-right {
  343. width: 44px;
  344. height: 44px;
  345. position: absolute;
  346. right: 0;
  347. top: 0;
  348. display: flex;
  349. align-items: center;
  350. justify-content: center;
  351. }
  352. }
  353. .feature-tags {
  354. // background: linear-gradient(to right, #b2f08d 0%, #39e9d2 100%);
  355. border-radius: 32rpx;
  356. display: flex;
  357. align-items: center;
  358. justify-content: space-between;
  359. padding: 0 24rpx;
  360. height: 80rpx;
  361. box-shadow: 0 4rpx 24rpx rgba(60, 167, 250, 0.08);
  362. .tag {
  363. flex: 1;
  364. display: flex;
  365. align-items: center;
  366. justify-content: center;
  367. .check {
  368. width: 36rpx;
  369. height: 36rpx;
  370. background: #fff;
  371. border-radius: 50%;
  372. display: flex;
  373. align-items: center;
  374. justify-content: center;
  375. font-size: 28rpx;
  376. color: #13ac47;
  377. font-weight: bold;
  378. margin-right: 10rpx;
  379. box-shadow: 0 2rpx 8rpx rgba(0,0,0,0.08);
  380. }
  381. .text {
  382. color: #fff;
  383. font-size: 28rpx;
  384. font-weight: bold;
  385. }
  386. }
  387. }
  388. .main-content {
  389. margin-top: 20rpx;
  390. padding-top: 88rpx;
  391. background: linear-gradient(180deg, #eaffe6 0%, #fff 30%);
  392. min-height: 100vh;
  393. width: 100vw;
  394. box-sizing: border-box;
  395. position: relative;
  396. z-index: 11;
  397. border-radius: 40rpx 40rpx 0 0;
  398. overflow: hidden;
  399. }
  400. .user-card {
  401. margin: 0 32rpx;
  402. background: linear-gradient(to bottom, #f6fff2 0%, #fff 100%);
  403. border-radius: 32rpx;
  404. box-shadow: 0 8rpx 32rpx rgba(60, 167, 250, 0.12);
  405. padding: 48rpx 36rpx 36rpx 36rpx;
  406. border: none;
  407. position: relative;
  408. top: -40rpx;
  409. display: flex;
  410. flex-direction: column;
  411. align-items: stretch;
  412. .user-info-row {
  413. display: flex;
  414. align-items: center;
  415. padding-bottom: 0;
  416. margin-bottom: 32rpx;
  417. // background-color: #fff;
  418. .avatar-box {
  419. margin-right: 24rpx;
  420. display: flex;
  421. flex-direction: column;
  422. align-items: center;
  423. .avatar-frame {
  424. width: 104rpx;
  425. height: 104rpx;
  426. border-radius: 10rpx;
  427. overflow: hidden;
  428. position: relative;
  429. background: #f2f2f2;
  430. box-shadow: 0 4rpx 16rpx rgba(0,0,0,0.10);
  431. .avatar-img {
  432. width: 104rpx;
  433. height: 80rpx;
  434. object-fit: cover;
  435. display: block;
  436. }
  437. .avatar-badge {
  438. position: absolute;
  439. left: 0;
  440. bottom: 0;
  441. width: 100%;
  442. height: 32rpx;
  443. line-height: 32rpx;
  444. background: rgba(238, 238, 238, 0.95);
  445. color: #999;
  446. font-size: 24rpx;
  447. text-align: center;
  448. border-bottom-left-radius: 10rpx;
  449. border-bottom-right-radius: 10rpx;
  450. font-weight: 400;
  451. letter-spacing: 2rpx;
  452. z-index: 2;
  453. }
  454. .avatar-badge-user {
  455. background: rgba(238, 238, 238, 0.95);
  456. color: #999;
  457. }
  458. .avatar-badge-expert {
  459. background: linear-gradient(90deg, #ff8917, #ffd01e);
  460. color: #fff;
  461. font-weight: 600;
  462. }
  463. .avatar-badge-ambassador {
  464. background: linear-gradient(90deg, #b2f08d, #39e9d2);
  465. color: #fff;
  466. font-weight: 600;
  467. }
  468. }
  469. }
  470. .user-meta {
  471. flex: 1;
  472. display: flex;
  473. flex-direction: column;
  474. justify-content: center;
  475. .nickname {
  476. font-size: 32rpx;
  477. font-weight: bold;
  478. color: #222;
  479. margin-bottom: 6rpx;
  480. }
  481. .userid {
  482. font-size: 24rpx;
  483. color: #bbb;
  484. }
  485. }
  486. .user-count {
  487. font-size: 30rpx;
  488. color: #222;
  489. font-weight: bold;
  490. text-align: right;
  491. min-width: 120rpx;
  492. margin-left: 16rpx;
  493. align-self: center;
  494. }
  495. }
  496. .user-stats-row {
  497. display: flex;
  498. align-items: stretch;
  499. justify-content: center;
  500. background: #f2fff6;
  501. border-radius: 24rpx;
  502. margin: 0 0 8rpx 0;
  503. padding: 32rpx 0;
  504. box-sizing: border-box;
  505. .stat-block {
  506. flex: 1;
  507. display: flex;
  508. flex-direction: column;
  509. align-items: center;
  510. justify-content: center;
  511. padding: 0 24rpx;
  512. .stat-label {
  513. font-size: 24rpx;
  514. color: #bbb;
  515. margin-bottom: 12rpx;
  516. text-align: center;
  517. }
  518. .stat-value {
  519. font-size: 40rpx;
  520. color: #222;
  521. font-weight: bold;
  522. margin-bottom: 18rpx;
  523. &.main {
  524. color: #13ac47;
  525. font-size: 48rpx;
  526. }
  527. }
  528. .withdraw-btn, .record-btn {
  529. width: 180rpx;
  530. height: 56rpx;
  531. border-radius: 28rpx;
  532. font-size: 26rpx;
  533. font-weight: bold;
  534. margin-top: 0;
  535. display: flex;
  536. align-items: center;
  537. justify-content: center;
  538. text-align: center;
  539. box-sizing: border-box;
  540. }
  541. .withdraw-btn {
  542. background: linear-gradient(90deg, #b2f08d, #39e9d2);
  543. color: #fff;
  544. border: none;
  545. }
  546. .record-btn {
  547. background: #fff;
  548. color: #13ac47;
  549. border: 2rpx solid #13ac47;
  550. &:active, &:focus {
  551. opacity: 0.8;
  552. }
  553. }
  554. }
  555. .stat-divider {
  556. width: 2rpx;
  557. height: 72rpx;
  558. background: #e0e0e0;
  559. margin: 0 16rpx;
  560. border-radius: 2rpx;
  561. align-self: center;
  562. }
  563. }
  564. .bottom-menu-row {
  565. display: flex;
  566. justify-content: center;
  567. align-items: center;
  568. margin: 40rpx 0 0 0;
  569. .menu-item {
  570. display: flex;
  571. align-items: center;
  572. margin: 0 40rpx;
  573. .menu-icon {
  574. width: 56rpx;
  575. height: 56rpx;
  576. border-radius: 50%;
  577. display: flex;
  578. align-items: center;
  579. justify-content: center;
  580. margin-right: 12rpx;
  581. &.red {
  582. background: #ff7e6a;
  583. }
  584. &.blue {
  585. background: #7eb6ff;
  586. }
  587. }
  588. .menu-text {
  589. font-size: 28rpx;
  590. color: #222;
  591. font-weight: 500;
  592. }
  593. }
  594. }
  595. }
  596. .rank-section {
  597. margin: 32rpx 32rpx 0 32rpx;
  598. .rank-title {
  599. font-size: 30rpx;
  600. color: #222;
  601. font-weight: bold;
  602. text-align: center;
  603. margin-bottom: 24rpx;
  604. }
  605. .rank-list {
  606. background: #fff;
  607. border-radius: 24rpx;
  608. box-shadow: 0 2rpx 8rpx rgba(60, 167, 250, 0.04);
  609. overflow: hidden;
  610. .rank-item {
  611. display: flex;
  612. align-items: center;
  613. padding: 0 44rpx;
  614. height: 104rpx;
  615. border-bottom: 1rpx solid #f3f3f3;
  616. &:last-child {
  617. border-bottom: none;
  618. }
  619. .rank-icon {
  620. width: 44rpx;
  621. display: flex;
  622. align-items: center;
  623. justify-content: center;
  624. .crown, .num-icon {
  625. width: 36rpx;
  626. height: 36rpx;
  627. }
  628. }
  629. .rank-avatar {
  630. width: 48rpx;
  631. height: 48rpx;
  632. border-radius: 50%;
  633. margin: 0 18rpx 0 10rpx;
  634. background: #f5f5f5;
  635. }
  636. .rank-phone {
  637. flex: 1;
  638. font-size: 28rpx;
  639. color: #222;
  640. font-weight: bold;
  641. }
  642. .rank-amount {
  643. font-size: 30rpx;
  644. color: #b98c4a;
  645. font-weight: bold;
  646. min-width: 120rpx;
  647. text-align: right;
  648. }
  649. }
  650. }
  651. }
  652. .rights-section {
  653. margin: 40rpx 32rpx 0 32rpx;
  654. .rights-title {
  655. font-size: 30rpx;
  656. color: #222;
  657. font-weight: bold;
  658. text-align: center;
  659. margin-bottom: 24rpx;
  660. }
  661. .rights-image {
  662. width: 100%;
  663. height: auto;
  664. }
  665. }
  666. .qrcode-section {
  667. margin: 48rpx 32rpx 0 32rpx;
  668. background: #fff;
  669. border-radius: 32rpx;
  670. box-shadow: 0 4rpx 24rpx rgba(60, 167, 250, 0.08);
  671. display: flex;
  672. flex-direction: column;
  673. align-items: center;
  674. padding: 32rpx 0 40rpx 0;
  675. .qrcode-title {
  676. font-size: 28rpx;
  677. color: #222;
  678. font-weight: bold;
  679. margin-bottom: 24rpx;
  680. }
  681. .qrcode-img {
  682. width: 220rpx;
  683. height: 220rpx;
  684. background: #fff;
  685. border-radius: 24rpx;
  686. box-shadow: 0 2rpx 8rpx rgba(0,0,0,0.08);
  687. cursor: pointer;
  688. transition: transform 0.2s ease;
  689. &:active {
  690. transform: scale(0.95);
  691. }
  692. }
  693. }
  694. .bottom-btns {
  695. position: fixed;
  696. left: 0;
  697. right: 0;
  698. bottom: 0;
  699. display: flex;
  700. justify-content: space-between;
  701. padding: 24rpx 32rpx calc(env(safe-area-inset-bottom) + 24rpx) 32rpx;
  702. background: #fff;
  703. z-index: 100;
  704. .btn {
  705. flex: 1;
  706. height: 88rpx;
  707. border-radius: 44rpx;
  708. font-size: 32rpx;
  709. font-weight: bold;
  710. margin: 0 12rpx;
  711. border: none;
  712. background: linear-gradient(90deg, #b2f08d, #39e9d2);
  713. display: flex;
  714. align-items: center;
  715. justify-content: center;
  716. &.gray {
  717. background: linear-gradient(90deg, #b2f08d, #39e9d2);
  718. color: #fff;
  719. }
  720. &.green {
  721. background: linear-gradient(90deg, #42dfc2, #9be48f);
  722. color: #fff;
  723. }
  724. }
  725. }
  726. .bottom-menu-row {
  727. display: flex;
  728. justify-content: center;
  729. align-items: center;
  730. margin: 40rpx 0 0 0;
  731. .menu-item {
  732. display: flex;
  733. align-items: center;
  734. margin: 0 40rpx;
  735. .menu-icon {
  736. width: 56rpx;
  737. height: 56rpx;
  738. border-radius: 50%;
  739. display: flex;
  740. align-items: center;
  741. justify-content: center;
  742. margin-right: 12rpx;
  743. &.red {
  744. background: #ff7e6a;
  745. }
  746. &.blue {
  747. background: #7eb6ff;
  748. }
  749. }
  750. .menu-text {
  751. font-size: 28rpx;
  752. color: #222;
  753. font-weight: 500;
  754. }
  755. }
  756. }
  757. .progress-modal-mask {
  758. position: fixed;
  759. left: 0; right: 0; top: 0; bottom: 0;
  760. background: rgba(0,0,0,0.25);
  761. z-index: 2000;
  762. display: flex;
  763. align-items: center;
  764. justify-content: center;
  765. }
  766. .progress-modal-box {
  767. width: 80vw;
  768. max-width: 420px;
  769. background: linear-gradient(180deg, #f3fff2 0%, #eafff6 100%);
  770. border-radius: 32rpx;
  771. box-shadow: 0 8rpx 32rpx rgba(60, 167, 250, 0.10);
  772. padding: 56rpx 0 32rpx 0;
  773. display: flex;
  774. flex-direction: column;
  775. align-items: center;
  776. }
  777. .progress-modal-title {
  778. font-size: 34rpx;
  779. color: #222;
  780. font-weight: bold;
  781. text-align: center;
  782. margin-bottom: 48rpx;
  783. white-space: pre-line;
  784. }
  785. .progress-modal-list {
  786. width: 88%;
  787. display: flex;
  788. flex-direction: column;
  789. gap: 18rpx;
  790. margin-bottom: 48rpx;
  791. }
  792. .progress-modal-item {
  793. // background: #fff;
  794. border-radius: 18rpx;
  795. height: 80rpx;
  796. display: flex;
  797. align-items: center;
  798. justify-content: space-between;
  799. font-size: 30rpx;
  800. color: #222;
  801. padding: 0 32rpx;
  802. box-shadow: 0 2rpx 8rpx rgba(60, 167, 250, 0.04);
  803. }
  804. .progress-modal-btn {
  805. width: 88%;
  806. height: 88rpx;
  807. background: linear-gradient(90deg, #b2f08d, #39e9d2);
  808. color: #222;
  809. font-size: 32rpx;
  810. font-weight: bold;
  811. border-radius: 44rpx;
  812. margin-top: 8rpx;
  813. box-shadow: 0 4rpx 16rpx rgba(60, 167, 250, 0.08);
  814. display: flex;
  815. align-items: center;
  816. justify-content: center;
  817. border: none;
  818. }
  819. // 客服二维码弹窗样式
  820. .qrcode-modal-mask {
  821. position: fixed;
  822. top: 0;
  823. left: 0;
  824. right: 0;
  825. bottom: 0;
  826. background: rgba(0, 0, 0, 0.6);
  827. display: flex;
  828. justify-content: center;
  829. align-items: center;
  830. z-index: 9999;
  831. backdrop-filter: blur(5rpx);
  832. }
  833. .qrcode-modal-content {
  834. background: #fff;
  835. border-radius: 24rpx;
  836. width: 600rpx;
  837. max-width: 90vw;
  838. animation: fadeInScale 0.3s ease;
  839. overflow: hidden;
  840. }
  841. .qrcode-modal-header {
  842. display: flex;
  843. justify-content: space-between;
  844. align-items: center;
  845. padding: 40rpx 40rpx 20rpx 40rpx;
  846. border-bottom: 1rpx solid #f0f0f0;
  847. }
  848. .qrcode-modal-title {
  849. font-size: 36rpx;
  850. font-weight: bold;
  851. color: #333;
  852. }
  853. .qrcode-modal-close {
  854. padding: 10rpx;
  855. margin: -10rpx;
  856. }
  857. .qrcode-modal-body {
  858. padding: 40rpx;
  859. display: flex;
  860. flex-direction: column;
  861. align-items: center;
  862. }
  863. .qrcode-modal-img {
  864. width: 400rpx;
  865. height: 400rpx;
  866. border-radius: 16rpx;
  867. margin-bottom: 30rpx;
  868. box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.1);
  869. }
  870. .qrcode-placeholder {
  871. width: 400rpx;
  872. height: 400rpx;
  873. border-radius: 16rpx;
  874. margin-bottom: 30rpx;
  875. background: #f5f5f5;
  876. display: flex;
  877. justify-content: center;
  878. align-items: center;
  879. text {
  880. color: #999;
  881. font-size: 28rpx;
  882. }
  883. }
  884. .qrcode-modal-tip {
  885. font-size: 28rpx;
  886. color: #666;
  887. text-align: center;
  888. line-height: 1.4;
  889. margin-bottom: 10rpx;
  890. }
  891. .qrcode-modal-benefit {
  892. font-size: 26rpx;
  893. color: #13ac47;
  894. text-align: center;
  895. font-weight: bold;
  896. }
  897. @keyframes fadeInScale {
  898. from {
  899. opacity: 0;
  900. transform: scale(0.8);
  901. }
  902. to {
  903. opacity: 1;
  904. transform: scale(1);
  905. }
  906. }
  907. </style>