import { useEffect, useState, useCallback } from 'react' import { Table, Button, Modal, Form, Input, Select, Switch, Space, message, Popconfirm, Tag, Row, Col, } from 'antd' import { PlusOutlined, DeleteOutlined } from '@ant-design/icons' import { getKeywords, createKeywords, updateKeyword, deleteKeyword, type Keyword } from '../api' const { Option } = Select const { TextArea } = Input function formatDateTime(dateStr: string) { return new Date(dateStr).toLocaleString('zh-CN') } const tagColors: Record = { seed: 'volcano', '机场': 'blue', VPN: 'green', } const industryOptions = [ { label: '搜索关键词', value: '机场' }, { label: '种子频道', value: 'seed' }, { label: 'VPN', value: 'VPN' }, ] interface BatchFormValues { keywords_text: string industry_tag: string } export default function Keywords() { const [data, setData] = useState([]) const [total, setTotal] = useState(0) const [page, setPage] = useState(1) const [loading, setLoading] = useState(false) const [modalOpen, setModalOpen] = useState(false) const [saving, setSaving] = useState(false) const [filterTag, setFilterTag] = useState('') const [form] = Form.useForm() const fetchData = useCallback(async (currentPage = 1) => { setLoading(true) try { const params: Record = { page: currentPage, page_size: 20 } if (filterTag) params.industry_tag = filterTag const res = await getKeywords(params) setData(res.data.items) setTotal(res.data.total) } catch { message.error('获取关键词列表失败') } finally { setLoading(false) } }, [filterTag]) useEffect(() => { setPage(1) fetchData(1) }, [filterTag, fetchData]) const handleBatchAdd = () => { form.resetFields() setModalOpen(true) } const handleSave = async () => { try { const values = await form.validateFields() const keywords = values.keywords_text .split('\n') .map((k: string) => k.trim()) .filter((k: string) => k.length > 0) if (keywords.length === 0) { message.warning('请输入至少一个关键词') return } setSaving(true) await createKeywords({ keywords, industry_tag: values.industry_tag }) message.success(`成功添加 ${keywords.length} 个条目`) setModalOpen(false) fetchData(page) } catch (err) { if (err && typeof err === 'object' && 'errorFields' in err) return message.error('添加失败') } finally { setSaving(false) } } const handleDelete = async (id: number) => { try { await deleteKeyword(id) message.success('删除成功') fetchData(page) } catch { message.error('删除失败') } } const handleToggle = async (record: Keyword, checked: boolean) => { try { await updateKeyword(record.id, { enabled: checked }) message.success('状态已更新') fetchData(page) } catch { message.error('状态更新失败') } } const columns = [ { title: 'ID', dataIndex: 'id', key: 'id', width: 70 }, { title: '关键词/频道名', dataIndex: 'keyword', key: 'keyword', }, { title: '类型', dataIndex: 'industry_tag', key: 'industry_tag', render: (v: string) => {v || '未分类'}, }, { title: '启用', dataIndex: 'enabled', key: 'enabled', render: (v: boolean, record: Keyword) => ( handleToggle(record, checked)} checkedChildren="启用" unCheckedChildren="禁用" /> ), }, { title: '创建时间', dataIndex: 'created_at', key: 'created_at', render: (t: string) => formatDateTime(t), }, { title: '操作', key: 'action', render: (_: unknown, record: Keyword) => ( handleDelete(record.id)} okText="确认" cancelText="取消" > ), }, ] return (
{ setPage(p) fetchData(p) }, showTotal: (t) => `共 ${t} 条`, }} /> setModalOpen(false)} confirmLoading={saving} okText="添加" cancelText="取消" >