import { useCallback, useEffect, useMemo, useState } from 'react' import { Button, Form, Input, Modal, Popconfirm, Space, Switch, Table, Tabs, Tag, Typography, message } from 'antd' import { DeleteOutlined, EditOutlined, PlusOutlined, ReloadOutlined } from '@ant-design/icons' import type { ColumnsType } from 'antd/es/table' import { platformApi, userApi } from '../api' import { PageHeader } from '../components/PageHeader' import type { MerchantMember, MerchantMemberGroup, PageResult, User } from '../types' import { formatDateTime } from '../utils/time' import { useAuth } from '../store/auth' import { roleText } from './merchantCenterUtils' import { useNavigate } from 'react-router-dom' type AdminFormValues = { username: string nickname?: string password?: string status: boolean } export default function PlatformUsers() { const { user: currentUser } = useAuth() const navigate = useNavigate() const [tab, setTab] = useState('admins') const [admins, setAdmins] = useState>({ list: [], total: 0, page: 1, size: 20 }) const [merchantAccounts, setMerchantAccounts] = useState>({ list: [], total: 0, page: 1, size: 20 }) const [loading, setLoading] = useState(false) const [submitting, setSubmitting] = useState(false) const [editingAdmin, setEditingAdmin] = useState(null) const [modalOpen, setModalOpen] = useState(false) const [form] = Form.useForm() const loadAdmins = useCallback(async (page = admins.page, size = admins.size) => { setLoading(true) try { setAdmins(await userApi.list({ page, size })) } catch (e) { message.error(e instanceof Error ? e.message : '加载失败') } finally { setLoading(false) } }, [admins.page, admins.size]) const loadMerchantAccounts = useCallback(async (page = merchantAccounts.page, size = merchantAccounts.size) => { setLoading(true) try { setMerchantAccounts(await platformApi.merchantAccounts({ page, size })) } catch (e) { message.error(e instanceof Error ? e.message : '加载失败') } finally { setLoading(false) } }, [merchantAccounts.page, merchantAccounts.size]) useEffect(() => { if (tab === 'admins') void loadAdmins() else void loadMerchantAccounts() }, [loadAdmins, loadMerchantAccounts, tab]) const openCreate = () => { setEditingAdmin(null) form.setFieldsValue({ username: '', nickname: '', password: '', status: true }) setModalOpen(true) } const openEdit = (record: User) => { setEditingAdmin(record) form.setFieldsValue({ username: record.username, nickname: record.nickname, password: '', status: record.status === 1 }) setModalOpen(true) } const submit = async () => { const values = await form.validateFields() setSubmitting(true) try { if (editingAdmin) { await userApi.update(editingAdmin.id, { username: values.username, nickname: values.nickname || '', password: values.password || undefined, status: values.status ? 1 : 0, }) message.success('平台管理员已更新') } else { await userApi.create({ username: values.username, password: values.password || '', nickname: values.nickname || '' }) message.success('平台管理员已创建') } setModalOpen(false) form.resetFields() void loadAdmins(editingAdmin ? admins.page : 1) } catch (e) { message.error(e instanceof Error ? e.message : editingAdmin ? '更新失败' : '创建失败') } finally { setSubmitting(false) } } const remove = async (record: User) => { try { await userApi.remove(record.id) message.success('平台管理员已删除') void loadAdmins() } catch (e) { message.error(e instanceof Error ? e.message : '删除失败') } } const columns: ColumnsType = [ { title: '用户名', dataIndex: 'username', width: 260, render: (value) => {value} }, { title: '昵称', dataIndex: 'nickname', width: 220, render: (value) => value || '-' }, { title: '状态', dataIndex: 'status', width: 120, render: (value) => value === 1 ? 启用 : 停用 }, { title: '创建时间', dataIndex: 'created_at', width: 190, render: formatDateTime }, { title: '操作', width: 190, render: (_, record) => record.id === currentUser?.id ? 当前账号 : ( remove(record)} okButtonProps={{ danger: true }}> ), }, ] const memberColumns: ColumnsType = [ { title: '员工账号', dataIndex: ['user', 'username'], width: 260, render: (_, record) => {record.user?.username || `#${record.user_id}`} }, { title: '昵称', dataIndex: ['user', 'nickname'], width: 220, render: (_, record) => record.user?.nickname || '-' }, { title: '商户角色', dataIndex: 'role', width: 160, render: (role) => {roleText(role)} }, { title: '成员状态', dataIndex: 'status', width: 130, render: (status) => status === 1 ? 启用 : 停用 }, ] const merchantColumns: ColumnsType = [ { title: '商户', width: 320, render: (_, record) => {record.merchant?.name || `商户#${record.merchant_id}`}{record.merchant?.code || '-'}, }, { title: '下游账号', width: 130, render: (_, record) => `${record.members.length} 个` }, { title: '角色分布', render: (_, record) => { const roles = [...new Set(record.members.map((member) => member.role))] return {roles.map((role) => {roleText(role)})} }, }, { title: '操作', width: 160, render: (_, record) => , }, ] const items = useMemo(() => [ { key: 'admins', label: `平台管理员 (${admins.total})`, children: void loadAdmins(page, size) }} />, }, { key: 'merchant-accounts', label: `商户账号 (${merchantAccounts.total})`, children:
, rowExpandable: (record) => record.members.length > 0, }} pagination={{ current: merchantAccounts.page, pageSize: merchantAccounts.size, total: merchantAccounts.total, showSizeChanger: true, onChange: (page, size) => void loadMerchantAccounts(page, size) }} />, }, ], [admins, columns, loadAdmins, loadMerchantAccounts, loading, memberColumns, merchantAccounts, merchantColumns]) return (
{tab === 'admins' && }} /> setModalOpen(false)} onOk={() => void submit()} confirmLoading={submitting} okText="保存" destroyOnHidden >
{editingAdmin && }
) }