- 提交体条件化:空数组不发送,修复全匹配/全新建两种场景被后端 @ArrayMinSize 拒 400 - 无论是否新建学生都先确认,避免已匹配学生被一键加入无提示 - 学员下拉保留学号/ID 兜底区分同名;科目去重键小写对齐后端唯一索引 - 任课老师空科目前端拦截;教师候选人相关调整
41 lines
1.3 KiB
TypeScript
41 lines
1.3 KiB
TypeScript
export interface TeacherCandidateRole {
|
||
code?: string | null;
|
||
name: string;
|
||
}
|
||
|
||
export interface TeacherCandidateUser {
|
||
id: number;
|
||
username: string;
|
||
name?: string | null;
|
||
isArchived: boolean;
|
||
studentStatus?: string | null;
|
||
roles?: TeacherCandidateRole[];
|
||
}
|
||
|
||
const isSuperAdminRole = (role: TeacherCandidateRole) =>
|
||
role.code === 'super_admin' || role.name === '超级管理员' || role.name === '超管';
|
||
|
||
export const isTeacherCandidate = (user: TeacherCandidateUser) => {
|
||
if (user.isArchived) return false;
|
||
if (user.studentStatus && user.studentStatus !== 'staff') return false;
|
||
return !(user.roles || []).some(isSuperAdminRole);
|
||
};
|
||
|
||
export const buildTeacherCandidateLabel = (user: TeacherCandidateUser) => {
|
||
const displayName = user.name?.trim();
|
||
const identity =
|
||
displayName && displayName !== user.username
|
||
? `${displayName}(${user.username})`
|
||
: user.username;
|
||
const roleNames = [
|
||
...new Set((user.roles || []).flatMap((role) => (role.name ? [role.name] : []))),
|
||
];
|
||
return [identity, roleNames.join('/')].filter(Boolean).join(' · ');
|
||
};
|
||
|
||
export const buildTeacherCandidateOptions = (users: TeacherCandidateUser[]) =>
|
||
users.filter(isTeacherCandidate).map((user) => ({
|
||
value: user.id,
|
||
label: buildTeacherCandidateLabel(user),
|
||
}));
|