feat: 添加剩余金额查看功能

This commit is contained in:
2026-01-09 11:51:39 +08:00
parent 0c6e642a33
commit ea63c83cbe
2 changed files with 73 additions and 24 deletions

View File

@@ -1,8 +1,10 @@
"use client"
import { useState } from "react"
import { useCallback, useState } from "react"
import { getRedPacketDrawsByRedPacketId } from "@/app/server/actions/get-red-packet-draws"
import { formatAmount } from "@/lib/format-amount"
import { CreateRedPacketPayload } from "@/lib/types/red-packet"
import { formatAmountFromInt, parseAmountToInt } from "@/lib/utils"
type Draw = {
id: string
@@ -12,10 +14,14 @@ type Draw = {
}
export function DrawList({
count,
rule,
precision,
redPacketId,
initialDraws,
}: {
count: number
rule: CreateRedPacketPayload['rule']
precision: number
redPacketId: string
initialDraws: Draw[]
@@ -37,6 +43,39 @@ export function DrawList({
}
}
const getBalance = useCallback(() => {
const used = draws.reduce((p, draw) => {
const pInt = parseAmountToInt(p, precision)
const dInt = parseAmountToInt(draw.amount, precision)
return formatAmountFromInt(dInt + pInt, precision)
}, '0.0');
if (rule.type === 'fixed') {
const amount = formatAmountFromInt(
parseAmountToInt(rule.singleAmount, precision) * BigInt(count),
precision
)
return formatAmountFromInt(
parseAmountToInt(amount, precision) - parseAmountToInt(used, precision),
precision,
)
} else if (rule.type === 'luck') {
const amount = formatAmountFromInt(
parseAmountToInt(rule.totalAmount, precision),
precision
)
return formatAmountFromInt(
parseAmountToInt(amount, precision) - parseAmountToInt(used, precision),
precision,
)
} else if (rule.type === 'random') {
return ''
}
return ''
}, [rule, draws])
return (
<section className="rounded-lg border p-3 space-y-2">
{/* 标题 + 刷新按钮 */}
@@ -54,31 +93,39 @@ export function DrawList({
{draws.length === 0 ? (
<div className="text-sm text-gray-400"></div>
) : (
<ul className="space-y-1">
{draws.map((draw) => (
<li
key={draw.id}
className="flex justify-between items-center text-sm font-mono"
>
{/* 用户 */}
<span>
{draw.userId.slice(0, 6)}
</span>
<div className="flex flex-1 flex-col">
{/* 金额 */}
<span className="text-right">
{formatAmount(draw.amount, precision)}
<>
<ul className="space-y-1">
{draws.map((draw) => (
<li
key={draw.id}
className="flex justify-between items-center text-sm font-mono"
>
{/* 用户 */}
<span>
{draw.userId.slice(0, 6)}
</span>
{/* 时间 */}
<span className="text-right text-gray-400">
{draw.createdAt.toLocaleString()}
</span>
</div>
</li>
))}
</ul>
<div className="flex flex-1 flex-col">
{/* 金额 */}
<span className="text-right">
{formatAmount(draw.amount, precision)}
</span>
{/* 时间 */}
<span className="text-right text-gray-400">
{draw.createdAt.toLocaleString()}
</span>
</div>
</li>
))}
</ul>
{getBalance() && <div className="border-t py-1">
<div className="text-sm">
<span></span>
<span>{getBalance()}</span>
</div>
</div>}
</>
)}
</section>
)

View File

@@ -73,6 +73,8 @@ export default async function AdminRedPacketPage({ params }: Props) {
</section>
<DrawList
count={redPacket.count}
rule={redPacket.rule}
precision={precision}
redPacketId={redPacketId}
initialDraws={initialDraws}