This commit is contained in:
Binary file not shown.
|
Before Width: | Height: | Size: 142 KiB After Width: | Height: | Size: 176 KiB |
@@ -0,0 +1,63 @@
|
||||
<template>
|
||||
<Dialog :open="isOpen" @update:open="setOpen">
|
||||
<DialogContent
|
||||
class="top-[94px] flex h-[calc(100vh-94px-50px)] w-[386px] translate-y-0 flex-col items-center justify-center border-none bg-transparent p-0 shadow-none outline-none focus:ring-0"
|
||||
:showCloseButton="false"
|
||||
>
|
||||
<div class="relative flex h-[628px] w-full flex-col rounded-[32px] bg-[#DDDDDD] px-4 py-6">
|
||||
<button
|
||||
@click="hide"
|
||||
class="absolute top-6 right-6 z-10 flex size-8 items-center justify-center rounded-lg transition-colors hover:bg-black/5"
|
||||
>
|
||||
<svg
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="3"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
class="text-black"
|
||||
>
|
||||
<line x1="18" y1="6" x2="6" y2="18"></line>
|
||||
<line x1="6" y1="6" x2="18" y2="18"></line>
|
||||
</svg>
|
||||
</button>
|
||||
|
||||
<h2 class="mb-2 px-4 pt-8 text-center text-[20px] font-bold text-black">提现记录</h2>
|
||||
|
||||
<WithdrawalLogList ref="logListRef" />
|
||||
</div>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { nextTick, ref } from 'vue'
|
||||
import { Dialog, DialogContent } from '@/components/ui/dialog'
|
||||
import WithdrawalLogList from './WithdrawalLogList.vue'
|
||||
|
||||
const isOpen = ref(false)
|
||||
const logListRef = ref<InstanceType<typeof WithdrawalLogList> | null>(null)
|
||||
|
||||
const setOpen = (value: boolean) => {
|
||||
isOpen.value = value
|
||||
}
|
||||
|
||||
const show = () => {
|
||||
isOpen.value = true
|
||||
nextTick(() => {
|
||||
logListRef.value?.refresh()
|
||||
})
|
||||
}
|
||||
|
||||
const hide = () => {
|
||||
isOpen.value = false
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
show,
|
||||
hide,
|
||||
})
|
||||
</script>
|
||||
@@ -0,0 +1,182 @@
|
||||
<template>
|
||||
<div class="flex flex-1 flex-col overflow-hidden">
|
||||
<div class="h-[430px] overflow-y-auto pr-1">
|
||||
<div v-if="loading" class="flex h-40 items-center justify-center">
|
||||
<div
|
||||
class="h-8 w-8 animate-spin rounded-full border-4 border-[#ADFF5B] border-t-transparent"
|
||||
></div>
|
||||
</div>
|
||||
<div
|
||||
v-else-if="list.length === 0"
|
||||
class="flex h-40 items-center justify-center text-gray-500"
|
||||
>
|
||||
暂无提现记录
|
||||
</div>
|
||||
<div v-else class="space-y-[10px]">
|
||||
<div
|
||||
v-for="item in list"
|
||||
:key="item.id"
|
||||
class="rounded-[20px] bg-[#CECECF] py-2 text-[14px] font-normal text-black"
|
||||
>
|
||||
<div class="grid grid-cols-2 gap-y-1">
|
||||
<div class="pl-4">
|
||||
<div class="text-xs text-gray-500">提现金额</div>
|
||||
<div class="font-bold text-[#222]">${{ formatAmount(item.amount) }}</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="text-xs text-gray-500">状态</div>
|
||||
<div class="font-medium">{{ statusText(item.status) }}</div>
|
||||
</div>
|
||||
|
||||
<div class="pl-4">
|
||||
<div class="text-xs text-gray-500">提现方式</div>
|
||||
<div>{{ methodText(item.method) }}</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="text-xs text-gray-500">申请时间</div>
|
||||
<div class="whitespace-nowrap">{{ formatTime(item.created_at) }}</div>
|
||||
</div>
|
||||
|
||||
<div v-if="item.reason" class="col-span-2 pl-4">
|
||||
<div class="text-xs text-gray-500">拒绝原因</div>
|
||||
<div class="break-all">{{ item.reason }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="total > 0" class="flex flex-col items-center pt-[18px]">
|
||||
<div class="mb-2 flex items-center gap-[10px]">
|
||||
<button
|
||||
@click="changePage(1)"
|
||||
:disabled="page === 1"
|
||||
class="flex h-[30px] min-w-[30px] items-center justify-center rounded-full bg-[#EAEAEA] transition-opacity disabled:opacity-30"
|
||||
>
|
||||
<span class="text-lg font-bold text-[#848484]"><<</span>
|
||||
</button>
|
||||
<button
|
||||
@click="changePage(page - 1)"
|
||||
:disabled="page === 1"
|
||||
class="flex h-[30px] min-w-[30px] items-center justify-center rounded-full bg-[#EAEAEA] transition-opacity disabled:opacity-30"
|
||||
>
|
||||
<span class="text-lg font-bold text-[#848484]"><</span>
|
||||
</button>
|
||||
|
||||
<div
|
||||
class="flex h-[30px] min-w-[65px] items-center justify-center rounded-full bg-[#EAEAEA] px-2"
|
||||
>
|
||||
<span class="text-base text-[#848484]">{{ page }}</span>
|
||||
<span class="ml-1 text-base text-[#848484]">v</span>
|
||||
</div>
|
||||
|
||||
<button
|
||||
@click="changePage(page + 1)"
|
||||
:disabled="page >= totalPages"
|
||||
class="flex h-[30px] min-w-[30px] items-center justify-center rounded-full bg-[#EAEAEA] transition-opacity disabled:opacity-30"
|
||||
>
|
||||
<span class="text-lg font-bold text-[#848484]">></span>
|
||||
</button>
|
||||
<button
|
||||
@click="changePage(totalPages)"
|
||||
:disabled="page >= totalPages"
|
||||
class="flex h-[30px] min-w-[30px] items-center justify-center rounded-full bg-[#EAEAEA] transition-opacity disabled:opacity-30"
|
||||
>
|
||||
<span class="text-lg font-bold text-[#848484]">>></span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="text-xs font-[300] text-[#848484]">第 {{ page }} / {{ totalPages }} 页</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed, ref } from 'vue'
|
||||
import request from '@/utils/request'
|
||||
|
||||
interface WithdrawalLog {
|
||||
id: number
|
||||
amount: number
|
||||
status: number
|
||||
method: number
|
||||
reason?: string
|
||||
created_at: number
|
||||
}
|
||||
|
||||
const page = ref(1)
|
||||
const size = ref(4)
|
||||
const total = ref(0)
|
||||
const list = ref<WithdrawalLog[]>([])
|
||||
const loading = ref(false)
|
||||
|
||||
const totalPages = computed(() => Math.ceil(total.value / size.value) || 1)
|
||||
|
||||
async function fetchLogs() {
|
||||
loading.value = true
|
||||
try {
|
||||
const res: any = await request.get('/api/v1/public/user/withdrawal_log', {
|
||||
page: page.value,
|
||||
size: size.value,
|
||||
})
|
||||
list.value = res.list || []
|
||||
total.value = res.total || 0
|
||||
} catch (error) {
|
||||
console.error('Fetch withdrawal logs error:', error)
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
function refresh() {
|
||||
page.value = 1
|
||||
fetchLogs()
|
||||
}
|
||||
|
||||
function changePage(p: number) {
|
||||
if (p < 1 || p > totalPages.value) return
|
||||
page.value = p
|
||||
fetchLogs()
|
||||
}
|
||||
|
||||
function statusText(status: number) {
|
||||
const map: Record<number, string> = {
|
||||
0: '待审核',
|
||||
1: '已通过',
|
||||
2: '已拒绝',
|
||||
3: '已取消',
|
||||
}
|
||||
return map[status] || '未知'
|
||||
}
|
||||
|
||||
function methodText(method: number) {
|
||||
const map: Record<number, string> = {
|
||||
0: '其他',
|
||||
1: '支付宝',
|
||||
2: '微信',
|
||||
3: 'USDT(TRC20)',
|
||||
}
|
||||
return map[method] || '未知'
|
||||
}
|
||||
|
||||
function formatAmount(amount: number) {
|
||||
return ((amount || 0) / 100).toFixed(2)
|
||||
}
|
||||
|
||||
function formatTime(timestamp: number) {
|
||||
if (!timestamp) return '-'
|
||||
const date = new Date(timestamp > 10000000000 ? timestamp : timestamp * 1000)
|
||||
return date.toLocaleString('en-US', {
|
||||
month: 'numeric',
|
||||
day: 'numeric',
|
||||
year: 'numeric',
|
||||
hour: 'numeric',
|
||||
minute: '2-digit',
|
||||
second: '2-digit',
|
||||
hour12: false,
|
||||
})
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
refresh,
|
||||
})
|
||||
</script>
|
||||
@@ -12,9 +12,7 @@
|
||||
<div class="ml-2 flex flex-col justify-center text-white">
|
||||
<div class="text-base font-semibold">{{ userInfo.email }}</div>
|
||||
<div class="flex items-center text-base font-semibold">
|
||||
<span class="mr-0.5 text-3xl">🌞</span> 超级合伙人 返佣比例{{
|
||||
userInfo.referral_percentage
|
||||
}}%
|
||||
<span class="mr-0.5 text-3xl">🌞</span> {{ referralText }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -29,7 +27,15 @@
|
||||
class="flex min-h-[90px] w-full items-center justify-between rounded-[25px] bg-[#ADFF5B] px-4 font-medium text-black"
|
||||
>
|
||||
<div>
|
||||
<div class="text-xl font-semibold">佣金账户余额</div>
|
||||
<div class="flex items-center text-xl font-semibold">
|
||||
佣金账户余额<!--<Button
|
||||
variant="link"
|
||||
class="ml-2 h-auto p-0 text-sm font-bold text-black/55 underline hover:text-black"
|
||||
@click="withdrawalLogDialogRef?.show()"
|
||||
>
|
||||
提现记录
|
||||
</Button>-->
|
||||
</div>
|
||||
<div class="text-3xl font-black">
|
||||
$ {{ (userInfo.commission / 100 || 0).toFixed(2) }}
|
||||
</div>
|
||||
@@ -43,6 +49,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<WalletDialog ref="walletDialogRef" :commission="userInfo.commission || 0" @confirm="init" />
|
||||
<WithdrawalLogDialog ref="withdrawalLogDialogRef" />
|
||||
<div>
|
||||
<div class="flex flex-col gap-[10px] px-6 pt-8 pb-4">
|
||||
<div
|
||||
@@ -78,6 +85,7 @@
|
||||
import UserCenterSkeleton from '@/components/user-center/UserCenterSkeleton.vue'
|
||||
import { Button } from '@/components/ui/button'
|
||||
import WalletDialog from './components/WalletDialog.vue'
|
||||
import WithdrawalLogDialog from './components/WithdrawalLogDialog.vue'
|
||||
import CopyIcon from './copy.svg?component'
|
||||
import { computed, onMounted, ref } from 'vue'
|
||||
import request from '@/utils/request'
|
||||
@@ -86,11 +94,13 @@ import { toast } from 'vue-sonner'
|
||||
|
||||
const router = useRouter()
|
||||
const walletDialogRef = ref<InstanceType<typeof WalletDialog> | null>(null)
|
||||
const withdrawalLogDialogRef = ref<InstanceType<typeof WithdrawalLogDialog> | null>(null)
|
||||
const userInfo = ref({
|
||||
email: '',
|
||||
created_at: '',
|
||||
share_link: '',
|
||||
commission: 0,
|
||||
referral_percentage: 0,
|
||||
})
|
||||
const inviteStats = ref({
|
||||
friendly_count: 0,
|
||||
@@ -141,6 +151,14 @@ const formattedDate = computed(() => {
|
||||
}).format(date)
|
||||
})
|
||||
|
||||
const referralText = computed(() => {
|
||||
const percentage = Number(userInfo.value.referral_percentage || 0)
|
||||
if (percentage <= 0) return '暂未激活比例,请联系客服激活'
|
||||
if (percentage <= 20) return `初级合伙人 返佣比例${percentage}%`
|
||||
if (percentage <= 39) return `高级合伙人 返佣比例${percentage}%`
|
||||
return `超级合伙人 返佣比例${percentage}%`
|
||||
})
|
||||
|
||||
function copy(text: string) {
|
||||
navigator.clipboard.writeText(text).then(() => {
|
||||
toast.success('已复制到剪贴板')
|
||||
|
||||
Reference in New Issue
Block a user