feat: initial commit - massive-cloud point cloud processing system

This commit is contained in:
2026-05-27 09:51:42 +00:00
commit 16811100d1
391 changed files with 78338 additions and 0 deletions

143
drizzle/schema.ts Normal file
View File

@@ -0,0 +1,143 @@
import { int, mysqlEnum, mysqlTable, text, timestamp, varchar, bigint, json } from "drizzle-orm/mysql-core";
// ─── 用户表(保持不变) ────────────────────────────────────────────────────────
export const users = mysqlTable("users", {
id: int("id").autoincrement().primaryKey(),
openId: varchar("openId", { length: 64 }).notNull().unique(),
name: text("name"),
email: varchar("email", { length: 320 }),
loginMethod: varchar("loginMethod", { length: 64 }),
role: mysqlEnum("role", ["user", "admin"]).default("user").notNull(),
createdAt: timestamp("createdAt").defaultNow().notNull(),
updatedAt: timestamp("updatedAt").defaultNow().onUpdateNow().notNull(),
lastSignedIn: timestamp("lastSignedIn").defaultNow().notNull(),
});
export type User = typeof users.$inferSelect;
export type InsertUser = typeof users.$inferInsert;
// ─── 车系 ─────────────────────────────────────────────────────────────────────
// 例:复兴号、和谐号
export const vehicleSeries = mysqlTable("vehicle_series", {
id: int("id").autoincrement().primaryKey(),
name: varchar("name", { length: 100 }).notNull(),
description: text("description"),
createdAt: timestamp("createdAt").defaultNow().notNull(),
updatedAt: timestamp("updatedAt").defaultNow().onUpdateNow().notNull(),
});
export type VehicleSeries = typeof vehicleSeries.$inferSelect;
export type InsertVehicleSeries = typeof vehicleSeries.$inferInsert;
// ─── 车型 ─────────────────────────────────────────────────────────────────────
// 例:CR400AF,归属于某车系
export const vehicleModels = mysqlTable("vehicle_models", {
id: int("id").autoincrement().primaryKey(),
seriesId: int("seriesId").notNull(),
name: varchar("name", { length: 100 }).notNull(),
description: text("description"),
createdAt: timestamp("createdAt").defaultNow().notNull(),
updatedAt: timestamp("updatedAt").defaultNow().onUpdateNow().notNull(),
});
export type VehicleModel = typeof vehicleModels.$inferSelect;
export type InsertVehicleModel = typeof vehicleModels.$inferInsert;
// ─── 车型 CAD 文件 ─────────────────────────────────────────────────────────────
// 一个车型可关联多个 CAD 文件(车头、车身、转向架等),低频变更
export const modelCadFiles = mysqlTable("model_cad_files", {
id: int("id").autoincrement().primaryKey(),
modelId: int("modelId").notNull(),
name: varchar("name", { length: 255 }).notNull(),
format: varchar("format", { length: 32 }).notNull(),
fileSize: bigint("fileSize", { mode: "number" }).notNull(),
filePath: varchar("filePath", { length: 512 }).notNull(),
createdAt: timestamp("createdAt").defaultNow().notNull(),
});
export type ModelCadFile = typeof modelCadFiles.$inferSelect;
export type InsertModelCadFile = typeof modelCadFiles.$inferInsert;
// ─── 任务 CAD 文件 ─────────────────────────────────────────────────────────────
// 每个任务可关联任意个 CAD 文件(与车型级 CAD 独立,用于本次检测的实测参考)
export const taskCadFiles = mysqlTable("task_cad_files", {
id: int("id").autoincrement().primaryKey(),
taskId: int("taskId").notNull(),
name: varchar("name", { length: 255 }).notNull(),
format: varchar("format", { length: 32 }).notNull(),
fileSize: bigint("fileSize", { mode: "number" }).notNull(),
filePath: varchar("filePath", { length: 512 }).notNull(),
createdAt: timestamp("createdAt").defaultNow().notNull(),
});
export type TaskCadFile = typeof taskCadFiles.$inferSelect;
export type InsertTaskCadFile = typeof taskCadFiles.$inferInsert;
// ─── 检测任务 ─────────────────────────────────────────────────────────────────
// 每次出厂/维保检测对应一条任务记录,归属于某车型
export const inspectionTasks = mysqlTable("inspection_tasks", {
id: int("id").autoincrement().primaryKey(),
modelId: int("modelId").notNull(),
name: varchar("name", { length: 255 }).notNull(),
inspector: varchar("inspector", { length: 100 }),
notes: text("notes"),
status: mysqlEnum("status", ["pending", "processing", "completed", "error"]).default("pending").notNull(),
createdAt: timestamp("createdAt").defaultNow().notNull(),
updatedAt: timestamp("updatedAt").defaultNow().onUpdateNow().notNull(),
completedAt: timestamp("completedAt"),
});
export type InspectionTask = typeof inspectionTasks.$inferSelect;
export type InsertInspectionTask = typeof inspectionTasks.$inferInsert;
// ─── 任务点云文件 ──────────────────────────────────────────────────────────────
// 每次检测上传的点云文件(可多个),归属于某检测任务
export const taskPointcloudFiles = mysqlTable("task_pointcloud_files", {
id: int("id").autoincrement().primaryKey(),
taskId: int("taskId").notNull(),
name: varchar("name", { length: 255 }).notNull(),
fileSize: bigint("fileSize", { mode: "number" }).notNull(),
filePath: varchar("filePath", { length: 512 }).notNull(),
createdAt: timestamp("createdAt").defaultNow().notNull(),
});
export type TaskPointcloudFile = typeof taskPointcloudFiles.$inferSelect;
export type InsertTaskPointcloudFile = typeof taskPointcloudFiles.$inferInsert;
// ─── 任务分析结果 ──────────────────────────────────────────────────────────────
// 对某检测任务运行分析后保存的结果,支持回放
export const taskAnalysisResults = mysqlTable("task_analysis_results", {
id: int("id").autoincrement().primaryKey(),
taskId: int("taskId").notNull(),
type: mysqlEnum("type", [
"error_analysis",
"measurement",
"compression",
"smooth_heatmap",
"assembly_inspection",
"obj_deviation",
// 通用算法插件统一以 'plugin' 类型记录;具体算法以 pluginId 区分
"plugin",
]).notNull(),
/** 仅 type='plugin' 时使用:manifest.id(如 coupler-panel) */
pluginId: varchar("pluginId", { length: 64 }),
/** 算法 result.json 的 schema 版本,便于回放时严格校验 */
schemaVersion: int("schemaVersion"),
status: mysqlEnum("status", ["pending", "processing", "completed", "error"]).default("pending").notNull(),
errorStats: json("errorStats"), // { min, max, mean, stdDev, totalPoints, withinTolerance, outOfTolerance }
measurements: json("measurements"), // [{ name, value, unit, tolerance, status }]
resultData: json("resultData"), // 其他分析数据(如压缩比等)
createdAt: timestamp("createdAt").defaultNow().notNull(),
updatedAt: timestamp("updatedAt").defaultNow().onUpdateNow().notNull(),
});
export type TaskAnalysisResult = typeof taskAnalysisResults.$inferSelect;
export type InsertTaskAnalysisResult = typeof taskAnalysisResults.$inferInsert;