vipMembership.vue 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. <route lang="json5" type="page">
  2. {
  3. layout: 'default',
  4. needLogin: true,
  5. style: {
  6. navigationBarTitleText: '%vipMembership.title%',
  7. navigationBarBackgroundColor: '#FFFFFF',
  8. },
  9. }
  10. </route>
  11. <script lang="ts" setup>
  12. import { memberConfigs } from '@/api/mine'
  13. import { t } from '@/locale'
  14. import { useUserStore } from '@/store'
  15. import { formatNumber } from '@/utils'
  16. defineOptions({
  17. name: 'VipMembership', // 会员中心
  18. })
  19. const userStore = useUserStore()
  20. const userInfo = computed(() => getUserInfoHook())
  21. interface TableData {
  22. vipLevel: string
  23. invitedNo: string
  24. directReferralReward: string
  25. indirectReferralReward: string
  26. joinedGroupsNo: string
  27. }
  28. // 表格列类型定义
  29. type AlignType = 'left' | 'center' | 'right'
  30. interface TableColumn {
  31. prop: string
  32. label: string
  33. fixed?: boolean
  34. slot?: boolean
  35. align: AlignType
  36. width: string
  37. }
  38. // 表格列配置
  39. const tableColumns = ref<TableColumn[]>([
  40. { prop: 'level', label: t('vipMembership.table.vipLevel'), fixed: true, align: 'center', width: '100rpx' },
  41. { prop: 'invitedNo', label: t('vipMembership.table.invitedNo'), align: 'center', width: '120rpx' },
  42. { prop: 'directReferralReward', slot: true, label: t('vipMembership.table.directReferralReward'), align: 'center', width: '210rpx' },
  43. { prop: 'indirectReferralReward', slot: true, label: t('vipMembership.table.indirectReferralReward'), align: 'center', width: '220rpx' },
  44. { prop: 'joinedGroupsNo', label: t('vipMembership.table.joinedGroupsNo'), align: 'center', width: '220rpx' },
  45. ])
  46. const dataList = ref<TableData[]>([])
  47. async function getConfigTable() {
  48. const res = await memberConfigs()
  49. console.log(res)
  50. dataList.value = res.data
  51. }
  52. onLoad(() => {
  53. userStore.getUserInfo()
  54. getConfigTable()
  55. })
  56. </script>
  57. <template>
  58. <view class="px-24rpx py-20rpx">
  59. <view
  60. class="relative mb-20rpx box-border min-h-302rpx bg-cover bg-center bg-no-repeat p-36rpx shadow-[0_48rpx_79rpx_13rpx_rgba(0,0,0,0.1)]"
  61. style="background-image: url('/static/images/vip-info-bg.png');"
  62. >
  63. <view>
  64. <wd-img width="100rpx" height="100rpx" custom-class="mb-18rpx" round :src="userInfo.headPic" />
  65. <view class="text-32rpx text-white font-bold">
  66. {{ userInfo.name }}
  67. </view>
  68. <wd-progress :duration="0" custom-class="w-85%!" color="#E7BEA6" :percentage="(userInfo.invitedNo / userInfo.nextInvitedNo) * 100" hide-text />
  69. <view class="text-22rpx text-#714428 font-bold">
  70. {{ t('vipMembership.inviteProgress', [formatNumber((userInfo.nextInvitedNo - userInfo.invitedNo), 0), userInfo.level + 1 >= dataList.length ? dataList.length : userInfo.level + 1]) }}
  71. </view>
  72. </view>
  73. <image :src="`/static/icons/vip${userInfo.level}.png`" class="absolute right-48rpx top-0 h-162rpx w-126.5rpx" />
  74. </view>
  75. <view class="mb-28rpx rounded-16rpx bg-white py-24rpx text-center">
  76. <view class="flex items-center justify-between">
  77. <view class="flex-[33.33%]">
  78. <view class="mb-3px text-22rpx text-#5B5B5B">
  79. {{ $t('vipMembership.invitedFriends') }}
  80. </view>
  81. <view class="text-26rpx font-bold">
  82. {{ formatNumber(userInfo.invitedNo, 0) }}
  83. </view>
  84. </view>
  85. <wd-divider custom-class="h-40rpx!" color="#A4A4A4" vertical dashed />
  86. <view class="flex-[33.33%]">
  87. <view class="mb-3px text-22rpx text-#5B5B5B">
  88. {{ $t('vipMembership.teamMembers') }}
  89. </view>
  90. <view class="text-26rpx font-bold">
  91. {{ formatNumber(userInfo.teamNo, 0) }}
  92. </view>
  93. </view>
  94. <wd-divider dashed custom-class="h-40rpx!" color="#A4A4A4" vertical />
  95. <view class="flex-[33.33%]">
  96. <view class="mb-3px text-22rpx text-#5B5B5B">
  97. {{ $t('vipMembership.l7dEarnings') }}
  98. </view>
  99. <view class="text-26rpx font-bold">
  100. {{ formatNumber(userInfo.l7DEarnings) }}
  101. </view>
  102. </view>
  103. </view>
  104. </view>
  105. <view>
  106. <view class="mb-28rpx text-32rpx">
  107. {{ $t('vipMembership.benefitsTiers') }}
  108. </view>
  109. <view class="rounded-16rpx bg-white p-24rpx">
  110. <wd-table :data="dataList" :border="false" :stripe="false" :fixed-header="false">
  111. <template
  112. v-for="(column, index) in tableColumns"
  113. :key="index"
  114. >
  115. <wd-table-col
  116. v-if="!column.slot"
  117. :prop="column.prop"
  118. :label="column.label"
  119. :fixed="column.fixed"
  120. :align="column.align"
  121. :width="column.width"
  122. />
  123. <wd-table-col
  124. v-else
  125. :prop="column.prop"
  126. :label="column.label"
  127. :fixed="column.fixed"
  128. :align="column.align"
  129. :width="column.width"
  130. >
  131. <template #value="{ row }">
  132. <view class="custom-class">
  133. <text>{{ column.prop === 'directReferralReward' ? row.directReferralReward : row.indirectReferralReward }}%</text>
  134. </view>
  135. </template>
  136. </wd-table-col>
  137. </template>
  138. </wd-table>
  139. </view>
  140. </view>
  141. </view>
  142. </template>
  143. <style lang="scss" scoped>
  144. :deep() {
  145. .wd-table {
  146. .wd-table__inner {
  147. .wd-table__header-row {
  148. text-align: center;
  149. .wd-table__cell {
  150. color: #636363 !important;
  151. }
  152. }
  153. }
  154. }
  155. .wd-progress {
  156. .wd-progress__outer {
  157. background-color: #e7bea6 !important;
  158. }
  159. .wd-progress__inner {
  160. background-image: linear-gradient(64deg, rgba(82, 40, 14, 0.5), rgba(127, 68, 32, 1)) !important;
  161. }
  162. }
  163. }
  164. </style>