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>
|
||
)
|
||
}
|