feat: add exam score management
Some checks failed
CI 检查 / lint (pull_request) Has been cancelled
CI 检查 / typecheck (pull_request) Has been cancelled
CI 检查 / test (pull_request) Has been cancelled

This commit is contained in:
2026-07-21 16:04:17 +08:00
parent 37ef6f9dd7
commit cbc04fea4f
27 changed files with 1061 additions and 16 deletions

View File

@@ -0,0 +1,62 @@
import { MigrationInterface, QueryRunner, Table, TableColumn, TableForeignKey, TableIndex } from 'typeorm';
export class AddExamManagement1784600000000 implements MigrationInterface {
async up(queryRunner: QueryRunner): Promise<void> {
if (!(await queryRunner.hasTable('exams'))) {
await queryRunner.createTable(
new Table({
name: 'exams',
columns: [
{ name: 'id', type: 'integer', isPrimary: true, isGenerated: true, generationStrategy: 'increment' },
{ name: 'exam_type', type: 'varchar', length: '50' },
{ name: 'exam_name', type: 'varchar', length: '100' },
{ name: 'subject', type: 'varchar', length: '50' },
{ name: 'exam_date', type: 'date' },
{ name: 'class_id', type: 'integer' },
{ name: 'status', type: 'varchar', length: '20', default: "'active'" },
{ name: 'created_at', type: 'datetime', default: 'CURRENT_TIMESTAMP' },
{ name: 'updated_at', type: 'datetime', default: 'CURRENT_TIMESTAMP' },
],
}),
);
await queryRunner.createForeignKey(
'exams',
new TableForeignKey({
columnNames: ['class_id'],
referencedTableName: 'classes',
referencedColumnNames: ['id'],
}),
);
await queryRunner.createIndex('exams', new TableIndex({ columnNames: ['class_id', 'status'] }));
}
if (!(await queryRunner.hasColumn('exam_scores', 'exam_id'))) {
await queryRunner.addColumn(
'exam_scores',
new TableColumn({ name: 'exam_id', type: 'integer', isNullable: true }),
);
await queryRunner.createForeignKey(
'exam_scores',
new TableForeignKey({
columnNames: ['exam_id'],
referencedTableName: 'exams',
referencedColumnNames: ['id'],
onDelete: 'CASCADE',
}),
);
await queryRunner.createIndex('exam_scores', new TableIndex({ columnNames: ['exam_id'] }));
}
}
async down(queryRunner: QueryRunner): Promise<void> {
if (await queryRunner.hasColumn('exam_scores', 'exam_id')) {
const table = await queryRunner.getTable('exam_scores');
const foreignKey = table?.foreignKeys.find((key) => key.columnNames.includes('exam_id'));
if (foreignKey) await queryRunner.dropForeignKey('exam_scores', foreignKey);
const index = table?.indices.find((item) => item.columnNames.includes('exam_id'));
if (index) await queryRunner.dropIndex('exam_scores', index);
await queryRunner.dropColumn('exam_scores', 'exam_id');
}
if (await queryRunner.hasTable('exams')) await queryRunner.dropTable('exams');
}
}