import React, { useEffect, useState } from 'react'; import { Button, Card, Form, Input, InputNumber, message, Modal, Popconfirm, Select, Space, Switch, Table, Tag, Typography, } from 'antd'; import { GiftOutlined, PlusOutlined, EditOutlined, DeleteOutlined, } from '@ant-design/icons'; import { getRechargePackages, saveRechargePackage, deleteRechargePackage } from '../api'; interface PackageItem { id: string; name: string; credits: number; price: number; bonusCredits: number; totalCredits: number; description: string | null; packageType: string; isGift: boolean; isActive: boolean; sortOrder: number; } const TYPE_COLORS: Record = { normal: 'blue', gift: 'green', promo: 'purple', }; const TYPE_LABELS: Record = { normal: '常规', gift: '赠送', promo: '促销', }; const AdminRechargePackages: React.FC = () => { const [packages, setPackages] = useState([]); const [loading, setLoading] = useState(false); const [modal, setModal] = useState<{ open: boolean; item: PackageItem | null }>({ open: false, item: null }); const [form] = Form.useForm(); const load = async () => { setLoading(true); try { const data = await getRechargePackages(); setPackages(data.map((item: any) => ({ id: item.id, name: item.name, credits: item.credits, price: item.price, bonusCredits: item.bonus_credits ?? item.bonusCredits ?? 0, totalCredits: item.total_credits ?? item.totalCredits ?? item.credits, description: item.description, packageType: item.package_type ?? item.packageType ?? 'normal', isGift: item.is_gift ?? item.isGift ?? false, isActive: item.is_active ?? item.isActive ?? true, sortOrder: item.sort_order ?? item.sortOrder ?? 0, }))); } catch { message.error('加载充值套餐失败'); } finally { setLoading(false); } }; useEffect(() => { load(); }, []); const handleSave = async () => { try { const values = await form.validateFields(); const payload = { name: values.name, credits: values.credits, price: values.price, bonus_credits: values.bonusCredits || 0, description: values.description || null, package_type: values.packageType || 'normal', is_gift: values.isGift || false, is_active: values.isActive ?? true, sort_order: values.sortOrder ?? 0, }; if (modal.item?.id) { await saveRechargePackage({ id: modal.item.id, ...payload }); message.success('已更新'); } else { await saveRechargePackage(payload); message.success('已添加'); } setModal({ open: false, item: null }); form.resetFields(); load(); } catch { /* validation */ } }; const handleDelete = async (id: string) => { try { await deleteRechargePackage(id); message.success('已删除'); load(); } catch (e: any) { message.error(e?.message || '删除失败'); } }; const openEdit = (item?: PackageItem) => { setModal({ open: true, item: item || null }); if (item) { form.setFieldsValue({ name: item.name, credits: item.credits, price: item.price, bonusCredits: item.bonusCredits, description: item.description, packageType: item.packageType, isGift: item.isGift, isActive: item.isActive, sortOrder: item.sortOrder, }); } else { form.resetFields(); form.setFieldsValue({ isActive: true, sortOrder: 0, packageType: 'normal', bonusCredits: 0, isGift: false }); } }; const columns = [ { title: '套餐名称', key: 'name', width: 160, render: (_: any, r: PackageItem) => (
{r.name} {r.description &&
{r.description}
}
), }, { title: '基础积分', dataIndex: 'credits', width: 100, render: (v: number) => {v.toLocaleString()}, }, { title: '赠送积分', dataIndex: 'bonusCredits', width: 100, render: (v: number) => v > 0 ? +{v.toLocaleString()} : -, }, { title: '总积分', key: 'total', width: 100, render: (_: any, r: PackageItem) => ( {(r.credits + r.bonusCredits).toLocaleString()} ), }, { title: '价格(元)', dataIndex: 'price', width: 100, render: (v: number) => ¥{v}, }, { title: '类型', dataIndex: 'packageType', width: 80, render: (v: string) => {TYPE_LABELS[v] || v}, }, { title: '状态', dataIndex: 'isActive', width: 80, render: (v: boolean) => {v ? '启用' : '停用'}, }, { title: '操作', key: 'action', width: 150, fixed: 'right' as const, render: (_: any, r: PackageItem) => ( handleDelete(r.id)}> ), }, ]; return (
充值套餐管理 {packages.length} 个套餐
{modal.item ? '编辑套餐' : '添加套餐'}} open={modal.open} onOk={handleSave} onCancel={() => { setModal({ open: false, item: null }); form.resetFields(); }} okText="保存" cancelText="取消" width={520} >
); }; export default AdminRechargePackages;