173 lines
7.5 KiB
TypeScript
173 lines
7.5 KiB
TypeScript
|
|
"use client"
|
|||
|
|
|
|||
|
|
import { useState, useEffect } from "react"
|
|||
|
|
import { useStore } from "@/lib/store"
|
|||
|
|
import { Button } from "@/components/ui/button"
|
|||
|
|
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"
|
|||
|
|
import { Badge } from "@/components/ui/badge"
|
|||
|
|
import { Check, Clock, Wallet, History } from "lucide-react"
|
|||
|
|
|
|||
|
|
export default function WithdrawalsPage() {
|
|||
|
|
const { withdrawals, completeWithdrawal } = useStore()
|
|||
|
|
const [mounted, setMounted] = useState(false)
|
|||
|
|
|
|||
|
|
useEffect(() => {
|
|||
|
|
setMounted(true)
|
|||
|
|
}, [])
|
|||
|
|
|
|||
|
|
if (!mounted) return null
|
|||
|
|
|
|||
|
|
const pendingWithdrawals = withdrawals?.filter((w) => w.status === "pending") || []
|
|||
|
|
const historyWithdrawals =
|
|||
|
|
withdrawals
|
|||
|
|
?.filter((w) => w.status !== "pending")
|
|||
|
|
.sort((a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime()) || []
|
|||
|
|
|
|||
|
|
const totalPending = pendingWithdrawals.reduce((sum, w) => sum + w.amount, 0)
|
|||
|
|
|
|||
|
|
const handleApprove = (id: string) => {
|
|||
|
|
if (confirm("确认打款并完成此提现申请吗?")) {
|
|||
|
|
completeWithdrawal(id)
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return (
|
|||
|
|
<div className="p-8 max-w-6xl mx-auto">
|
|||
|
|
<div className="mb-8">
|
|||
|
|
<h1 className="text-2xl font-bold text-white">提现管理</h1>
|
|||
|
|
<p className="text-gray-400 mt-1">
|
|||
|
|
待处理 {pendingWithdrawals.length} 笔,共 ¥{totalPending.toFixed(2)}
|
|||
|
|
</p>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div className="grid gap-6">
|
|||
|
|
{/* 待处理申请 */}
|
|||
|
|
<Card className="bg-[#0f2137] border-gray-700/50 shadow-xl">
|
|||
|
|
<CardHeader>
|
|||
|
|
<CardTitle className="flex items-center gap-2 text-white">
|
|||
|
|
<div className="p-2 rounded-lg bg-orange-500/20">
|
|||
|
|
<Clock className="w-5 h-5 text-orange-400" />
|
|||
|
|
</div>
|
|||
|
|
待处理申请 ({pendingWithdrawals.length})
|
|||
|
|
</CardTitle>
|
|||
|
|
</CardHeader>
|
|||
|
|
<CardContent>
|
|||
|
|
{pendingWithdrawals.length === 0 ? (
|
|||
|
|
<div className="text-center py-12">
|
|||
|
|
<Wallet className="w-12 h-12 text-gray-600 mx-auto mb-3" />
|
|||
|
|
<p className="text-gray-500">暂无待处理申请</p>
|
|||
|
|
</div>
|
|||
|
|
) : (
|
|||
|
|
<div className="overflow-x-auto">
|
|||
|
|
<table className="w-full text-sm">
|
|||
|
|
<thead>
|
|||
|
|
<tr className="bg-[#0a1628] text-gray-400">
|
|||
|
|
<th className="p-4 text-left font-medium">申请时间</th>
|
|||
|
|
<th className="p-4 text-left font-medium">用户</th>
|
|||
|
|
<th className="p-4 text-left font-medium">收款方式</th>
|
|||
|
|
<th className="p-4 text-left font-medium">收款账号</th>
|
|||
|
|
<th className="p-4 text-left font-medium">金额</th>
|
|||
|
|
<th className="p-4 text-right font-medium">操作</th>
|
|||
|
|
</tr>
|
|||
|
|
</thead>
|
|||
|
|
<tbody className="divide-y divide-gray-700/50">
|
|||
|
|
{pendingWithdrawals.map((w) => (
|
|||
|
|
<tr key={w.id} className="hover:bg-[#0a1628] transition-colors">
|
|||
|
|
<td className="p-4 text-gray-400">{new Date(w.createdAt).toLocaleString()}</td>
|
|||
|
|
<td className="p-4">
|
|||
|
|
<div>
|
|||
|
|
<p className="font-medium text-white">{w.name}</p>
|
|||
|
|
<p className="text-xs text-gray-500 font-mono">{w.userId.slice(0, 8)}...</p>
|
|||
|
|
</div>
|
|||
|
|
</td>
|
|||
|
|
<td className="p-4">
|
|||
|
|
<Badge
|
|||
|
|
className={
|
|||
|
|
w.method === "wechat"
|
|||
|
|
? "bg-green-500/20 text-green-400 hover:bg-green-500/20 border-0"
|
|||
|
|
: "bg-blue-500/20 text-blue-400 hover:bg-blue-500/20 border-0"
|
|||
|
|
}
|
|||
|
|
>
|
|||
|
|
{w.method === "wechat" ? "微信" : "支付宝"}
|
|||
|
|
</Badge>
|
|||
|
|
</td>
|
|||
|
|
<td className="p-4 font-mono text-gray-300">{w.account}</td>
|
|||
|
|
<td className="p-4">
|
|||
|
|
<span className="font-bold text-orange-400">¥{w.amount.toFixed(2)}</span>
|
|||
|
|
</td>
|
|||
|
|
<td className="p-4 text-right">
|
|||
|
|
<Button
|
|||
|
|
size="sm"
|
|||
|
|
onClick={() => handleApprove(w.id)}
|
|||
|
|
className="bg-[#38bdac] hover:bg-[#2da396] text-white"
|
|||
|
|
>
|
|||
|
|
<Check className="w-4 h-4 mr-1" />
|
|||
|
|
确认打款
|
|||
|
|
</Button>
|
|||
|
|
</td>
|
|||
|
|
</tr>
|
|||
|
|
))}
|
|||
|
|
</tbody>
|
|||
|
|
</table>
|
|||
|
|
</div>
|
|||
|
|
)}
|
|||
|
|
</CardContent>
|
|||
|
|
</Card>
|
|||
|
|
|
|||
|
|
{/* 处理历史 */}
|
|||
|
|
<Card className="bg-[#0f2137] border-gray-700/50 shadow-xl">
|
|||
|
|
<CardHeader>
|
|||
|
|
<CardTitle className="flex items-center gap-2 text-white">
|
|||
|
|
<div className="p-2 rounded-lg bg-gray-700/50">
|
|||
|
|
<History className="w-5 h-5 text-gray-400" />
|
|||
|
|
</div>
|
|||
|
|
处理历史
|
|||
|
|
</CardTitle>
|
|||
|
|
</CardHeader>
|
|||
|
|
<CardContent>
|
|||
|
|
{historyWithdrawals.length === 0 ? (
|
|||
|
|
<div className="text-center py-12">
|
|||
|
|
<History className="w-12 h-12 text-gray-600 mx-auto mb-3" />
|
|||
|
|
<p className="text-gray-500">暂无历史记录</p>
|
|||
|
|
</div>
|
|||
|
|
) : (
|
|||
|
|
<div className="overflow-x-auto">
|
|||
|
|
<table className="w-full text-sm">
|
|||
|
|
<thead>
|
|||
|
|
<tr className="bg-[#0a1628] text-gray-400">
|
|||
|
|
<th className="p-4 text-left font-medium">申请时间</th>
|
|||
|
|
<th className="p-4 text-left font-medium">处理时间</th>
|
|||
|
|
<th className="p-4 text-left font-medium">用户</th>
|
|||
|
|
<th className="p-4 text-left font-medium">渠道</th>
|
|||
|
|
<th className="p-4 text-left font-medium">金额</th>
|
|||
|
|
<th className="p-4 text-left font-medium">状态</th>
|
|||
|
|
</tr>
|
|||
|
|
</thead>
|
|||
|
|
<tbody className="divide-y divide-gray-700/50">
|
|||
|
|
{historyWithdrawals.map((w) => (
|
|||
|
|
<tr key={w.id} className="hover:bg-[#0a1628] transition-colors">
|
|||
|
|
<td className="p-4 text-gray-400">{new Date(w.createdAt).toLocaleString()}</td>
|
|||
|
|
<td className="p-4 text-gray-400">
|
|||
|
|
{w.completedAt ? new Date(w.completedAt).toLocaleString() : "-"}
|
|||
|
|
</td>
|
|||
|
|
<td className="p-4 font-medium text-white">{w.name}</td>
|
|||
|
|
<td className="p-4 text-gray-300">{w.method === "wechat" ? "微信" : "支付宝"}</td>
|
|||
|
|
<td className="p-4 font-medium text-white">¥{w.amount.toFixed(2)}</td>
|
|||
|
|
<td className="p-4">
|
|||
|
|
<Badge className="bg-green-500/20 text-green-400 hover:bg-green-500/20 border-0">
|
|||
|
|
已完成
|
|||
|
|
</Badge>
|
|||
|
|
</td>
|
|||
|
|
</tr>
|
|||
|
|
))}
|
|||
|
|
</tbody>
|
|||
|
|
</table>
|
|||
|
|
</div>
|
|||
|
|
)}
|
|||
|
|
</CardContent>
|
|||
|
|
</Card>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
)
|
|||
|
|
}
|