feat: add inspection task lifecycle controls

This commit is contained in:
2026-07-08 17:44:45 +08:00
parent aa2bd80418
commit b87aa3f990
14 changed files with 901 additions and 28 deletions

View File

@@ -1,4 +1,4 @@
import { eq, desc, sql } from "drizzle-orm";
import { eq, desc, inArray, sql, and } from "drizzle-orm";
import { drizzle } from "drizzle-orm/mysql2";
import type { ResultSetHeader } from "mysql2";
import {
@@ -342,19 +342,73 @@ export async function createInspectionTask(data: InsertInspectionTask): Promise<
return row;
}
export async function findInspectionTaskByModelAndName(modelId: number, name: string): Promise<InspectionTask | undefined> {
const db = await getDb();
if (!db) return undefined;
const [row] = await db.select().from(inspectionTasks)
.where(and(eq(inspectionTasks.modelId, modelId), eq(inspectionTasks.name, name)))
.limit(1);
return row;
}
export async function listInspectionTasksByModel(modelId: number): Promise<InspectionTask[]> {
const db = await getDb();
if (!db) return [];
return db.select().from(inspectionTasks)
const tasks = await db.select().from(inspectionTasks)
.where(eq(inspectionTasks.modelId, modelId))
.orderBy(desc(inspectionTasks.createdAt));
return withComputedInspectionTaskStatuses(tasks);
}
export async function getInspectionTaskById(id: number): Promise<InspectionTask | undefined> {
const db = await getDb();
if (!db) return undefined;
const [row] = await db.select().from(inspectionTasks).where(eq(inspectionTasks.id, id));
return row;
if (!row) return undefined;
const [task] = await withComputedInspectionTaskStatuses([row]);
return task;
}
type InspectionTaskStatus = InspectionTask["status"];
type AnalysisStatus = TaskAnalysisResult["status"];
function summarizeInspectionTaskStatus(
fallback: InspectionTaskStatus,
analysisStatuses: AnalysisStatus[],
): InspectionTaskStatus {
if (analysisStatuses.length === 0) return fallback;
if (analysisStatuses.some(status => status === "processing" || status === "pending")) {
return "processing";
}
if (analysisStatuses.some(status => status === "error")) return "error";
if (analysisStatuses.some(status => status === "completed")) return "completed";
return fallback;
}
async function withComputedInspectionTaskStatuses(tasks: InspectionTask[]): Promise<InspectionTask[]> {
if (tasks.length === 0) return tasks;
const db = await getDb();
if (!db) return tasks;
const rows = await db
.select({
taskId: taskAnalysisResults.taskId,
status: taskAnalysisResults.status,
})
.from(taskAnalysisResults)
.where(inArray(taskAnalysisResults.taskId, tasks.map(task => task.id)));
const statusesByTask = new Map<number, AnalysisStatus[]>();
for (const row of rows) {
const statuses = statusesByTask.get(row.taskId) ?? [];
statuses.push(row.status);
statusesByTask.set(row.taskId, statuses);
}
return tasks.map(task => ({
...task,
status: summarizeInspectionTaskStatus(task.status, statusesByTask.get(task.id) ?? []),
}));
}
export async function updateInspectionTask(id: number, data: Partial<InsertInspectionTask>): Promise<void> {
@@ -366,6 +420,9 @@ export async function updateInspectionTask(id: number, data: Partial<InsertInspe
export async function deleteInspectionTask(id: number): Promise<void> {
const db = await getDb();
if (!db) return;
await db.delete(taskAnalysisResults).where(eq(taskAnalysisResults.taskId, id));
await db.delete(taskPointcloudFiles).where(eq(taskPointcloudFiles.taskId, id));
await db.delete(taskCadFiles).where(eq(taskCadFiles.taskId, id));
await db.delete(inspectionTasks).where(eq(inspectionTasks.id, id));
}