补充个人中心下的页面

This commit is contained in:
Eamon
2026-08-31 14:49:28 +08:00
parent b1f99b51e2
commit 3072b97bcf
59 changed files with 4122 additions and 970 deletions

View File

@@ -1,6 +1,6 @@
import type { ColumnDef } from "@tanstack/react-table"
import { SearchIcon } from "lucide-react"
import { useMemo, useState } from "react"
import AccountCell from "@/components/composites/accountCell"
import DataTable from "@/components/data-table"
import Page from "@/components/page"
import { Button } from "@/components/ui/button"
@@ -12,48 +12,17 @@ import {
SelectTrigger,
SelectValue,
} from "@/components/ui/select"
import { useOrderFilters } from "@/lib/hooks/useOrderFilters"
import {
Tooltip,
TooltipContent,
TooltipTrigger,
} from "@/components/ui/tooltip"
import {
cutAccount,
DEFAULT_FILTERS,
formatOrderType,
type OrderFilters,
formatDate,
formatMoney,
type OrderItem,
PACKAGE_OPTIONS,
totalConnections,
} from "@/lib/models/order"
import { MOCK_ORDERS, MOCK_PRODUCTS } from "./mock"
import { MOCK_ORDERS, MOCK_PRODUCTS } from "../mock/orders"
function formatMoney(value: number): string {
return value.toFixed(2)
}
function formatDate(value: string): string {
const date = new Date(value)
if (Number.isNaN(date.getTime())) return value
const year = date.getFullYear()
const month = String(date.getMonth() + 1).padStart(2, "0")
const day = String(date.getDate()).padStart(2, "0")
return `${year}.${month}.${day}`
}
function AccountCell({ accounts }: { accounts: string }) {
const isCut = accounts.length > 15
if (!isCut) return <span className="truncate">{accounts}</span>
return (
<Tooltip>
<TooltipTrigger asChild>
<span className="cursor-default truncate">{cutAccount(accounts)}</span>
</TooltipTrigger>
<TooltipContent className="max-w-80 break-all">{accounts}</TooltipContent>
</Tooltip>
)
}
// 后端订单接口就绪后,将 MOCK_ORDERS 替换为 fetchRefundOrders 返回的分页数据
const columns: ColumnDef<OrderItem>[] = [
{
@@ -65,11 +34,6 @@ const columns: ColumnDef<OrderItem>[] = [
accessorKey: "OrderNo",
header: "订单编号",
},
{
accessorKey: "OrderType",
header: "类型",
cell: ({ row }) => formatOrderType(row.original.OrderType),
},
{
accessorKey: "ProductName",
header: "产品",
@@ -110,69 +74,18 @@ const columns: ColumnDef<OrderItem>[] = [
},
]
function matchOrders(list: typeof MOCK_ORDERS, filters: OrderFilters) {
const keyword = filters.keyword.trim()
return list.filter(order => {
if (
filters.orderType !== "0" &&
order.OrderType !== Number(filters.orderType)
) {
return false
}
if (
filters.productId !== "0" &&
order.ProductId !== Number(filters.productId)
) {
return false
}
if (
filters.packageName !== "0" &&
order.PackageName !== filters.packageName
) {
return false
}
if (
keyword &&
!order.OrderNo.includes(keyword) &&
!order.Accounts.includes(keyword)
) {
return false
}
if (filters.bTime && order.CreateTime.slice(0, 10) < filters.bTime) {
return false
}
if (filters.eTime && order.CreateTime.slice(0, 10) > filters.eTime) {
return false
}
return true
})
}
export default function RefundOrdersPage() {
const [filters, setFilters] = useState<OrderFilters>(DEFAULT_FILTERS)
const [appliedFilters, setAppliedFilters] =
useState<OrderFilters>(DEFAULT_FILTERS)
const [page, setPage] = useState(1)
const [pageSize, setPageSize] = useState(10)
const filtered = useMemo(
() => matchOrders(MOCK_ORDERS, appliedFilters),
[appliedFilters],
)
const paged = useMemo(
() => filtered.slice((page - 1) * pageSize, page * pageSize),
[filtered, page, pageSize],
)
const patch = (partial: Partial<OrderFilters>) =>
setFilters({ ...filters, ...partial })
const handleSearch = () => {
setAppliedFilters(filters)
setPage(1)
}
const {
filters,
patch,
handleSearch,
page,
setPage,
pageSize,
handleSizeChange,
filtered,
paged,
} = useOrderFilters(MOCK_ORDERS)
return (
<Page>
@@ -250,7 +163,7 @@ export default function RefundOrdersPage() {
</div>
<div className="bg-white rounded-lg p-4 flex flex-col gap-4">
<h3 className="font-semibold text-lg">订单管理</h3>
<h3 className="font-semibold text-lg">退款订单管理</h3>
<DataTable
data={paged}
status="done"
@@ -260,10 +173,7 @@ export default function RefundOrdersPage() {
size: pageSize,
total: filtered.length,
onPageChange: setPage,
onSizeChange: size => {
setPageSize(size)
setPage(1)
},
onSizeChange: handleSizeChange,
}}
/>
</div>