Files
massive-cloud/drizzle/schema.ts

175 lines
9.4 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { int, mysqlEnum, mysqlTable, text, timestamp, varchar, bigint, json, uniqueIndex } 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;
// ─── 车型点云文件 ─────────────────────────────────────────────────────────────
// 一个车型可维护多个通用点云文件,供任务按需关联复用
export const modelPointcloudFiles = mysqlTable("model_pointcloud_files", {
id: int("id").autoincrement().primaryKey(),
modelId: int("modelId").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 ModelPointcloudFile = typeof modelPointcloudFiles.$inferSelect;
export type InsertModelPointcloudFile = typeof modelPointcloudFiles.$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(),
/** 来源:uploaded = 用户上传;model_library = 车型 CAD 库关联 */
source: varchar("source", { length: 32 }).default("uploaded").notNull(),
/** 来源车型 CAD 文件 ID(仅 model_library 时有值) */
sourceModelCadFileId: int("sourceModelCadFileId"),
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", ["created", "pending", "processing", "completed", "error"]).default("created").notNull(),
createdAt: timestamp("createdAt").defaultNow().notNull(),
updatedAt: timestamp("updatedAt").defaultNow().onUpdateNow().notNull(),
completedAt: timestamp("completedAt"),
}, (table) => {
return {
modelNameUnique: uniqueIndex("uk_inspection_tasks_model_name").on(table.modelId, table.name),
};
});
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 = 配准算法产出;model_library = 车型点云库关联 */
source: varchar("source", { length: 32 }).default("uploaded").notNull(),
/** 产出该点云的分析结果 ID(仅 registered 时有值) */
sourceResultId: int("sourceResultId"),
/** 生成该配准产物的原始任务点云 ID(仅 registered 时有值) */
sourcePointcloudFileId: int("sourcePointcloudFileId"),
/** 来源车型点云文件 ID(仅 model_library 时有值) */
sourceModelPointcloudId: int("sourceModelPointcloudId"),
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", "cancelled"]).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;