"use client" import { format } from "date-fns" import { Loader2 } from "lucide-react" import { Suspense, useCallback, useEffect, useMemo, useState } from "react" import { toast } from "sonner" import { activeProductSku, getAllProduct, getPageProductSku, } from "@/actions/product" import { DataTable, useDataTable } from "@/components/data-table" import { Page } from "@/components/page" import { SkuCodeBadge } from "@/components/products/format" import { Badge } from "@/components/ui/badge" import { Button } from "@/components/ui/button" import type { ProductCode } from "@/lib/base" import { cn } from "@/lib/utils" import type { Product } from "@/models/product" import type { ProductSku } from "@/models/product_sku" import { BatchUpdateDiscount } from "./batch-discount" import { CreateProductSku } from "./create" import type { SelectedProduct } from "./type" import { UpdateProductSku } from "./update" export default function ProductPage() { const [selected, setSelected] = useState( undefined, ) return ( ) } function Products(props: { selected?: SelectedProduct onSelect?: (id: SelectedProduct) => void }) { const [list, setList] = useState([]) const refresh = useCallback(async () => { const resp = await getAllProduct() if (resp.success) { setList(resp.data) } }, []) const selected = useMemo(() => { return list.find(item => item.id === props.selected?.id) }, [list, props.selected]) useEffect(() => { refresh() }, [refresh]) return (

产品列表

    {list.map(item => (
  • ))}
) } function ProductSkus(props: { selected?: { id: number code: ProductCode } }) { const action = useCallback( (page: number, size: number) => getPageProductSku({ page, size, product_id: props.selected?.id }), [props.selected], ) const table = useDataTable(action) console.log(table, "table") return (
classNames={{ root: "overflow-auto", }} {...table} columns={[ { header: "套餐编码", cell: ({ row }) => row.original.product ? ( ) : ( row.original.code ), }, { header: "套餐名称", accessorKey: "name" }, { header: "单价", accessorFn: row => Number(row.price).toFixed(2) }, { header: "折扣", accessorFn: row => row.discount?.name ?? "—" }, { header: "最终价格", accessorFn: row => { const value = row.discount ? (Number(row.price) * Number(row.discount.discount)) / 100 : Number(row.price) return Number(value.toFixed(2)) }, }, { header: "最低价格", accessorKey: "price_min" }, { header: "创建时间", accessorFn: row => format(row.created_at, "yyyy-MM-dd HH:mm"), }, { header: "更新时间", accessorFn: row => format(row.updated_at, "yyyy-MM-dd HH:mm"), }, { id: "action", meta: { pin: "right" }, header: "操作", cell: ({ row }) => (
), }, ]} />
) } function ActiveButton(props: { sku: ProductSku; onSuccess?: () => void }) { const [loading, setLoading] = useState(false) const handleConfirm = async () => { setLoading(true) try { const newStatus = props.sku.status === 1 ? 0 : 1 const resp = await activeProductSku({ id: props.sku.id, status: newStatus, }) if (resp.success) { toast.success(newStatus === 1 ? "已启用" : "已禁用") props.onSuccess?.() } else { toast.error(resp.message ?? "操作失败") } } catch (error) { const message = error instanceof Error ? error.message : error toast.error(`接口请求错误: ${message}`) } finally { setLoading(false) } } return ( ) }