import { useEffect, useState } from 'react' import { useNavigate, useLocation, useParams } from 'react-router-dom' import { message } from 'antd' import { useAppDispatch } from '../../store/hooks' import { openTab } from '../../store/slices/tabsSlice' import { getStaffs, getPermissionGroups, createUser, updateUser } from '../../api/usr' import type { StaffVO, PermissionGroupVO, UserListItemVO, UserCreateReq, UserUpdateReq } from '../../api/usr' // REQ-USR-001: 增加用户 // REQ-USR-002: 修改用户 export default function UserDetailPage() { const { id } = useParams() const navigate = useNavigate() const location = useLocation() const dispatch = useAppDispatch() const isNew = !id const rowData = location.state as UserListItemVO | null const [staffs, setStaffs] = useState([]) const [permGroups, setPermGroups] = useState([]) const [selectedPermIds, setSelectedPermIds] = useState([]) const [submitting, setSubmitting] = useState(false) const [activePermTab, setActivePermTab] = useState(0) const [userCode, setUserCode] = useState('') const [username, setUsername] = useState('') const [userType, setUserType] = useState<'普通用户' | '超级管理员'>('普通用户') const [language, setLanguage] = useState<'中文' | '英文' | '繁体'>('中文') const [canEditDoc, setCanEditDoc] = useState(false) const [isDisabled, setIsDisabled] = useState(false) const [employeeId, setEmployeeId] = useState(null) useEffect(() => { if (!isNew && !rowData) { navigate('/usr/users', { replace: true }) return } dispatch(openTab({ id: 'userdetail', title: '用户信息单据', path: location.pathname, closable: true })) getStaffs().then(setStaffs).catch(() => {}) getPermissionGroups().then(setPermGroups).catch(() => {}) if (!isNew && rowData) { setUserType(rowData.sUserType as '普通用户' | '超级管理员') setLanguage(rowData.sLanguage as '中文' | '英文' | '繁体') setCanEditDoc(rowData.bCanEditDoc === 1) setIsDisabled(rowData.bIsDisabled === 1) } }, []) // eslint-disable-line react-hooks/exhaustive-deps async function handleSave() { if (isNew) { if (!userCode.trim()) { message.error('请输入用户号'); return } if (!username.trim()) { message.error('请输入用户名'); return } } setSubmitting(true) try { if (isNew) { const req: UserCreateReq = { userCode, username, userType, language, canEditDoc, employeeId, permGroupIds: selectedPermIds } await createUser(req) message.success('新增用户成功') } else { const req: UserUpdateReq = { userType, language, canEditDoc, isDisabled, employeeId, permGroupIds: selectedPermIds } await updateUser(id!, req) message.success('修改用户成功') } navigate('/usr/users') } catch (e: unknown) { if (e instanceof Error) message.error(e.message) } finally { setSubmitting(false) } } const PERM_TABS = ['权限组', '客户查看权限', '供应商查看权限', '人员查看权限', '工序查看权限', '司机查看权限'] const fieldBg = 'var(--color-field-bg-edit)' const readonlyBg = 'var(--color-form-bg-readonly)' const inputStyle: React.CSSProperties = { flex: 1, height: 28, border: '1px solid #d5d8de', borderRadius: 2, padding: '0 10px', background: fieldBg, minWidth: 0, fontSize: 13, fontFamily: 'inherit' } const roStyle: React.CSSProperties = { flex: 1, height: 28, border: '1px solid #d5d8de', borderRadius: 2, padding: '0 10px', background: readonlyBg, color: '#444', display: 'flex', alignItems: 'center', fontSize: 13, minWidth: 0, overflow: 'hidden' } const selectStyle: React.CSSProperties = { ...inputStyle, padding: '0 8px' } const cellStyle: React.CSSProperties = { display: 'flex', alignItems: 'center', gap: 6, padding: '8px 10px' } const lblStyle: React.CSSProperties = { minWidth: 88, color: '#333', fontSize: 13, textAlign: 'right', flexShrink: 0 } const reqLblStyle: React.CSSProperties = { ...lblStyle, color: 'var(--color-field-label-req)' } return (
{/* Dark toolbar */}
{[ { label: '⊕ 新增', onClick: () => navigate('/usr/users/new'), disabled: false }, { label: '✎ 修改', onClick: undefined, disabled: true }, { label: '🗑 删除', onClick: undefined, disabled: true, title: '功能待实现' }, { label: '💾 保存', onClick: handleSave, disabled: submitting }, { label: '✕ 取消', onClick: () => navigate('/usr/users'), disabled: false }, { label: '作废', onClick: undefined, disabled: true, title: '功能待实现' }, { label: '重置密码', onClick: undefined, disabled: true, title: '功能待实现' }, ].map(btn => ( ))}
{/* 3-column form grid */}
{/* Row 1: 创建时间 / 制单人 / 员工名 */}
创建时间:
{isNew ? '' : rowData?.tCreateDate}
制单人:
{isNew ? '保存后自动生成' : rowData?.sCreatorUsername}
*员工名:
{/* Row 2: 用户名 / 类型 / 语言 */}
{isNew ? '*用户名:' : '用户名:'} {isNew ? setUsername(e.target.value)} placeholder="请输入用户名" style={inputStyle} /> :
{rowData?.sUsername}
}
*类型:
*语言:
{/* Row 3: 用户号 / (empty) / 单据修改权限 */}
{isNew ? '*用户号:' : '用户号:'} {isNew ? setUserCode(e.target.value)} placeholder="请输入用户号" style={inputStyle} /> :
{rowData?.sUserCode}
}
单据修改权限: setCanEditDoc(e.target.checked)} style={{ width: 14, height: 14 }} />
{/* Permission tabs row */}
{PERM_TABS.map((tab, i) => (
setActivePermTab(i)} style={{ padding: '11px 18px', fontSize: 14, color: i === activePermTab ? 'var(--color-tab-active)' : '#444', cursor: 'pointer', borderBottom: i === activePermTab ? `2px solid var(--color-tab-active)` : 'none', marginRight: 4 }} > {tab}
))}
{/* Permission list KNOWN LIMITATION (edit mode): UserListItemVO does not include permGroupIds (backend list API does not return them). In edit mode, selectedPermIds starts empty — saving will overwrite existing permissions with whatever the user selects here. A future backend GET /usr/users/:id endpoint should return permGroupIds so they can be pre-populated. */} {!isNew && activePermTab === 0 && (
⚠ 编辑模式下权限组未预加载(后端列表接口不返回 permGroupIds)。保存将以当前勾选为准,请重新勾选所需权限组。
)}
权限分类
{activePermTab === 0 ? permGroups.map(pg => (
setSelectedPermIds(prev => e.target.checked ? [...prev, pg.sId] : prev.filter(x => x !== pg.sId))} style={{ width: 14, height: 14, flexShrink: 0 }} /> {pg.sGroupName}
)) :
功能待实现
}
) }