原生成绩查询、科目/总分排名、达线判断、等级计算及成绩单防伪码:[CandidateService.Results.cs (line 11)](C:/Users/BI/Documents/EIS-dotnet/src/Eis.Infrastructure/Candidate/CandidateService.Results.cs:11)

原生成绩复议提交,工作流、分配人与审计日志同事务写入。
原生准考证下载窗口校验及 HTML 文书生成:[CandidateAdmitCardRenderer.cs (line 9)](C:/Users/BI/Documents/EIS-dotnet/src/Eis.Infrastructure/Candidate/CandidateAdmitCardRenderer.cs:9)
三个路由已切换到 ASP.NET Core:[NativeCandidateEndpoints.cs (line 61)](C:/Users/BI/Documents/EIS-dotnet/src/Eis.Web/Candidate/NativeCandidateEndpoints.cs:61)
更新迁移说明:[MIGRATION.md (line 50)](C:/Users/BI/Documents/EIS-dotnet/MIGRATION.md:50)
This commit is contained in:
2026-07-22 20:08:08 +08:00 Unverified
parent aecb0a04e7
commit 4417d6d674
12 changed files with 783 additions and 25 deletions
@@ -0,0 +1,58 @@
import { DatabaseSync } from 'node:sqlite';
const databasePath = process.argv[2];
const candidateNumber = process.argv[3];
if (!databasePath || !candidateNumber) throw new Error('缺少 SQLite 路径或报名号');
const database = new DatabaseSync(databasePath);
const registration = database.prepare(`
SELECT registration.id, registration.exam_id
FROM registrations registration
JOIN users user ON user.id = registration.user_id
WHERE user.candidate_number = ? AND registration.status = 'approved'
ORDER BY registration.created_at, registration.id LIMIT 1
`).get(candidateNumber);
if (!registration) throw new Error('未找到已审核报名');
const numberRule = database.prepare('SELECT id FROM admission_number_rules ORDER BY created_at, id LIMIT 1').get();
const center = database.prepare("SELECT id, code, name, province_name, city_name, district_name, address FROM test_centers WHERE status = 'active' ORDER BY id LIMIT 1").get();
const room = center ? database.prepare("SELECT id, code, name, building, floor FROM test_rooms WHERE center_id = ? AND status = 'active' ORDER BY code, id LIMIT 1").get(center.id) : null;
if (!numberRule || !center || !room) throw new Error('准考证冒烟数据缺少编号规则、考点或考场');
const now = '2026-07-22T00:00:00.000Z';
database.exec('BEGIN IMMEDIATE');
try {
database.prepare('UPDATE exams SET admit_download_start = ?, admit_download_end = ? WHERE id = ?')
.run('2000-01-01T00:00:00.000Z', '2099-12-31T23:59:59.999Z', registration.exam_id);
database.prepare(`
INSERT OR IGNORE INTO exam_arrangement_plans (
id, exam_id, number_rule_id, mixing_scope, random_seed, candidate_count, center_count,
subject_assignment_count, subject_combination_count, same_school_center_rate,
warnings_json, generated_by, generated_at
) VALUES (?, ?, ?, 'district', 'migration-smoke', 1, 1, 1, 1, 1, '[]', NULL, ?)
`).run('plan_migration_smoke', registration.exam_id, numberRule.id, now);
const plan = database.prepare('SELECT id FROM exam_arrangement_plans WHERE exam_id = ?').get(registration.exam_id);
const address = [center.province_name, center.city_name, center.district_name, center.address].filter(Boolean).join(' ');
database.prepare(`
INSERT OR REPLACE INTO admit_cards (
registration_id, plan_id, card_number, center_id, test_center, center_code, center_address, generated_at
) VALUES (?, ?, ?, ?, ?, ?, ?, ?)
`).run(registration.id, plan.id, 'MIGRATION-SMOKE-001', center.id, center.name, center.code, address, now);
const subjects = database.prepare('SELECT subject_id FROM registration_subjects WHERE registration_id = ? ORDER BY subject_id').all(registration.id);
const insertAssignment = database.prepare(`
INSERT OR REPLACE INTO admit_card_subjects (
registration_id, subject_id, room_id, room, room_code, exam_room_code,
building, floor, seat, subject_signature
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
`);
subjects.forEach((subject, index) => insertAssignment.run(
registration.id, subject.subject_id, room.id, room.name, room.code, '001',
room.building, room.floor || '', '01', `migration-smoke-${index + 1}`
));
database.exec('COMMIT');
console.log(registration.id);
} catch (error) {
database.exec('ROLLBACK');
throw error;
} finally {
database.close();
}