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(), /** 来源:uploaded = 用户上传;registered = 配准算法产出 */ source: varchar("source", { length: 32 }).default("uploaded").notNull(), /** 产出该点云的分析结果 ID(仅 registered 时有值) */ sourceResultId: int("sourceResultId"), 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;