diff --git a/src/app/admin/balance/page.tsx b/src/app/admin/balance/page.tsx index 3f61f34..27c168c 100644 --- a/src/app/admin/balance/page.tsx +++ b/src/app/admin/balance/page.tsx @@ -1,5 +1,5 @@ 'use client' -import {useCallback, useEffect, useState} from 'react' +import {Suspense, useCallback, useEffect, useState} from 'react' import {PageRecord} from '@/lib/api' import {Balance} from '@/lib/models' import {useStatus} from '@/lib/states' @@ -136,100 +136,101 @@ export default function BalancePage(props: BalancePageProps) { - - { - await refresh(page, data.size) - }, - onSizeChange: async (size: number) => { - await refresh(data.page, size) - }, - }} - columns={[ - {accessorKey: 'bill_no', header: `账单编号`, - accessorFn: row => row.bill?.bill_no || '', - }, - { - accessorKey: 'status', - header: `状态`, - cell: ({row}) => { - const trade = row.original.trade - if (![1, 2, 3, 4, 5].includes(trade?.method)) { + + { + await refresh(page, data.size) + }, + onSizeChange: async (size: number) => { + await refresh(data.page, size) + }, + }} + columns={[ + {accessorKey: 'bill_no', header: `账单编号`, + accessorFn: row => row.bill?.bill_no || '', + }, + { + accessorKey: 'status', + header: `状态`, + cell: ({row}) => { + const trade = row.original.trade + if (![1, 2, 3, 4, 5].includes(trade?.method)) { + return ( +
+ + 已完成 +
+ ) + } + if (!trade) return - return (
- - 已完成 + {trade?.status === 1 ? ( + + ) : trade?.status === 2 ? ( + + ) : trade?.status === 3 ? ( + + ) : null} + + {trade?.status === 1 ? '已完成' + : trade?.status === 2 ? '已取消' + : trade?.status === 3 ? '已退款' : '-'} +
) - } - if (!trade) return - - return ( + }, + }, + { + accessorKey: 'amount', + header: '变动金额', + cell: ({row}) => { + const amount = row.original.amount + const isPositive = Number(amount) > 0 + return ( +
+ + {isPositive ? '+' : ''} + {Number(amount).toFixed(2)} + +
+ ) + }, + }, + { + header: '余额变化', + accessorKey: 'balance_prev', + cell: ({row}) => (
- {trade?.status === 1 ? ( - - ) : trade?.status === 2 ? ( - - ) : trade?.status === 3 ? ( - - ) : null} - - {trade?.status === 1 ? '已完成' - : trade?.status === 2 ? '已取消' - : trade?.status === 3 ? '已退款' : '-'} - + ¥{Number(row.original.balance_prev).toFixed(2)} + + ¥{Number(row.original.balance_curr).toFixed(2)}
- ) + ), }, - }, - { - accessorKey: 'amount', - header: '变动金额', - cell: ({row}) => { - const amount = row.original.amount - const isPositive = Number(amount) > 0 - return ( -
- - {isPositive ? '+' : ''} - {Number(amount).toFixed(2)} - -
- ) + { + header: '备注', + accessorKey: 'remark', }, - }, - { - header: '余额变化', - accessorKey: 'balance_prev', - cell: ({row}) => ( -
- ¥{Number(row.original.balance_prev).toFixed(2)} - - ¥{Number(row.original.balance_curr).toFixed(2)} -
- ), - }, - { - header: '备注', - accessorKey: 'remark', - }, - { - header: '创建时间', - accessorKey: 'created_at', - cell: ({row}) => - format(new Date(row.original.created_at), 'yyyy-MM-dd HH:mm'), - }, - ]} - /> + { + header: '创建时间', + accessorKey: 'created_at', + cell: ({row}) => + format(new Date(row.original.created_at), 'yyyy-MM-dd HH:mm:ss'), + }, + ]} + /> +
) } diff --git a/src/app/admin/bills/page.tsx b/src/app/admin/bills/page.tsx index 1e60e85..7bc8193 100644 --- a/src/app/admin/bills/page.tsx +++ b/src/app/admin/bills/page.tsx @@ -88,7 +88,7 @@ export default function BillsPage(props: BillsPageProps) {
-
+ 账单类型}> {({id, field}) => ( diff --git a/src/app/admin/resources/_components/utils.tsx b/src/app/admin/resources/_components/utils.tsx index 0952113..97c355c 100644 --- a/src/app/admin/resources/_components/utils.tsx +++ b/src/app/admin/resources/_components/utils.tsx @@ -44,7 +44,7 @@ export function ExpireBadge({expireAt}: {expireAt: Date}) { // 格式化日期 export function formatDateTime(date: Date | null | undefined) { if (!date) return '-' - return format(date, 'yyyy-MM-dd HH:mm') + return format(date, 'yyyy-MM-dd HH:mm:ss') } // 计算今日使用量 diff --git a/src/app/admin/whitelist/page.tsx b/src/app/admin/whitelist/page.tsx index 7e7c9af..73b43af 100644 --- a/src/app/admin/whitelist/page.tsx +++ b/src/app/admin/whitelist/page.tsx @@ -269,7 +269,7 @@ export default function WhitelistPage(props: WhitelistPageProps) { header: `备注`, accessorKey: 'remark', }, { - header: `添加时间`, cell: ({row}) => format(parseISO(row.original.created_at), 'yyyy-MM-dd HH:mm'), + header: `添加时间`, cell: ({row}) => format(parseISO(row.original.created_at), 'yyyy-MM-dd HH:mm:ss'), }, { id: 'actions', header: `操作`, cell: ({row}) => ( diff --git a/src/components/composites/extract/index.tsx b/src/components/composites/extract/index.tsx index 1143c8f..d4e8f3e 100644 --- a/src/components/composites/extract/index.tsx +++ b/src/components/composites/extract/index.tsx @@ -427,7 +427,7 @@ function SelectResource() {
到期时间: - {format(resource.short.expire_at, 'yyyy-MM-dd HH:mm')} + {format(resource.short.expire_at, 'yyyy-MM-dd HH:mm:ss')} {intlFormatDistance(resource.short.expire_at, new Date())}
@@ -469,7 +469,7 @@ function SelectResource() {
到期时间: - {format(resource.long.expire_at, 'yyyy-MM-dd HH:mm')} + {format(resource.long.expire_at, 'yyyy-MM-dd HH:mm:ss')} {intlFormatDistance(resource.long.expire_at, new Date())}
diff --git a/src/components/composites/purchase/shared/side-panel.tsx b/src/components/composites/purchase/shared/side-panel.tsx index cc6afa5..a009b85 100644 --- a/src/components/composites/purchase/shared/side-panel.tsx +++ b/src/components/composites/purchase/shared/side-panel.tsx @@ -15,6 +15,7 @@ import {formatPurchaseLiveLabel} from './sku' import {User} from '@/lib/models' import {PurchaseFormValues} from './form-values' import {IdCard} from 'lucide-react' +import {Loader2} from 'lucide-react' const emptyPrice: ExtraResp = { price: '0.00', @@ -43,7 +44,7 @@ export function PurchaseSidePanel(props: PurchaseSidePanelProps) { expire, dailyLimit, } - const priceData = usePurchasePrice(profile, selection) + const {priceData, isLoading, isError} = usePurchasePrice(profile, selection) const {price, actual: discountedPrice = '0.00'} = priceData const totalDiscount = getTotalDiscount(price, discountedPrice) const hasDiscount = Number(totalDiscount) > 0 @@ -70,9 +71,13 @@ export function PurchaseSidePanel(props: PurchaseSidePanelProps) {
  • 原价 - ¥{price} + { isError ? ( + + ) : ( + ¥{price} + )}
  • - {hasDiscount && ( + {hasDiscount && !isError && (
  • 总折扣 -¥{totalDiscount} @@ -91,9 +96,13 @@ export function PurchaseSidePanel(props: PurchaseSidePanelProps) {
  • 原价 - ¥{price} + { isError ? ( + + ) : ( + ¥{price} + )}
  • - {hasDiscount && ( + {hasDiscount && !isError && (
  • 总折扣 -¥{totalDiscount} @@ -105,7 +114,11 @@ export function PurchaseSidePanel(props: PurchaseSidePanelProps) {

    实付价格 - ¥{discountedPrice} + { isError ? ( + + ) : ( + ¥{discountedPrice} + )}

    {profile ? ( profile.id_type !== 0 ? ( @@ -143,6 +156,8 @@ export function PurchaseSidePanel(props: PurchaseSidePanelProps) { function usePurchasePrice(profile: User | null, selection: PurchaseSelection) { const [priceData, setPriceData] = useState>(emptyPrice) + const [isLoading, setIsLoading] = useState(true) + const [isError, setIsError] = useState(false) const requestIdRef = useRef(0) const {kind, mode, live, quota, expire, dailyLimit} = selection @@ -150,6 +165,9 @@ function usePurchasePrice(profile: User | null, selection: PurchaseSelection) { const requestId = ++requestIdRef.current const loadPrice = async () => { + setIsLoading(true) + setIsError(false) + try { const resource = buildPurchaseResource({ kind, @@ -176,6 +194,7 @@ function usePurchasePrice(profile: User | null, selection: PurchaseSelection) { actual: response.data.actual ?? response.data.price ?? '0.00', discounted: response.data.discounted ?? '0.00', }) + setIsError(false) } catch (error) { if (requestId !== requestIdRef.current) { @@ -184,13 +203,19 @@ function usePurchasePrice(profile: User | null, selection: PurchaseSelection) { console.error('获取价格失败:', error) setPriceData(emptyPrice) + setIsError(true) + } + finally { + if (requestId === requestIdRef.current) { + setIsLoading(false) + } } } loadPrice() }, [dailyLimit, expire, kind, live, mode, profile, quota]) - return priceData + return {priceData, isLoading, isError} } function getTotalDiscount(price: string, discountedPrice: string) {