Files
gongxue-base/apps/admin/src/api/schemas/core.ts
wangziqi 2e7bb81ebd fix(admin): 修正接口 schema 与路由不匹配
- classroomSchema 允许 building/status 为 null,教室查看页恢复数据
- 排期 matrix 单元格为对象而非数组,教室排期页恢复渲染
- 押金批量收取改用 /deposits/eligible-students 路由
- 学生下拉 schema 按 /deposits/student-lookups 实际结构校验
- 水电费录入改走 /expenses/student-utility,批量恢复改为 PUT
2026-08-06 11:58:19 +08:00

347 lines
8.6 KiB
TypeScript

import { z } from 'zod';
export const studentProfileAggregateSchema = z
.object({
student: z
.object({
id: z.number(),
name: z.string(),
phone: z.string(),
idNumber: z.string(),
studentNo: z.string(),
status: z.string(),
})
.passthrough(),
profile: z.record(z.string(), z.unknown()).nullable(),
enrollments: z.array(z.record(z.string(), z.unknown())),
examScores: z.array(z.record(z.string(), z.unknown())),
learningRecords: z.array(z.record(z.string(), z.unknown())),
result: z.record(z.string(), z.unknown()).nullable(),
attachments: z.array(z.record(z.string(), z.unknown())),
attendances: z.array(z.record(z.string(), z.unknown())),
})
.passthrough();
/** 权限树 */
export const permissionItemSchema = z
.object({ id: z.number(), code: z.string(), name: z.string(), group: z.string() })
.passthrough();
export const permissionTreeSchema = z.array(
z.object({ group: z.string(), permissions: z.array(permissionItemSchema) }).passthrough(),
);
/** 机构 */
export const organizationSchema = z
.object({ id: z.number(), name: z.string(), code: z.string(), status: z.string() })
.passthrough();
export const organizationsSchema = z.array(organizationSchema);
export const organizationOptionSchema = z
.object({ id: z.number(), name: z.string() })
.passthrough();
export const organizationOptionsSchema = z.array(organizationOptionSchema);
/** 账单 */
export const billSchema = z
.object({
id: z.number(),
status: z.string(),
student: z
.object({ id: z.number(), name: z.string() })
.passthrough()
.nullable()
.optional(),
})
.passthrough();
export const billsSchema = z.array(billSchema);
/** 班级 */
export const classSchema = z
.object({
id: z.number(),
name: z.string(),
code: z.string(),
classType: z.string(),
isArchived: z.boolean(),
})
.passthrough();
export const classesSchema = z.array(classSchema);
/** 教师 */
export const teacherSchema = z
.object({ id: z.number(), username: z.string(), name: z.string() })
.passthrough();
export const teacherListSchema = z
.object({ list: z.array(teacherSchema), total: z.number() })
.passthrough();
/** 角色 / 用户 */
export const roleSchema = z
.object({ id: z.number(), name: z.string(), status: z.number() })
.passthrough();
export const rolesSchema = z.array(roleSchema);
export const userSchema = z
.object({ id: z.number(), username: z.string(), name: z.string() })
.passthrough();
export const usersSchema = z.array(userSchema);
/** 操作日志 */
export const operationLogSchema = z
.object({
id: z.number(),
module: z.string(),
action: z.string(),
username: z.string(),
createdAt: z.string(),
})
.passthrough();
export const operationLogsSchema = z
.object({ data: z.array(operationLogSchema), total: z.number() })
.passthrough();
/** 通知 */
export const notificationSchema = z
.object({
id: z.number(),
type: z.string(),
title: z.string(),
content: z.string(),
isRead: z.boolean(),
createdAt: z.string(),
})
.passthrough();
export const notificationsSchema = z.array(notificationSchema);
/** 考勤机 / 教室选项 */
export const attendanceDeviceSchema = z
.object({ id: z.number(), deviceSn: z.string(), deviceName: z.string(), status: z.string() })
.passthrough();
export const attendanceDevicesSchema = z.array(attendanceDeviceSchema);
export const classroomOptionSchema = z
.object({ id: z.number(), name: z.string() })
.passthrough();
export const classroomOptionsSchema = z.array(classroomOptionSchema);
/** 宿舍 / 教室 */
export const roomSchema = z
.object({
id: z.number(),
roomNumber: z.string(),
status: z.string(),
currentCount: z.number(),
capacity: z.number(),
})
.passthrough();
export const roomsOverviewSchema = z.array(roomSchema);
export const classroomSchema = z
.object({
id: z.number(),
name: z.string(),
building: z.string().nullable().optional(),
status: z.string().nullable().optional(),
})
.passthrough();
export const classroomsSchema = z.array(classroomSchema);
/** 学生 */
export const studentSchema = z
.object({
id: z.number(),
name: z.string(),
studentNo: z.string().nullable().optional(),
status: z.string(),
})
.passthrough();
export const studentsSchema = z.array(studentSchema);
/** 押金 */
export const depositSchema = z
.object({ id: z.number(), studentId: z.number(), amount: z.number(), status: z.string() })
.passthrough();
export const depositsSchema = z.array(depositSchema);
export const depositStudentLookupSchema = z
.object({
id: z.number(),
name: z.string().nullable().optional(),
studentNo: z.string().nullable().optional(),
})
.passthrough();
export const depositStudentLookupsSchema = z.array(depositStudentLookupSchema);
export const eligibleStudentSchema = z
.object({ studentId: z.number(), roomId: z.number(), roomNumber: z.string() })
.passthrough();
export const eligibleStudentsSchema = z.array(eligibleStudentSchema);
/** 钱包 */
export const walletSchema = z
.object({
studentId: z.number(),
studentName: z.string(),
balance: z.number(),
outstandingAmount: z.number(),
})
.passthrough();
export const walletsSchema = z.array(walletSchema);
export const roomTypesSchema = z.array(z.string());
/** 费用 */
export const expenseRecordSchema = z
.object({
id: z.number(),
expenseType: z.string(),
amount: z.number(),
status: z.string().optional(),
})
.passthrough();
export const expenseRecordsSchema = z.array(expenseRecordSchema);
export const expenseStudentLookupSchema = z
.object({
id: z.number(),
name: z.string().nullable().optional(),
studentNo: z.string().nullable().optional(),
})
.passthrough();
export const expenseStudentLookupsSchema = z.array(expenseStudentLookupSchema);
export const expenseRoomsListSchema = z.array(z.record(z.string(), z.unknown()));
export const expenseLookupsSchema = z
.object({
rooms: z.array(z.record(z.string(), z.unknown())),
students: z.array(z.record(z.string(), z.unknown())),
})
.passthrough();
export const expenseTypesSchema = z.array(
z.object({ code: z.string(), name: z.string(), category: z.string() }),
);
/** 入住 */
export const occupancySchema = z
.object({
id: z.number(),
studentId: z.number(),
roomId: z.number(),
checkInDate: z.string().optional(),
status: z.string().optional(),
})
.passthrough();
export const occupanciesSchema = z.array(occupancySchema);
/** 排课 */
export const scheduleLookupsSchema = z
.object({
classrooms: z.array(classroomOptionSchema),
classes: z.array(z.object({ id: z.number(), name: z.string() }).passthrough()),
})
.passthrough();
export const weeklyScheduleSchema = z.record(
z.string(),
z.record(
z.string(),
z.array(
z
.object({
id: z.number().nullable(),
classId: z.number().nullable(),
classroomId: z.number(),
weekDay: z.number(),
startTime: z.string(),
endTime: z.string(),
})
.passthrough(),
),
),
);
/** 租赁订单 */
export const rentalSchema = z
.object({
id: z.number(),
classroom: z
.object({ id: z.number(), name: z.string() })
.passthrough()
.nullable()
.optional(),
lesseeOrganization: z
.object({ id: z.number(), name: z.string() })
.passthrough()
.nullable()
.optional(),
status: z.string().optional(),
})
.passthrough();
export const rentalsSchema = z.array(rentalSchema);
/** 考试 */
export const examSchema = z
.object({
id: z.number(),
examName: z.string(),
examType: z.string(),
isArchived: z.boolean(),
})
.passthrough();
export const examsSchema = z.array(examSchema);
export const examDetailSchema = z
.object({ id: z.number(), examName: z.string() })
.passthrough();
export const classOptionSchema = z
.object({ id: z.number(), name: z.string() })
.passthrough();
export const classOptionsSchema = z.array(classOptionSchema);
export const studentFilterLookupsSchema = z
.object({
classes: z.array(z.object({ id: z.number(), name: z.string() }).passthrough()),
teachers: z.array(z.object({ id: z.number(), name: z.string() }).passthrough()),
})
.passthrough();
/** 教师工作台 */
export const teacherWorkspaceSchema = z
.object({
assignedClasses: z.array(
z.object({ classId: z.number(), className: z.string() }).passthrough(),
),
todaySchedules: z.array(z.record(z.string(), z.unknown())),
})
.passthrough();
/** 集成配置 */