fix(archive): 档案聚合接口 null 字段归一化为空串
避免可选列缺省返回 null 导致前端响应校验报「字段格式异常」
This commit is contained in:
@@ -36,4 +36,54 @@ describe('ArchiveService.getProfile', () => {
|
|||||||
expect(response).toMatchObject({ student, result, attendances: [] });
|
expect(response).toMatchObject({ student, result, attendances: [] });
|
||||||
expect(response).not.toHaveProperty('resultArchive');
|
expect(response).not.toHaveProperty('resultArchive');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('将学生可空字符串字段归一化为空串,避免前端校验报格式异常', async () => {
|
||||||
|
const student = {
|
||||||
|
id: 7,
|
||||||
|
name: '测试学生',
|
||||||
|
phone: null,
|
||||||
|
idNumber: null,
|
||||||
|
studentNo: null,
|
||||||
|
gender: null,
|
||||||
|
ethnicity: null,
|
||||||
|
emergencyContact: null,
|
||||||
|
emergencyPhone: null,
|
||||||
|
supervisor: null,
|
||||||
|
};
|
||||||
|
const emptyRepos = {
|
||||||
|
profile: { findOne: jest.fn().mockResolvedValue(null) },
|
||||||
|
enrollment: { find: jest.fn().mockResolvedValue([]) },
|
||||||
|
exam: { find: jest.fn().mockResolvedValue([]) },
|
||||||
|
learning: { find: jest.fn().mockResolvedValue([]) },
|
||||||
|
result: { findOne: jest.fn().mockResolvedValue(null) },
|
||||||
|
attachment: { find: jest.fn().mockResolvedValue([]) },
|
||||||
|
attendance: { find: jest.fn().mockResolvedValue([]) },
|
||||||
|
};
|
||||||
|
const service = new ArchiveService(
|
||||||
|
{ findOne: jest.fn().mockResolvedValue(student) } as never,
|
||||||
|
emptyRepos.profile as never,
|
||||||
|
emptyRepos.enrollment as never,
|
||||||
|
emptyRepos.exam as never,
|
||||||
|
emptyRepos.learning as never,
|
||||||
|
emptyRepos.result as never,
|
||||||
|
emptyRepos.attachment as never,
|
||||||
|
emptyRepos.attendance as never,
|
||||||
|
{} as never,
|
||||||
|
);
|
||||||
|
|
||||||
|
const response = await service.getProfile(7);
|
||||||
|
|
||||||
|
expect(response.student).toMatchObject({
|
||||||
|
id: 7,
|
||||||
|
name: '测试学生',
|
||||||
|
phone: '',
|
||||||
|
idNumber: '',
|
||||||
|
studentNo: '',
|
||||||
|
gender: '',
|
||||||
|
ethnicity: '',
|
||||||
|
emergencyContact: '',
|
||||||
|
emergencyPhone: '',
|
||||||
|
supervisor: '',
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -63,6 +63,19 @@ export class ArchiveService {
|
|||||||
relations: ['organization'],
|
relations: ['organization'],
|
||||||
});
|
});
|
||||||
if (!student) throw new NotFoundException('学生不存在');
|
if (!student) throw new NotFoundException('学生不存在');
|
||||||
|
// 前端档案契约要求这些字段为字符串;可空列缺省时归一化为空串,
|
||||||
|
// 避免接口返回 null 导致响应校验报「student.idNumber 格式异常」。
|
||||||
|
const normalizedStudent = {
|
||||||
|
...student,
|
||||||
|
phone: student.phone ?? '',
|
||||||
|
idNumber: student.idNumber ?? '',
|
||||||
|
studentNo: student.studentNo ?? '',
|
||||||
|
gender: student.gender ?? '',
|
||||||
|
ethnicity: student.ethnicity ?? '',
|
||||||
|
emergencyContact: student.emergencyContact ?? '',
|
||||||
|
emergencyPhone: student.emergencyPhone ?? '',
|
||||||
|
supervisor: student.supervisor ?? '',
|
||||||
|
};
|
||||||
|
|
||||||
const [
|
const [
|
||||||
profileRaw,
|
profileRaw,
|
||||||
@@ -91,7 +104,7 @@ export class ArchiveService {
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
student,
|
student: normalizedStudent,
|
||||||
profile: profileRaw,
|
profile: profileRaw,
|
||||||
enrollments,
|
enrollments,
|
||||||
examScores,
|
examScores,
|
||||||
|
|||||||
Reference in New Issue
Block a user