import { useEffect, useState } from 'react'; import { useNavigate, useParams } from 'react-router-dom'; import { Alert, Button, Card, Form, Result, Space, Spin, message } from 'antd'; import { usersApi } from '../../api/users'; import type { CreateUserReq, UpdateUserReq, UserDetail } from '../../api/users'; import { BizError, isBizError } from '../../api/errors'; import { ERROR_MESSAGES } from './usersConstants'; import UserFormFields from './UserFormFields'; import UserPermissionPanel from './UserPermissionPanel'; interface Props { mode: 'create' | 'edit'; } interface FormValues { username?: string; userCode?: string; userType?: 'NORMAL' | 'SUPER_ADMIN'; language?: 'zh-CN' | 'en-US' | 'zh-TW'; canEditDocument?: boolean; employeeId?: number; } export default function UserFormPage({ mode }: Props) { const navigate = useNavigate(); const params = useParams<{ userId?: string }>(); const userId = params.userId ? Number(params.userId) : undefined; const [form] = Form.useForm(); const [loadingInitial, setLoadingInitial] = useState(mode === 'edit'); const [submitting, setSubmitting] = useState(false); const [errorMessage, setErrorMessage] = useState(null); const [notFound, setNotFound] = useState(false); const [permissionCategoryIds, setPermissionCategoryIds] = useState([]); const [originalDetail, setOriginalDetail] = useState(null); useEffect(() => { if (mode !== 'edit' || userId == null) return; let cancelled = false; (async () => { try { const detail = await usersApi.get(userId); if (cancelled) return; setOriginalDetail(detail); form.setFieldsValue({ username: detail.username, userCode: detail.userCode, userType: detail.userType, language: detail.language as FormValues['language'], canEditDocument: false, // detail VO 当前不返回,默认 false employeeId: detail.employeeId ?? undefined, }); setPermissionCategoryIds(detail.permissionCategoryIds ?? []); } catch (e) { if (cancelled) return; if (isBizError(e) && e.code === 40401) { setNotFound(true); } else if (isBizError(e)) { setErrorMessage(e.message || (ERROR_MESSAGES.UNKNOWN as string)); } else { setErrorMessage(ERROR_MESSAGES.UNKNOWN as string); } } finally { if (!cancelled) setLoadingInitial(false); } })(); return () => { cancelled = true; }; }, [mode, userId, form]); const handleSubmit = async (values: FormValues) => { setSubmitting(true); setErrorMessage(null); form.setFields([ { name: 'username', errors: [] }, { name: 'userCode', errors: [] }, ]); try { if (mode === 'create') { await usersApi.create({ username: values.username!, userCode: values.userCode!, userType: values.userType!, language: values.language!, canEditDocument: !!values.canEditDocument, employeeId: values.employeeId, permissionCategoryIds, }); message.success('新增用户成功'); } else if (userId != null) { const patch: UpdateUserReq = { userCode: values.userCode, userType: values.userType, language: values.language, canEditDocument: values.canEditDocument, employeeId: values.employeeId, permissionCategoryIds, }; await usersApi.update(userId, patch); message.success('保存成功'); } navigate('/users'); } catch (e) { handleBizError(e); } finally { setSubmitting(false); } }; const handleBizError = (e: unknown) => { if (!isBizError(e)) { setErrorMessage(ERROR_MESSAGES.UNKNOWN as string); return; } const be = e as BizError; if (be.code === 40901) { form.setFields([{ name: 'username', errors: [ERROR_MESSAGES[40901] as string] }]); } else if (be.code === 40902) { form.setFields([{ name: 'userCode', errors: [ERROR_MESSAGES[40902] as string] }]); } else if (be.code === 40004) { setErrorMessage(ERROR_MESSAGES[40004] as string); } else if (be.code === 40401) { setNotFound(true); } else if (be.code === -1) { setErrorMessage(ERROR_MESSAGES.NETWORK as string); } else { setErrorMessage(be.message || (ERROR_MESSAGES.UNKNOWN as string)); } }; if (notFound) { return (
navigate('/users')}> 返回列表 } />
); } return (
{errorMessage && ( )} form={form} layout="vertical" onFinish={handleSubmit} initialValues={{ userType: 'NORMAL', language: 'zh-CN', canEditDocument: false, }} disabled={submitting || loadingInitial} data-testid="user-form" >
); }