import React, { useEffect, useState, useMemo } from 'react'; import { Table, Modal, Form, Input, Select, Space, message, Tag, Popconfirm } from 'antd'; import { PlusOutlined, InboxOutlined } from '@ant-design/icons'; import api from '../../api'; import PermissionButton from '../../components/PermissionButton'; const PRESET_COLORS = [ '#ff7875', '#ffa940', '#ffc53d', '#73d13d', '#36cfc9', '#40a9ff', '#597ef7', '#9254de', '#f759ab', '#8c8c8c', ]; const TenantsPage: React.FC = () => { const [data, setData] = useState([]); const [loading, setLoading] = useState(false); const [modalOpen, setModalOpen] = useState(false); const [editing, setEditing] = useState(null); const [form] = Form.useForm(); const [saving, setSaving] = useState(false); const [searchText, setSearchText] = useState(''); const [filterStatus, setFilterStatus] = useState(undefined); const filteredData = useMemo(() => { let result = data; if (searchText) { const s = searchText.toLowerCase(); result = result.filter((d: Record) => (typeof d.name === 'string' && d.name.toLowerCase().includes(s)) || (typeof d.contact === 'string' && d.contact.toLowerCase().includes(s))); } if (filterStatus) result = result.filter((d: Record) => d.status === filterStatus); return result; }, [data, searchText, filterStatus]); const fetchData = async () => { setLoading(true); try { const res: any = await api.get('/tenants'); setData(res); } catch (e) { console.error(e); } setLoading(false); }; useEffect(() => { fetchData(); }, []); const handleSave = async () => { const values = await form.validateFields(); setSaving(true); try { if (editing) { await api.put(`/tenants/${editing.id}`, values); message.success('更新成功'); } else { await api.post('/tenants', values); message.success('创建成功'); } setModalOpen(false); form.resetFields(); setEditing(null); fetchData(); } catch (e: any) { message.error(e?.message || '操作失败'); } finally { setSaving(false); } }; const handleArchive = async (id: number) => { try { await api.delete(`/tenants/${id}`); message.success('已归档'); fetchData(); } catch (e: any) { message.error(e?.message || '归档失败'); } }; const columns = useMemo(() => [ { title: '租赁方名称', width: 120, dataIndex: 'name', render: (v: string, r: any) => ( {v} ), }, { title: '联系人', dataIndex: 'contact', width: 100, render: (v: string) => v || '-' }, { title: '电话', dataIndex: 'phone', width: 120, render: (v: string) => v || '-' }, { title: '颜色', width: 80, dataIndex: 'color', render: (v: string) => v ? ( ) : ( '-' ), }, { title: '备注', dataIndex: 'notes', ellipsis: true, render: (v: string) => v || '-' }, { title: '操作', width: 150, render: (_: any, record: any) => ( { setEditing(record); form.setFieldsValue(record); setModalOpen(true); }} > 编辑 handleArchive(record.id)} okText="归档" cancelText="取消" > }> 归档 ), }, ], [handleArchive]); return (
setSearchText(v)} onChange={(e) => { if (!e.target.value) setSearchText(''); }} /> {PRESET_COLORS.map((c) => ( form.setFieldValue('color', c)} onKeyDown={(e) => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); form.setFieldValue('color', c); } }} style={{ display: 'inline-block', width: 28, height: 28, background: c, borderRadius: 3, cursor: 'pointer', border: '1px solid #d9d9d9', }} /> ))}
); }; export default TenantsPage;