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

674 lines
17 KiB

1 week ago
1 week ago
1 week ago
1 week ago
1 week ago
1 week ago
1 week ago
1 week ago
1 week ago
1 week ago
1 week ago
5 days ago
1 week ago
1 week ago
1 week ago
1 week ago
1 week ago
1 week ago
1 week ago
1 week ago
1 week ago
1 week ago
1 week ago
1 week ago
1 week ago
1 week ago
1 week ago
1 week ago
1 week ago
1 week ago
1 week ago
1 week ago
1 week ago
1 week ago
1 week ago
1 week ago
1 week ago
1 week ago
1 week ago
1 week ago
1 week ago
1 week ago
1 week ago
1 week ago
1 week ago
1 week ago
1 week ago
1 week ago
1 week ago
1 week ago
1 week ago
1 week ago
1 week ago
1 week ago
1 week ago
1 week ago
1 week ago
1 week ago
1 week ago
1 week ago
1 week ago
1 week ago
1 week ago
1 week ago
1 week ago
1 week ago
1 week 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="user-type">{{userInfo.type}}</view>
  31. </view>
  32. </view>
  33. <view class="user-meta">
  34. <view class="nickname">{{userInfo.name}}</view>
  35. <view class="userid">ID: {{userInfo.id}}</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.balance}}</view>
  43. <button class="withdraw-btn">提现</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.totalWithdraw}}</view>
  49. <button class="record-btn">提现记录</button>
  50. </view>
  51. </view>
  52. <view class="bottom-menu-row">
  53. <view class="menu-item">
  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">
  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" :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.avatar" mode="aspectFill" />
  77. <text class="rank-phone">{{item.phone}}</text>
  78. <text class="rank-amount">¥{{item.amount}}</text>
  79. </view>
  80. </view>
  81. </view>
  82. <!-- 权益说明表格 -->
  83. <view class="rights-section">
  84. <view class="rights-title">权益说明</view>
  85. <view class="rights-table">
  86. <view class="table-header">
  87. <view class="th" v-for="(h, i) in rightsHeader" :key="i">{{h}}</view>
  88. </view>
  89. <view class="table-row" v-for="(row, i) in rightsRows" :key="i">
  90. <view class="td" v-for="(cell, j) in row" :key="j">
  91. <text v-if="cell==='✓'" class="cell-check"></text>
  92. <text v-else-if="cell==='X'" class="cell-x">X</text>
  93. <text v-else>{{cell}}</text>
  94. </view>
  95. </view>
  96. </view>
  97. </view>
  98. <!-- 联系客服二维码 -->
  99. <view class="qrcode-section">
  100. <view class="qrcode-title">联系客服</view>
  101. <image class="qrcode-img" :src="qrcodeUrl" mode="aspectFit" />
  102. </view>
  103. </view>
  104. <!-- 底部按钮区 -->
  105. <view class="bottom-btns">
  106. <button class="btn gray" @tap="goQrcode">我的二维码</button>
  107. <button class="btn green" @tap="goUpgrade">立即升级推广官</button>
  108. </view>
  109. </view>
  110. </template>
  111. <script>
  112. import pullRefreshMixin from '@/pages/mixins/pullRefreshMixin.js'
  113. export default {
  114. mixins: [pullRefreshMixin],
  115. data() {
  116. return {
  117. statusBarHeight: 0,
  118. navBarHeight: 44, // px
  119. navBarTotalHeight: 44, // px
  120. featureTags: ['收益高', '品类全', '到账快', '城市多'],
  121. userInfo: {
  122. avatar: '',
  123. name: '',
  124. id: '',
  125. type: '',
  126. balance: '',
  127. totalWithdraw: '',
  128. },
  129. tabActive: 0,
  130. rankList: [
  131. { phone: '151****6712', amount: '8094.44', avatar: '/static/avatar1.png' },
  132. { phone: '151****5283', amount: '7912.19', avatar: '/static/avatar2.png' },
  133. { phone: '155****1691', amount: '6880.53', avatar: '/static/avatar3.png' },
  134. { phone: '185****9149', amount: '6784.96', avatar: '/static/avatar4.png' },
  135. { phone: '189****2462', amount: '5775.65', avatar: '/static/avatar5.png' },
  136. ],
  137. rightsHeader: ['推广锁粉权限', '用户', '推广官', '合伙人'],
  138. rightsRows: [
  139. ['推广锁粉权限', 'X', '✓', '✓'],
  140. ['直接推广收益', 'X', '20%', '20%'],
  141. ['间接推广收益', 'X', 'X', '5%'],
  142. ['官方群服务', 'X', '20%', '25%'],
  143. ['推广课程支持', 'X', '5%', '25%'],
  144. ['推广工具包', 'X', '20%', '25%'],
  145. ['VIP专属客服', 'X', 'X', '25%'],
  146. ['收益模式', 'X', '5%', '主动收益'],
  147. ['线下沙龙', 'X', '✓', '主动收益'],
  148. ],
  149. qrcodeUrl: '/static/qrcode.png',
  150. }
  151. },
  152. onLoad() {
  153. const sysInfo = uni.getSystemInfoSync()
  154. this.statusBarHeight = sysInfo.statusBarHeight
  155. this.navBarHeight = 44
  156. this.navBarTotalHeight = this.statusBarHeight + this.navBarHeight
  157. this.getUserInfoByToken()
  158. },
  159. onPullDownRefresh() {
  160. this.getUserInfoByToken()
  161. uni.stopPullDownRefresh()
  162. },
  163. methods: {
  164. async onRefresh() {
  165. // 模拟刷新数据
  166. await new Promise(resolve => setTimeout(resolve, 1000))
  167. uni.stopPullRefresh()
  168. },
  169. navigateBack() {
  170. uni.navigateBack()
  171. },
  172. getRankIcon(idx) {
  173. return `/static/crown${idx}.png`
  174. },
  175. goQrcode() {
  176. uni.navigateTo({ url: '/pages/subcomponent/promo-qrcode' })
  177. },
  178. goUpgrade() {
  179. uni.navigateTo({ url: '/pages/subcomponent/upgrad' })
  180. },
  181. getUserInfoByToken() {
  182. this.$api('getUserByToken', {}, (res) => {
  183. if (res && res.success && res.result) {
  184. this.userInfo.avatar = res.result.headImage || ''
  185. this.userInfo.name = res.result.nickName || ''
  186. this.userInfo.id = res.result.id || ''
  187. // 你可以根据实际接口补充type、balance、totalWithdraw等字段
  188. }
  189. })
  190. }
  191. }
  192. }
  193. </script>
  194. <style lang="scss" scoped>
  195. .promotion-page {
  196. min-height: 100vh;
  197. background: linear-gradient(to right, #b2f08d 0%, #39e9d2 100%);
  198. padding-bottom: calc(env(safe-area-inset-bottom) + 120rpx);
  199. }
  200. .nav-bar {
  201. position: fixed;
  202. top: 0;
  203. left: 0;
  204. right: 0;
  205. z-index: 1000;
  206. width: 100vw;
  207. background: linear-gradient(to right, #b2f08d 0%, #39e9d2 100%);
  208. box-shadow: 0 2rpx 12rpx rgba(0,0,0,0.03);
  209. .nav-bar-inner {
  210. display: flex;
  211. align-items: center;
  212. height: 44px;
  213. width: 100vw;
  214. position: relative;
  215. }
  216. .back-icon {
  217. width: 44px;
  218. height: 44px;
  219. display: flex;
  220. align-items: center;
  221. justify-content: center;
  222. position: absolute;
  223. left: 0;
  224. top: 0;
  225. }
  226. .nav-bar-title {
  227. flex: 1;
  228. text-align: center;
  229. font-size: 36rpx;
  230. font-weight: bold;
  231. color: #222;
  232. letter-spacing: 2rpx;
  233. line-height: 44px;
  234. }
  235. .nav-bar-right {
  236. width: 44px;
  237. height: 44px;
  238. position: absolute;
  239. right: 0;
  240. top: 0;
  241. display: flex;
  242. align-items: center;
  243. justify-content: center;
  244. }
  245. }
  246. .feature-tags {
  247. // background: linear-gradient(to right, #b2f08d 0%, #39e9d2 100%);
  248. border-radius: 32rpx;
  249. display: flex;
  250. align-items: center;
  251. justify-content: space-between;
  252. padding: 0 24rpx;
  253. height: 80rpx;
  254. box-shadow: 0 4rpx 24rpx rgba(60, 167, 250, 0.08);
  255. .tag {
  256. flex: 1;
  257. display: flex;
  258. align-items: center;
  259. justify-content: center;
  260. .check {
  261. width: 36rpx;
  262. height: 36rpx;
  263. background: #fff;
  264. border-radius: 50%;
  265. display: flex;
  266. align-items: center;
  267. justify-content: center;
  268. font-size: 28rpx;
  269. color: #13ac47;
  270. font-weight: bold;
  271. margin-right: 10rpx;
  272. box-shadow: 0 2rpx 8rpx rgba(0,0,0,0.08);
  273. }
  274. .text {
  275. color: #fff;
  276. font-size: 28rpx;
  277. font-weight: bold;
  278. }
  279. }
  280. }
  281. .main-content {
  282. margin-top: 20rpx;
  283. padding-top: 88rpx;
  284. background: linear-gradient(180deg, #eaffe6 0%, #fff 30%);
  285. min-height: 100vh;
  286. width: 100vw;
  287. box-sizing: border-box;
  288. position: relative;
  289. z-index: 11;
  290. border-radius: 40rpx 40rpx 0 0;
  291. overflow: hidden;
  292. }
  293. .user-card {
  294. margin: 0 32rpx;
  295. background: linear-gradient(to bottom, #f6fff2 0%, #fff 100%);
  296. border-radius: 32rpx;
  297. box-shadow: 0 8rpx 32rpx rgba(60, 167, 250, 0.12);
  298. padding: 48rpx 36rpx 36rpx 36rpx;
  299. border: none;
  300. position: relative;
  301. top: -40rpx;
  302. display: flex;
  303. flex-direction: column;
  304. align-items: stretch;
  305. .user-info-row {
  306. display: flex;
  307. align-items: center;
  308. padding-bottom: 0;
  309. margin-bottom: 32rpx;
  310. // background-color: #fff;
  311. .avatar-box {
  312. margin-right: 24rpx;
  313. display: flex;
  314. flex-direction: column;
  315. align-items: center;
  316. .avatar-frame {
  317. width: 104rpx;
  318. height: 104rpx;
  319. border-radius: 10rpx;
  320. overflow: hidden;
  321. position: relative;
  322. background: #f2f2f2;
  323. box-shadow: 0 4rpx 16rpx rgba(0,0,0,0.10);
  324. .avatar-img {
  325. width: 104rpx;
  326. height: 80rpx;
  327. object-fit: cover;
  328. display: block;
  329. }
  330. .user-type {
  331. position: absolute;
  332. left: 0;
  333. bottom: 0;
  334. width: 100%;
  335. height: 32rpx;
  336. background: #e5e5e5;
  337. color: #888;
  338. font-size: 22rpx;
  339. font-weight: 500;
  340. text-align: center;
  341. line-height: 32rpx;
  342. border-bottom-left-radius: 10rpx;
  343. border-bottom-right-radius: 10rpx;
  344. }
  345. }
  346. }
  347. .user-meta {
  348. flex: 1;
  349. display: flex;
  350. flex-direction: column;
  351. justify-content: center;
  352. .nickname {
  353. font-size: 32rpx;
  354. font-weight: bold;
  355. color: #222;
  356. margin-bottom: 6rpx;
  357. }
  358. .userid {
  359. font-size: 24rpx;
  360. color: #bbb;
  361. }
  362. }
  363. .user-count {
  364. font-size: 30rpx;
  365. color: #222;
  366. font-weight: bold;
  367. text-align: right;
  368. min-width: 120rpx;
  369. margin-left: 16rpx;
  370. align-self: center;
  371. }
  372. }
  373. .user-stats-row {
  374. display: flex;
  375. align-items: stretch;
  376. justify-content: center;
  377. background: #f2fff6;
  378. border-radius: 24rpx;
  379. margin: 0 0 8rpx 0;
  380. padding: 32rpx 0;
  381. box-sizing: border-box;
  382. .stat-block {
  383. flex: 1;
  384. display: flex;
  385. flex-direction: column;
  386. align-items: center;
  387. justify-content: center;
  388. padding: 0 24rpx;
  389. .stat-label {
  390. font-size: 24rpx;
  391. color: #bbb;
  392. margin-bottom: 12rpx;
  393. text-align: center;
  394. }
  395. .stat-value {
  396. font-size: 40rpx;
  397. color: #222;
  398. font-weight: bold;
  399. margin-bottom: 18rpx;
  400. &.main {
  401. color: #13ac47;
  402. font-size: 48rpx;
  403. }
  404. }
  405. .withdraw-btn, .record-btn {
  406. width: 180rpx;
  407. height: 56rpx;
  408. border-radius: 28rpx;
  409. font-size: 26rpx;
  410. font-weight: bold;
  411. margin-top: 0;
  412. display: flex;
  413. align-items: center;
  414. justify-content: center;
  415. text-align: center;
  416. box-sizing: border-box;
  417. }
  418. .withdraw-btn {
  419. background: linear-gradient(90deg, #b2f08d, #39e9d2);
  420. color: #fff;
  421. border: none;
  422. }
  423. .record-btn {
  424. background: #fff;
  425. color: #13ac47;
  426. border: 2rpx solid #13ac47;
  427. }
  428. }
  429. .stat-divider {
  430. width: 2rpx;
  431. height: 72rpx;
  432. background: #e0e0e0;
  433. margin: 0 16rpx;
  434. border-radius: 2rpx;
  435. align-self: center;
  436. }
  437. }
  438. .bottom-menu-row {
  439. display: flex;
  440. justify-content: center;
  441. align-items: center;
  442. margin: 40rpx 0 0 0;
  443. .menu-item {
  444. display: flex;
  445. align-items: center;
  446. margin: 0 40rpx;
  447. .menu-icon {
  448. width: 56rpx;
  449. height: 56rpx;
  450. border-radius: 50%;
  451. display: flex;
  452. align-items: center;
  453. justify-content: center;
  454. margin-right: 12rpx;
  455. &.red {
  456. background: #ff7e6a;
  457. }
  458. &.blue {
  459. background: #7eb6ff;
  460. }
  461. }
  462. .menu-text {
  463. font-size: 28rpx;
  464. color: #222;
  465. font-weight: 500;
  466. }
  467. }
  468. }
  469. }
  470. .rank-section {
  471. margin: 32rpx 32rpx 0 32rpx;
  472. .rank-title {
  473. font-size: 30rpx;
  474. color: #222;
  475. font-weight: bold;
  476. text-align: center;
  477. margin-bottom: 24rpx;
  478. }
  479. .rank-list {
  480. background: #fff;
  481. border-radius: 24rpx;
  482. box-shadow: 0 2rpx 8rpx rgba(60, 167, 250, 0.04);
  483. overflow: hidden;
  484. .rank-item {
  485. display: flex;
  486. align-items: center;
  487. padding: 0 44rpx;
  488. height: 104rpx;
  489. border-bottom: 1rpx solid #f3f3f3;
  490. &:last-child {
  491. border-bottom: none;
  492. }
  493. .rank-icon {
  494. width: 44rpx;
  495. display: flex;
  496. align-items: center;
  497. justify-content: center;
  498. .crown, .num-icon {
  499. width: 36rpx;
  500. height: 36rpx;
  501. }
  502. }
  503. .rank-avatar {
  504. width: 48rpx;
  505. height: 48rpx;
  506. border-radius: 50%;
  507. margin: 0 18rpx 0 10rpx;
  508. background: #f5f5f5;
  509. }
  510. .rank-phone {
  511. flex: 1;
  512. font-size: 28rpx;
  513. color: #222;
  514. font-weight: bold;
  515. }
  516. .rank-amount {
  517. font-size: 30rpx;
  518. color: #b98c4a;
  519. font-weight: bold;
  520. min-width: 120rpx;
  521. text-align: right;
  522. }
  523. }
  524. }
  525. }
  526. .rights-section {
  527. margin: 40rpx 32rpx 0 32rpx;
  528. .rights-title {
  529. font-size: 30rpx;
  530. color: #222;
  531. font-weight: bold;
  532. text-align: center;
  533. margin-bottom: 24rpx;
  534. }
  535. .rights-table {
  536. background: #fff;
  537. border-radius: 24rpx;
  538. border: 1rpx solid #ff9900;
  539. overflow: hidden;
  540. box-sizing: border-box;
  541. .table-header {
  542. display: flex;
  543. background: #fff7ed;
  544. border-bottom: 1rpx solid #ff9900;
  545. .th {
  546. flex: 1;
  547. text-align: center;
  548. font-size: 26rpx;
  549. color: #ff9900;
  550. font-weight: bold;
  551. padding: 24rpx 0;
  552. border-right: 1rpx solid #ff9900;
  553. &:last-child { border-right: none; }
  554. }
  555. }
  556. .table-row {
  557. display: flex;
  558. border-bottom: 1rpx solid #ffe5c2;
  559. &:last-child { border-bottom: none; }
  560. .td {
  561. flex: 1;
  562. text-align: center;
  563. font-size: 26rpx;
  564. color: #222;
  565. padding: 20rpx 0;
  566. border-right: 1rpx solid #ffe5c2;
  567. &:last-child { border-right: none; }
  568. .cell-check {
  569. color: #13ac47;
  570. font-size: 30rpx;
  571. font-weight: bold;
  572. }
  573. .cell-x {
  574. color: #bbb;
  575. font-size: 30rpx;
  576. }
  577. }
  578. }
  579. }
  580. }
  581. .qrcode-section {
  582. margin: 48rpx 32rpx 0 32rpx;
  583. background: #fff;
  584. border-radius: 32rpx;
  585. box-shadow: 0 4rpx 24rpx rgba(60, 167, 250, 0.08);
  586. display: flex;
  587. flex-direction: column;
  588. align-items: center;
  589. padding: 32rpx 0 40rpx 0;
  590. .qrcode-title {
  591. font-size: 28rpx;
  592. color: #222;
  593. font-weight: bold;
  594. margin-bottom: 24rpx;
  595. }
  596. .qrcode-img {
  597. width: 220rpx;
  598. height: 220rpx;
  599. background: #fff;
  600. border-radius: 24rpx;
  601. box-shadow: 0 2rpx 8rpx rgba(0,0,0,0.08);
  602. }
  603. }
  604. .bottom-btns {
  605. position: fixed;
  606. left: 0;
  607. right: 0;
  608. bottom: 0;
  609. display: flex;
  610. justify-content: space-between;
  611. padding: 24rpx 32rpx calc(env(safe-area-inset-bottom) + 24rpx) 32rpx;
  612. background: #fff;
  613. z-index: 100;
  614. .btn {
  615. flex: 1;
  616. height: 88rpx;
  617. border-radius: 44rpx;
  618. font-size: 32rpx;
  619. font-weight: bold;
  620. margin: 0 12rpx;
  621. border: none;
  622. &.gray {
  623. background: #f5f5f5;
  624. color: #999;
  625. }
  626. &.green {
  627. background: linear-gradient(90deg, #42dfc2, #9be48f);
  628. color: #fff;
  629. }
  630. }
  631. }
  632. .bottom-menu-row {
  633. display: flex;
  634. justify-content: center;
  635. align-items: center;
  636. margin: 40rpx 0 0 0;
  637. .menu-item {
  638. display: flex;
  639. align-items: center;
  640. margin: 0 40rpx;
  641. .menu-icon {
  642. width: 56rpx;
  643. height: 56rpx;
  644. border-radius: 50%;
  645. display: flex;
  646. align-items: center;
  647. justify-content: center;
  648. margin-right: 12rpx;
  649. &.red {
  650. background: #ff7e6a;
  651. }
  652. &.blue {
  653. background: #7eb6ff;
  654. }
  655. }
  656. .menu-text {
  657. font-size: 28rpx;
  658. color: #222;
  659. font-weight: 500;
  660. }
  661. }
  662. }
  663. </style>