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