- classroomSchema 允许 building/status 为 null,教室查看页恢复数据 - 排期 matrix 单元格为对象而非数组,教室排期页恢复渲染 - 押金批量收取改用 /deposits/eligible-students 路由 - 学生下拉 schema 按 /deposits/student-lookups 实际结构校验 - 水电费录入改走 /expenses/student-utility,批量恢复改为 PUT
347 lines
8.6 KiB
TypeScript
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();
|
|
|
|
/** 集成配置 */
|