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: detail.canEditDocument ?? 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]); // spec § 八三态 employeeId 映射: // - 新增模式:values.employeeId === undefined 或 0 → 不传 / 显式 null;正整数 → 传 ID // - 编辑模式:undefined → 不变(PATCH 缺省 = 保留原值);0 → 显式发 0(解除关联约定);正整数 → 传 ID const toCreateEmployeeId = (v: number | undefined): number | null | undefined => v == null || v === 0 ? null : v; const toUpdateEmployeeId = (v: number | undefined): number | undefined => v; 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: toCreateEmployeeId(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: toUpdateEmployeeId(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" >
); }