fix: parallel fetches, error handling, extract UserTreeNode component
This commit is contained in:
@@ -53,6 +53,33 @@ interface ImportUsersResponse {
|
||||
skipped: number;
|
||||
}
|
||||
|
||||
const UserTreeNode: React.FC<{
|
||||
u: { userid: string; name: string; mobile: string };
|
||||
isTeacher: boolean;
|
||||
onToggle: () => void;
|
||||
roleId: number | undefined;
|
||||
defaultRoleId: number | null;
|
||||
roles: Array<{ id: number; name: string }>;
|
||||
onRoleChange: (roleId: number) => void;
|
||||
}> = React.memo(({ u, isTeacher, onToggle, roleId, defaultRoleId, roles, onRoleChange }) => (
|
||||
<Space size="small">
|
||||
<Checkbox checked={isTeacher} onChange={onToggle}>老师</Checkbox>
|
||||
<span style={{ fontWeight: 500 }}>{u.name}</span>
|
||||
{u.mobile && <Tag style={{ marginLeft: 4 }}>{u.mobile}</Tag>}
|
||||
{isTeacher && (
|
||||
<Select
|
||||
size="small"
|
||||
style={{ width: 100, marginLeft: 8 }}
|
||||
value={roleId || defaultRoleId}
|
||||
onChange={onRoleChange}
|
||||
options={roles.map((r) => ({ label: r.name, value: r.id }))}
|
||||
placeholder="选择角色"
|
||||
onClick={(e: React.MouseEvent) => e.stopPropagation()}
|
||||
/>
|
||||
)}
|
||||
</Space>
|
||||
));
|
||||
|
||||
const IntegrationConfigPage: React.FC = () => {
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [saving, setSaving] = useState(false);
|
||||
@@ -91,8 +118,7 @@ const IntegrationConfigPage: React.FC = () => {
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
fetchConfig();
|
||||
fetchRoles();
|
||||
void Promise.all([fetchConfig(), fetchRoles()]);
|
||||
}, []);
|
||||
|
||||
const handleSave = async () => {
|
||||
@@ -137,7 +163,7 @@ const IntegrationConfigPage: React.FC = () => {
|
||||
const teacherRole = activeRoles.find((r) => r.name === '班主任');
|
||||
setDefaultTeacherRoleId(teacherRole?.id || activeRoles[0]?.id || null);
|
||||
} catch {
|
||||
// ignore
|
||||
message.error('获取角色列表失败');
|
||||
}
|
||||
};
|
||||
|
||||
@@ -154,7 +180,7 @@ const IntegrationConfigPage: React.FC = () => {
|
||||
setDeptPickerTree(toTreeNode(res.data));
|
||||
}
|
||||
} catch {
|
||||
// ignore
|
||||
message.error('获取部门架构失败');
|
||||
}
|
||||
};
|
||||
|
||||
@@ -230,43 +256,30 @@ const IntegrationConfigPage: React.FC = () => {
|
||||
...buildTreeData(node.children),
|
||||
...node.users.map((u) => ({
|
||||
title: (
|
||||
<Space size="small">
|
||||
<Checkbox
|
||||
checked={!!teacherChecks[u.userid]}
|
||||
onChange={(e) => {
|
||||
setTeacherChecks((prev) => ({
|
||||
...prev,
|
||||
[u.userid]: e.target.checked,
|
||||
}));
|
||||
if (!e.target.checked) {
|
||||
setTeacherRoles((prev) => {
|
||||
const next = { ...prev };
|
||||
delete next[u.userid];
|
||||
return next;
|
||||
});
|
||||
}
|
||||
}}
|
||||
>
|
||||
老师
|
||||
</Checkbox>
|
||||
<span style={{ fontWeight: 500 }}>{u.name}</span>
|
||||
{u.mobile && (
|
||||
<Tag style={{ marginLeft: 4 }}>{u.mobile}</Tag>
|
||||
)}
|
||||
{teacherChecks[u.userid] && (
|
||||
<Select
|
||||
size="small"
|
||||
style={{ width: 100, marginLeft: 8 }}
|
||||
value={teacherRoles[u.userid] || defaultTeacherRoleId}
|
||||
onChange={(roleId: number) =>
|
||||
setTeacherRoles((prev) => ({ ...prev, [u.userid]: roleId }))
|
||||
}
|
||||
options={roles.map((r) => ({ label: r.name, value: r.id }))}
|
||||
placeholder="选择角色"
|
||||
onClick={(e: React.MouseEvent) => e.stopPropagation()}
|
||||
/>
|
||||
)}
|
||||
</Space>
|
||||
<UserTreeNode
|
||||
key={u.userid}
|
||||
u={u}
|
||||
isTeacher={!!teacherChecks[u.userid]}
|
||||
onToggle={() => {
|
||||
setTeacherChecks((prev) => ({
|
||||
...prev,
|
||||
[u.userid]: !prev[u.userid],
|
||||
}));
|
||||
if (teacherChecks[u.userid]) {
|
||||
setTeacherRoles((prev) => {
|
||||
const next = { ...prev };
|
||||
delete next[u.userid];
|
||||
return next;
|
||||
});
|
||||
}
|
||||
}}
|
||||
roleId={teacherRoles[u.userid]}
|
||||
defaultRoleId={defaultTeacherRoleId}
|
||||
roles={roles}
|
||||
onRoleChange={(roleId) =>
|
||||
setTeacherRoles((prev) => ({ ...prev, [u.userid]: roleId }))
|
||||
}
|
||||
/>
|
||||
),
|
||||
key: `user-${u.userid}`,
|
||||
selectable: false,
|
||||
|
||||
Reference in New Issue
Block a user