feat: add inspection object resource workflow
This commit is contained in:
60
scripts/migrate-inspection-objects.ts
Normal file
60
scripts/migrate-inspection-objects.ts
Normal file
@@ -0,0 +1,60 @@
|
||||
import mysql from 'mysql2/promise';
|
||||
|
||||
type Mapping = { modelId: number; objectName: string; pointclouds: string[]; defaultPointcloud: string; cadFiles: string[]; defaultCad: string };
|
||||
const mappings: Mapping[] = [
|
||||
{ modelId: 1, objectName: '中间车', pointclouds: ['1_10.ply', '1_11.ply', '1_12.ply'], defaultPointcloud: '1_10.ply', cadFiles: ['train_1_mesh.ply'], defaultCad: 'train_1_mesh.ply' },
|
||||
{ modelId: 2, objectName: '头车', pointclouds: ['2_10.ply', '2_11.ply', '2_12.ply', 'train_2_10M.ply', 'train_2_1T.ply'], defaultPointcloud: '2_10.ply', cadFiles: ['m000004802418tc01_asm.stp', 'train_2_mesh.ply'], defaultCad: 'm000004802418tc01_asm.stp' },
|
||||
];
|
||||
|
||||
const connectionString = process.env.DATABASE_URL;
|
||||
if (!connectionString) throw new Error('DATABASE_URL is required');
|
||||
const connection = await mysql.createConnection(connectionString);
|
||||
let createdObjects = 0;
|
||||
let assignedPointclouds = 0;
|
||||
let assignedCads = 0;
|
||||
let classifiedTasks = 0;
|
||||
const warnings: Array<{ taskId: number; reason: string }> = [];
|
||||
const conflicts: string[] = [];
|
||||
|
||||
try {
|
||||
await connection.beginTransaction();
|
||||
for (const mapping of mappings) {
|
||||
const [existing] = await connection.query<mysql.RowDataPacket[]>('SELECT id FROM inspection_objects WHERE modelId=? AND name=?', [mapping.modelId, mapping.objectName]);
|
||||
if (existing.length === 0) {
|
||||
await connection.execute('INSERT INTO inspection_objects (modelId,name,status) VALUES (?,?,\'draft\')', [mapping.modelId, mapping.objectName]);
|
||||
createdObjects += 1;
|
||||
}
|
||||
const [objectRows] = await connection.query<mysql.RowDataPacket[]>('SELECT id FROM inspection_objects WHERE modelId=? AND name=?', [mapping.modelId, mapping.objectName]);
|
||||
const objectId = Number(objectRows[0].id);
|
||||
for (const name of mapping.pointclouds) {
|
||||
const [rows] = await connection.query<mysql.RowDataPacket[]>('SELECT id,inspectionObjectId FROM model_pointcloud_files WHERE modelId=? AND name=?', [mapping.modelId, name]);
|
||||
if (rows.length !== 1) { conflicts.push(`点云 model=${mapping.modelId} name=${name} 匹配数量=${rows.length}`); continue; }
|
||||
if (rows[0].inspectionObjectId && Number(rows[0].inspectionObjectId) !== objectId) { conflicts.push(`点云 ${name} 已属于其他检测对象`); continue; }
|
||||
if (!rows[0].inspectionObjectId) { await connection.execute('UPDATE model_pointcloud_files SET inspectionObjectId=?,status=\'available\' WHERE id=?', [objectId, rows[0].id]); assignedPointclouds += 1; }
|
||||
}
|
||||
for (const name of mapping.cadFiles) {
|
||||
const [rows] = await connection.query<mysql.RowDataPacket[]>('SELECT id FROM model_cad_files WHERE modelId=? AND name=?', [mapping.modelId, name]);
|
||||
if (rows.length !== 1) { conflicts.push(`CAD model=${mapping.modelId} name=${name} 匹配数量=${rows.length}`); continue; }
|
||||
const [result] = await connection.execute<mysql.ResultSetHeader>('INSERT IGNORE INTO model_cad_inspection_objects (cadFileId,inspectionObjectId) VALUES (?,?)', [rows[0].id, objectId]);
|
||||
assignedCads += result.affectedRows;
|
||||
}
|
||||
const [[defaultPc]] = await connection.query<mysql.RowDataPacket[]>('SELECT id FROM model_pointcloud_files WHERE modelId=? AND name=? AND inspectionObjectId=?', [mapping.modelId, mapping.defaultPointcloud, objectId]);
|
||||
const [[defaultCad]] = await connection.query<mysql.RowDataPacket[]>('SELECT c.id FROM model_cad_files c JOIN model_cad_inspection_objects r ON r.cadFileId=c.id WHERE c.modelId=? AND c.name=? AND r.inspectionObjectId=?', [mapping.modelId, mapping.defaultCad, objectId]);
|
||||
if (defaultPc && defaultCad) await connection.execute('UPDATE inspection_objects SET defaultModelPointcloudId=?,defaultModelCadFileId=?,status=\'active\' WHERE id=?', [defaultPc.id, defaultCad.id, objectId]);
|
||||
else conflicts.push(`${mapping.objectName} 默认输入方案资源不完整`);
|
||||
}
|
||||
|
||||
const [tasks] = await connection.query<mysql.RowDataPacket[]>('SELECT id FROM inspection_tasks WHERE inspectionObjectId IS NULL ORDER BY id');
|
||||
for (const task of tasks) {
|
||||
const [sources] = await connection.query<mysql.RowDataPacket[]>('SELECT DISTINCT mp.inspectionObjectId FROM task_pointcloud_files tp JOIN model_pointcloud_files mp ON mp.id=tp.sourceModelPointcloudId WHERE tp.taskId=? AND mp.inspectionObjectId IS NOT NULL', [task.id]);
|
||||
if (sources.length === 1) { await connection.execute('UPDATE inspection_tasks SET inspectionObjectId=? WHERE id=? AND inspectionObjectId IS NULL', [sources[0].inspectionObjectId, task.id]); classifiedTasks += 1; }
|
||||
else warnings.push({ taskId: Number(task.id), reason: sources.length > 1 ? '包含不同检测对象的车型库点云' : '无可推断的车型库来源点云' });
|
||||
}
|
||||
await connection.commit();
|
||||
console.log(JSON.stringify({ createdObjects, assignedPointclouds, assignedCads, classifiedTasks, unclassifiedTasks: warnings, conflicts }, null, 2));
|
||||
} catch (error) {
|
||||
await connection.rollback();
|
||||
throw error;
|
||||
} finally {
|
||||
await connection.end();
|
||||
}
|
||||
Reference in New Issue
Block a user