import React, { useEffect, useState } from 'react'; import { Button, Card, Space, Table, Tag, Typography, message, Modal, Form, Input, InputNumber, Upload, } from 'antd'; import { HistoryOutlined, ReloadOutlined, PlusOutlined, UploadOutlined, EyeOutlined, EditOutlined, DeleteOutlined, } from '@ant-design/icons'; import { getOpenTypeList, getOpenType, createOpenType, updateOpenType, deleteOpenType, uploadImage } from '../api'; import { formatDate } from '../utils/formatDate'; interface OpenType { id: string; openType: number; typeName: string; description: string; thumb?: string; createdAt: string; updatedAt: string; } const normalizeUploadError = (e: unknown): Error => { if (e instanceof Error) { return e; } if (typeof e === 'string') { return new Error(e); } return new Error('上传失败'); }; const assertUploadFile = (file: unknown): File => { if (file instanceof File) { return file; } throw new Error('请选择有效图片文件'); }; const AdminPlatform: React.FC = () => { const [openTypes, setOpenTypes] = useState([]); const [total, setTotal] = useState(0); const [loading, setLoading] = useState(false); const [page, setPage] = useState(1); const [pageSize, setPageSize] = useState(20); const [createModalVisible, setCreateModalVisible] = useState(false); const [detailModalVisible, setDetailModalVisible] = useState(false); const [updateModalVisible, setUpdateModalVisible] = useState(false); const [currentOpenType, setCurrentOpenType] = useState(null); const [createThumbUrl, setCreateThumbUrl] = useState(''); const [updateThumbUrl, setUpdateThumbUrl] = useState(''); const [createForm] = Form.useForm(); const [updateForm] = Form.useForm(); const load = async (p?: number, ps?: number) => { setLoading(true); try { const res = await getOpenTypeList({ page: p || page, page_size: ps || pageSize, }); setOpenTypes(res.data || []); setTotal(res.pagination.total || 0); } catch { message.error('加载开户方式列表失败'); } finally { setLoading(false); } }; useEffect(() => { load(); }, []); const handleCreate = async () => { try { const values = await createForm.validateFields(); const thumbUrl = createThumbUrl; const thumbPath = thumbUrl.startsWith('http') ? thumbUrl.replace(/^https?:\/\/[^/]+/, '') : thumbUrl; await createOpenType({ open_type: values.open_type, type_name: values.type_name, description: values.description, thumb: thumbPath, }); message.success('创建成功'); setCreateModalVisible(false); createForm.resetFields(); setCreateThumbUrl(''); load(); } catch (e: any) { message.error(e?.message || '创建失败'); } }; const handleDetail = async (id: string) => { try { const openType = await getOpenType(id); setCurrentOpenType(openType.data || {}); setDetailModalVisible(true); } catch (e: any) { message.error(e?.message || '获取详情失败'); } }; const handleUpdate = async (id: string) => { try { const openType = await getOpenType(id); const thumb = openType.data?.thumb || ''; const baseUrl = import.meta.env.VITE_API_BASE || 'http://localhost:8000'; const fullThumbUrl = thumb.startsWith('http') ? thumb : `${baseUrl}${thumb}`; setCurrentOpenType(openType.data || {}); setUpdateThumbUrl(fullThumbUrl); setUpdateModalVisible(true); } catch (e: any) { message.error(e?.message || '获取详情失败'); } }; const handleSaveUpdate = async () => { if (!currentOpenType) return; try { const values = await updateForm.validateFields(); const thumbUrl = updateThumbUrl; const thumbPath = thumbUrl.startsWith('http') ? thumbUrl.replace(/^https?:\/\/[^/]+/, '') : thumbUrl; await updateOpenType(currentOpenType.id, { open_type: values.open_type, type_name: values.type_name, description: values.description, thumb: thumbPath, }); message.success('更新成功'); setUpdateModalVisible(false); updateForm.resetFields(); setCurrentOpenType(null); setUpdateThumbUrl(''); load(); } catch (e: any) { message.error(e?.message || '更新失败'); } }; const handleDelete = (id: string) => { Modal.confirm({ title: '确认删除', content: '确定要删除这个开户方式吗?', okText: '删除', okType: 'danger', cancelText: '取消', onOk: async () => { try { await deleteOpenType(id); message.success('删除成功'); load(); } catch (e: any) { message.error(e?.message || '删除失败'); } }, }); }; const columns = [ { title: 'ID', dataIndex: 'id', width: 100, render: (v: string) => {v}, }, { title: '开户类型', dataIndex: 'openType', width: 100, render: (v: number) => {v}, }, { title: '类型名称', dataIndex: 'typeName', width: 150, render: (v: string) => {v}, }, { title: '描述', dataIndex: 'description', width: 250, ellipsis: true, render: (v: string) => ( {v} ), }, { title: '缩略图', dataIndex: 'thumb', width: 120, render: (v: string) => { if (!v) return '-'; const baseUrl = import.meta.env.VITE_API_BASE || 'http://localhost:8000'; const fullUrl = v.startsWith('http') ? v : `${baseUrl}${v}`; return thumb; }, }, { title: '创建时间', dataIndex: 'createdAt', width: 160, render: (v: string) => ( {formatDate(v)} ), }, { title: '更新时间', dataIndex: 'updatedAt', width: 160, render: (v: string) => ( {formatDate(v)} ), }, { title: '操作', width: 240, render: (_: any, record: OpenType) => ( ), }, ]; return (
平台开户方式管理
`共 ${t} 条记录`, onChange: (p, ps) => { setPage(p); setPageSize(ps); load(p, ps); }, }} scroll={{ x: 1000 }} /> { setCreateModalVisible(false); createForm.resetFields(); setCreateThumbUrl(''); }} mask={{ closable: false }} okText="创建" cancelText="取消" width={600} >
{ try { const uploadFile = assertUploadFile(file); const res = await uploadImage(uploadFile); const baseUrl = import.meta.env.VITE_API_BASE || 'http://localhost:8000'; const fullUrl = res.url.startsWith('http') ? res.url : `${baseUrl}${res.url}`; setCreateThumbUrl(fullUrl); onSuccess?.({ url: fullUrl }); } catch (e) { onError?.(normalizeUploadError(e)); } }} onRemove={() => setCreateThumbUrl('')} > {!createThumbUrl && (
上传图片
)}
setDetailModalVisible(false)} onCancel={() => { setDetailModalVisible(false); setCurrentOpenType(null); }} mask={{ closable: false }} okText="关闭" cancelText="取消" width={520} > {currentOpenType && (
{currentOpenType.thumb ? ( thumb ) : ( 暂无图片 )}
{currentOpenType.typeName}
开户类型: {currentOpenType.openType}
ID {currentOpenType.id}
开户类型 {currentOpenType.openType}
类型名称 {currentOpenType.typeName}
描述
{currentOpenType.description || '-'}
创建时间 {formatDate(currentOpenType.createdAt)}
更新时间 {formatDate(currentOpenType.updatedAt)}
)}
{ setUpdateModalVisible(false); updateForm.resetFields(); setCurrentOpenType(null); }} afterOpenChange={(open) => { if (open && currentOpenType) { updateForm.setFieldsValue({ open_type: currentOpenType.openType, type_name: currentOpenType.typeName, description: currentOpenType.description, }); } }} mask={{ closable: false }} okText="更新" cancelText="取消" width={600} >
{ try { const uploadFile = assertUploadFile(file); const res = await uploadImage(uploadFile); const baseUrl = import.meta.env.VITE_API_BASE || 'http://localhost:8000'; const fullUrl = res.url.startsWith('http') ? res.url : `${baseUrl}${res.url}`; setUpdateThumbUrl(fullUrl); onSuccess?.({ url: fullUrl }); } catch (e) { onError?.(normalizeUploadError(e)); } }} onRemove={() => setUpdateThumbUrl('')} > {!updateThumbUrl && (
上传图片
)}
); }; export default AdminPlatform;