/** * Static Data Management Page */ import { useState, useEffect } from 'react'; import { Modal, Form, Input, Select } from 'antd'; import type { ColumnsType } from 'antd/es/table'; import { DataTable } from '../../components/admin/DataTable'; import { request } from '../../utils/request'; import { useToast } from '../../contexts/ToastContext'; interface StaticDataItem { id: number; category: string; name: string; name_zh: string; data: any; } export function StaticData() { const [loading, setLoading] = useState(false); const [data, setData] = useState([]); const [filteredData, setFilteredData] = useState([]); const [isModalOpen, setIsModalOpen] = useState(false); const [editingRecord, setEditingRecord] = useState(null); const [form] = Form.useForm(); const toast = useToast(); useEffect(() => { loadData(); }, []); const loadData = async () => { setLoading(true); try { const { data: result } = await request.get('/celestial/static/list'); setData(result.items || []); setFilteredData(result.items || []); } catch (error) { toast.error('加载数据失败'); } finally { setLoading(false); } }; const handleSearch = (keyword: string) => { const lowerKeyword = keyword.toLowerCase(); const filtered = data.filter( (item) => item.name.toLowerCase().includes(lowerKeyword) || item.name_zh?.toLowerCase().includes(lowerKeyword) || item.category.toLowerCase().includes(lowerKeyword) ); setFilteredData(filtered); }; const handleAdd = () => { setEditingRecord(null); form.resetFields(); form.setFieldsValue({ category: 'star' }); setIsModalOpen(true); }; const handleEdit = (record: StaticDataItem) => { setEditingRecord(record); // Convert JSON data to string for editing form.setFieldsValue({ ...record, data: JSON.stringify(record.data, null, 2) }); setIsModalOpen(true); }; const handleDelete = async (record: StaticDataItem) => { try { await request.delete(`/celestial/static/${record.id}`); toast.success('删除成功'); loadData(); } catch (error) { toast.error('删除失败'); } }; const handleModalOk = async () => { try { const values = await form.validateFields(); // Parse JSON data try { values.data = JSON.parse(values.data); } catch (e) { toast.error('JSON格式错误'); return; } if (editingRecord) { await request.put(`/celestial/static/${editingRecord.id}`, values); toast.success('更新成功'); } else { await request.post('/celestial/static', values); toast.success('创建成功'); } setIsModalOpen(false); loadData(); } catch (error) { console.error(error); } }; const columns: ColumnsType = [ { title: 'ID', dataIndex: 'id', width: 80, sorter: (a, b) => a.id - b.id, }, { title: '分类', dataIndex: 'category', width: 120, filters: [ { text: '恒星', value: 'star' }, { text: '星座', value: 'constellation' }, { text: '星系', value: 'galaxy' }, { text: '星云', value: 'nebula' }, { text: '小行星带', value: 'asteroid_belt' }, { text: '柯伊伯带', value: 'kuiper_belt' }, { text: '恒星际', value: 'interstellar' }, ], onFilter: (value, record) => record.category === value, }, { title: '英文名', dataIndex: 'name', sorter: (a, b) => a.name.localeCompare(b.name), }, { title: '中文名', dataIndex: 'name_zh', }, { title: '数据 (JSON)', dataIndex: 'data', ellipsis: true, render: (text) => JSON.stringify(text), }, ]; return ( <> setIsModalOpen(false)} width={700} >
{ try { JSON.parse(value); return Promise.resolve(); } catch (err) { return Promise.reject(new Error('无效的JSON格式')); } } } ]} >
); }