import { useEffect, useState, useCallback } from 'react'; import { Table, Switch, Modal, Form, Input, Button, Space, Typography, message, Card, } from 'antd'; import { EditOutlined } from '@ant-design/icons'; import { listLanguages, updateLanguage, type LanguageInfo, } from '../../api/languages'; // --- Component --- export default function LanguageManager() { const [languages, setLanguages] = useState([]); const [loading, setLoading] = useState(false); const [editModalOpen, setEditModalOpen] = useState(false); const [editingLang, setEditingLang] = useState(null); const [editForm] = Form.useForm(); const fetchLanguages = useCallback(async () => { setLoading(true); try { const result = await listLanguages(); setLanguages(result); } catch { message.error('加载语言列表失败'); } setLoading(false); }, []); useEffect(() => { fetchLanguages(); }, [fetchLanguages]); // --- Enable / Disable Toggle --- const handleToggle = async (record: LanguageInfo, enabled: boolean) => { try { await updateLanguage(record.code, { enabled }); setLanguages((prev) => prev.map((lang) => lang.code === record.code ? { ...lang, enabled } : lang, ), ); message.success(enabled ? '已启用' : '已禁用'); } catch { message.error('操作失败'); } }; // --- Edit Modal --- const openEdit = (lang: LanguageInfo) => { setEditingLang(lang); editForm.setFieldsValue({ name: lang.name, translations: lang.translations ? Object.entries(lang.translations) .map(([key, value]) => `${key}=${value}`) .join('\n') : '', }); setEditModalOpen(true); }; const closeEdit = () => { setEditModalOpen(false); setEditingLang(null); editForm.resetFields(); }; const handleEditSubmit = async (values: { name: string; translations: string }) => { if (!editingLang) return; const translations: Record = {}; if (values.translations?.trim()) { for (const line of values.translations.split('\n')) { const trimmed = line.trim(); if (!trimmed) continue; const eqIndex = trimmed.indexOf('='); if (eqIndex === -1) continue; const key = trimmed.slice(0, eqIndex).trim(); const val = trimmed.slice(eqIndex + 1).trim(); if (key) { translations[key] = val; } } } try { const updated = await updateLanguage(editingLang.code, { name: values.name, translations, }); setLanguages((prev) => prev.map((lang) => lang.code === editingLang.code ? updated : lang, ), ); message.success('语言更新成功'); closeEdit(); } catch (err: unknown) { const errorMsg = (err as { response?: { data?: { message?: string } } })?.response?.data ?.message || '更新失败'; message.error(errorMsg); } }; // --- Columns --- const columns = [ { title: '语言代码', dataIndex: 'code', key: 'code', width: 160, }, { title: '语言名称', dataIndex: 'name', key: 'name', width: 200, }, { title: '状态', dataIndex: 'enabled', key: 'enabled', width: 120, render: (enabled: boolean, record: LanguageInfo) => ( handleToggle(record, checked)} /> ), }, { title: '翻译条目数', key: 'translationCount', width: 140, render: (_: unknown, record: LanguageInfo) => record.translations ? Object.keys(record.translations).length : 0, }, { title: '操作', key: 'actions', render: (_: unknown, record: LanguageInfo) => ( ), }, ]; return (
语言管理 {/* Edit Modal */} editForm.submit()} >
); }