/** * 用户详情页 */ import React, { useState, useEffect } from 'react'; import { Card, Descriptions, Button, Space, Tag, Spin, message, Typography, Row, Col, Table, Modal, Tooltip, Empty, } from 'antd'; import { ArrowLeftOutlined, EditOutlined, KeyOutlined, StopOutlined, CheckCircleOutlined, PlusOutlined, DeleteOutlined, SettingOutlined, ExclamationCircleOutlined, } from '@ant-design/icons'; import { useNavigate, useParams } from 'react-router-dom'; import type { ColumnsType } from 'antd/es/table'; import * as userApi from '../api/userApi'; import type { UserDetail, TenantMembership, TenantOption, UserRole } from '../types/user'; import { ROLE_DISPLAY_NAMES, ROLE_COLORS, TENANT_TYPE_NAMES } from '../types/user'; import AssignTenantModal from '../components/AssignTenantModal'; import ModulePermissionModal from '../components/ModulePermissionModal'; const { Title, Text } = Typography; const UserDetailPage: React.FC = () => { const navigate = useNavigate(); const { id } = useParams<{ id: string }>(); const [loading, setLoading] = useState(true); const [user, setUser] = useState(null); const [tenantOptions, setTenantOptions] = useState([]); const [assignTenantVisible, setAssignTenantVisible] = useState(false); const [modulePermissionVisible, setModulePermissionVisible] = useState(false); const [selectedMembership, setSelectedMembership] = useState(null); // 加载用户详情 const loadUser = async () => { if (!id) return; setLoading(true); try { const data = await userApi.getUserById(id); setUser(data); } catch (error) { console.error('加载用户详情失败:', error); message.error('加载用户详情失败'); } finally { setLoading(false); } }; useEffect(() => { loadUser(); userApi.getTenantOptions().then(setTenantOptions).catch(console.error); }, [id]); // 处理状态切换 const handleToggleStatus = () => { if (!user) return; const newStatus = user.status === 'active' ? 'disabled' : 'active'; const actionText = newStatus === 'active' ? '启用' : '禁用'; Modal.confirm({ title: `确认${actionText}`, icon: , content: `确定要${actionText}用户 "${user.name}" 吗?`, onOk: async () => { try { await userApi.updateUserStatus(user.id, newStatus); message.success(`${actionText}成功`); loadUser(); } catch (error) { message.error(`${actionText}失败`); } }, }); }; // 处理重置密码 const handleResetPassword = () => { if (!user) return; Modal.confirm({ title: '确认重置密码', icon: , content: (

确定要重置用户 "{user.name}" 的密码吗?

重置后密码将变为默认密码:123456

), onOk: async () => { try { await userApi.resetUserPassword(user.id); message.success('密码已重置'); loadUser(); } catch (error) { message.error('重置密码失败'); } }, }); }; // 处理移除租户 const handleRemoveTenant = (membership: TenantMembership) => { if (!user) return; if (membership.tenantId === user.defaultTenant.id) { message.warning('不能移除用户的默认租户'); return; } Modal.confirm({ title: '确认移除租户', icon: , content: `确定要从租户 "${membership.tenantName}" 移除该用户吗?`, onOk: async () => { try { await userApi.removeTenantFromUser(user.id, membership.tenantId); message.success('移除成功'); loadUser(); } catch (error) { message.error('移除失败'); } }, }); }; // 打开模块权限配置 const handleConfigModules = (membership: TenantMembership) => { setSelectedMembership(membership); setModulePermissionVisible(true); }; // 租户成员表格列 const tenantColumns: ColumnsType = [ { title: '租户', key: 'tenant', render: (_, record) => ( {record.tenantName} {user?.defaultTenant.id === record.tenantId && ( 默认 )} {TENANT_TYPE_NAMES[record.tenantType]} · {record.tenantCode} ), }, { title: '角色', dataIndex: 'role', key: 'role', width: 120, render: (role: UserRole) => ( {ROLE_DISPLAY_NAMES[role]} ), }, { title: '模块权限', key: 'modules', render: (_, record) => { const enabledModules = record.allowedModules.filter((m) => m.isEnabled); if (enabledModules.length === 0) { return 无模块权限; } return ( {enabledModules.slice(0, 4).map((m) => ( {m.name} ))} {enabledModules.length > 4 && ( m.name).join('、')}> +{enabledModules.length - 4} )} ); }, }, { title: '加入时间', dataIndex: 'joinedAt', key: 'joinedAt', width: 160, render: (date) => new Date(date).toLocaleString('zh-CN'), }, { title: '操作', key: 'action', width: 120, render: (_, record) => ( 用户详情 {user.name} {user.phone} {user.email || '-'} {ROLE_DISPLAY_NAMES[user.role]} {user.status === 'active' ? '正常' : '已禁用'} {user.isDefaultPassword ? ( 默认密码 ) : ( 已修改 )} {user.defaultTenant.name} ({user.defaultTenant.code}) {user.department?.name || '-'} {new Date(user.createdAt).toLocaleString('zh-CN')} {user.lastLoginAt ? new Date(user.lastLoginAt).toLocaleString('zh-CN') : '从未登录'} {/* 租户关系卡片 */} 租户关系 {/* 分配租户弹窗 */} m.tenantId)} tenantOptions={tenantOptions} onClose={() => setAssignTenantVisible(false)} onSuccess={() => { setAssignTenantVisible(false); loadUser(); }} /> {/* 模块权限配置弹窗 */} {selectedMembership && ( { setModulePermissionVisible(false); setSelectedMembership(null); }} onSuccess={() => { setModulePermissionVisible(false); setSelectedMembership(null); loadUser(); }} /> )} ); }; export default UserDetailPage;