import * as React from 'react'; import { Modal, Table, Input, Select, Space, message, Tree, Divider, Button } from 'antd'; import type { TableColumnsType } from 'antd'; import type { DataNode } from 'antd/es/tree'; import { Tree as TreeIcon, Group, Search } from 'iconoir-react'; import './VipSelector.scss'; interface VipUser { userId: string; userName: string; nickName: string; deptName: string; deptId: string; userTypeName: string; } interface Department { deptId: string; deptName: string; children?: Department[]; } interface VipSelectorProps { open: boolean; onClose: () => void; onConfirm: (users: VipUser[]) => void; existingUsers?: VipUser[]; } // Mock 数据 - 部门树 const mockDepartments: Department[] = [ { deptId: 'dept_001', deptName: '政务服务中心', children: [ { deptId: 'dept_001_01', deptName: '窗口服务科' }, { deptId: 'dept_001_02', deptName: '在线咨询科' }, ], }, { deptId: 'dept_002', deptName: '市场监管局', children: [ { deptId: 'dept_002_01', deptName: '企业注册科' }, { deptId: 'dept_002_02', deptName: '质量监管科' }, ], }, { deptId: 'dept_003', deptName: '大数据局', children: [ { deptId: 'dept_003_01', deptName: '数据共享科' }, { deptId: 'dept_003_02', deptName: '智慧城市科' }, ], }, { deptId: 'dept_004', deptName: '财政局', children: [ { deptId: 'dept_004_01', deptName: '预算科' }, { deptId: 'dept_004_02', deptName: '国库科' }, ], }, { deptId: 'dept_005', deptName: '人社局', children: [ { deptId: 'dept_005_01', deptName: '社保科' }, { deptId: 'dept_005_02', deptName: '就业科' }, ], }, ]; // Mock 数据 - 用户列表(带部门关联) const mockUserList: VipUser[] = [ { userId: 'user_001', userName: 'zhangsan', nickName: '张三', deptName: '政务服务中心', deptId: 'dept_001', userTypeName: '普通用户' }, { userId: 'user_002', userName: 'lisi', nickName: '李四', deptName: '市场监管局', deptId: 'dept_002', userTypeName: 'VIP 用户' }, { userId: 'user_003', userName: 'wangwu', nickName: '王五', deptName: '大数据局', deptId: 'dept_003', userTypeName: '管理员' }, { userId: 'user_004', userName: 'zhaoliu', nickName: '赵六', deptName: '财政局', deptId: 'dept_004', userTypeName: '普通用户' }, { userId: 'user_005', userName: 'qianqi', nickName: '钱七', deptName: '人社局', deptId: 'dept_005', userTypeName: 'VIP 用户' }, { userId: 'user_006', userName: 'sunba', nickName: '孙八', deptName: '政务服务中心', deptId: 'dept_001', userTypeName: '普通用户' }, { userId: 'user_007', userName: 'zhoujiu', nickName: '周九', deptName: '市场监管局', deptId: 'dept_002', userTypeName: '管理员' }, { userId: 'user_008', userName: 'zhengshi', nickName: '郑十', deptName: '大数据局', deptId: 'dept_003', userTypeName: 'VIP 用户' }, { userId: 'user_009', userName: 'wushi', nickName: '吴十', deptName: '财政局', deptId: 'dept_004', userTypeName: '普通用户' }, { userId: 'user_010', userName: 'zhengyi', nickName: '郑十一', deptName: '人社局', deptId: 'dept_005', userTypeName: '管理员' }, ]; // 将部门树转换为 Tree 组件需要的格式 const convertToTreeData = (departments: Department[]): DataNode[] => { return departments.map(dept => ({ title: dept.deptName, key: dept.deptId, children: dept.children?.map(child => ({ title: child.deptName, key: child.deptId, isLeaf: true, })), })); }; const VipSelector: React.FC = ({ open, onClose, onConfirm, existingUsers = [] }) => { const [selectedRowKeys, setSelectedRowKeys] = React.useState([]); const [selectedDeptId, setSelectedDeptId] = React.useState(''); const [searchUserName, setSearchUserName] = React.useState(''); const [searchNickName, setSearchNickName] = React.useState(''); const [searchUserType, setSearchUserType] = React.useState(); // 初始化选中项为已选的 VIP 用户 React.useEffect(() => { if (open) { setSelectedRowKeys(existingUsers.map(item => item.userId)); } }, [open, existingUsers]); // 部门树选择处理 const onDeptSelect: TreeProps['onSelect'] = (selectedKeys) => { if (selectedKeys.length > 0) { setSelectedDeptId(selectedKeys[0] as string); } else { setSelectedDeptId(''); } }; // 根据部门和筛选条件过滤用户 const filteredUsers = mockUserList.filter(user => { const matchDept = !selectedDeptId || user.deptId === selectedDeptId || mockDepartments.some(d => d.deptId === selectedDeptId && user.deptId === d.deptId); const matchUserName = !searchUserName || user.userName.toLowerCase().includes(searchUserName.toLowerCase()); const matchNickName = !searchNickName || user.nickName.includes(searchNickName); const matchUserType = !searchUserType || user.userTypeName === searchUserType; return matchDept && matchUserName && matchNickName && matchUserType; }); const columns: TableColumnsType = [ { title: '昵称', dataIndex: 'nickName', key: 'nickName', width: 100, }, { title: '用户名称', dataIndex: 'userName', key: 'userName', width: 120, }, { title: '部门', dataIndex: 'deptName', key: 'deptName', width: 140, }, { title: '用户类型', dataIndex: 'userTypeName', key: 'userTypeName', width: 100, }, ]; const rowSelection = { selectedRowKeys, onChange: (newSelectedRowKeys: React.Key[]) => { setSelectedRowKeys(newSelectedRowKeys); }, }; const handleConfirm = () => { const selectedUsers = filteredUsers.filter(user => selectedRowKeys.includes(user.userId) ); onConfirm(selectedUsers); message.success(`已选择 ${selectedUsers.length} 个用户`); }; const handleSelectAll = () => { setSelectedRowKeys(filteredUsers.map(user => user.userId)); }; const handleClearAll = () => { setSelectedRowKeys([]); }; return (
{/* 左侧:部门树 */}
选择部门
已选:{selectedRowKeys.length} 人
{/* 右侧:用户列表 */}
用户列表 {selectedDeptId && ( {mockDepartments.find(d => d.deptId === selectedDeptId)?.deptName || '已筛选'} )}
{/* 筛选条件 */} setSearchUserName(e.target.value)} style={{ width: 140 }} allowClear prefix={} /> setSearchNickName(e.target.value)} style={{ width: 120 }} allowClear /> {/* 用户表格 */} `共 ${total} 条`, showSizeChanger: false, showQuickJumper: true, current: 1, pageSize: 10, total: filteredUsers.length, }} scroll={{ y: 360 }} size="small" /> ); }; export default VipSelector;