优化模型上传与预览体验
This commit is contained in:
@@ -37,6 +37,9 @@ function buildFolderNodes(rows: FolderRow[], userInfo: { id: number; username: s
|
||||
ownerUserId: row.owner_user_id,
|
||||
isSystem: Boolean(row.is_system)
|
||||
},
|
||||
state: {
|
||||
opened: row.library_type === "system" && row.parent_id === null
|
||||
},
|
||||
children: [] as unknown[]
|
||||
}));
|
||||
}
|
||||
@@ -52,6 +55,9 @@ function buildTree(rows: FolderRow[], userInfo: { id: number; username: string;
|
||||
permissions: { read: true, write: false },
|
||||
virtual: true
|
||||
},
|
||||
state: {
|
||||
opened: true
|
||||
},
|
||||
children: [] as unknown[]
|
||||
};
|
||||
const byId = new Map(nodes.map((node) => [Number(node.id), node]));
|
||||
|
||||
@@ -41,6 +41,24 @@ function getProperties(modelId: number) {
|
||||
return Object.fromEntries(rows.map((row) => [row.property_key, row.property_value]));
|
||||
}
|
||||
|
||||
function getPropertiesMap(modelIds: number[]) {
|
||||
const properties = new Map<number, Record<string, string>>();
|
||||
if (modelIds.length === 0) return properties;
|
||||
const placeholders = modelIds.map(() => "?").join(",");
|
||||
const rows = db.prepare(`
|
||||
SELECT model_id, property_key, property_value
|
||||
FROM model_properties
|
||||
WHERE model_id IN (${placeholders})
|
||||
`).all(...modelIds) as { model_id: number; property_key: string; property_value: string }[];
|
||||
|
||||
for (const row of rows) {
|
||||
const modelProperties = properties.get(row.model_id) ?? {};
|
||||
modelProperties[row.property_key] = row.property_value;
|
||||
properties.set(row.model_id, modelProperties);
|
||||
}
|
||||
return properties;
|
||||
}
|
||||
|
||||
function saveProperties(modelId: number, properties: Record<string, string>) {
|
||||
const stmt = db.prepare(`
|
||||
INSERT INTO model_properties (model_id, property_key, property_value)
|
||||
@@ -67,6 +85,22 @@ function modelPayload(row: ModelRow, userInfo?: { id: number; username: string;
|
||||
};
|
||||
}
|
||||
|
||||
function modelListPayload(
|
||||
rows: ModelRow[],
|
||||
userInfo?: { id: number; username: string; role: "admin" | "user" }
|
||||
) {
|
||||
const propertiesMap = getPropertiesMap(rows.map((row) => row.id));
|
||||
return rows.map((row) => ({
|
||||
...row,
|
||||
file_url: publicObjectUrl(row.file_path, row.storage_provider),
|
||||
thumbnail_url: row.thumbnail_path && row.thumbnail_provider
|
||||
? publicObjectUrl(row.thumbnail_path, row.thumbnail_provider)
|
||||
: null,
|
||||
permissions: userInfo ? modelPermissions(userInfo, row) : { read: true, write: false },
|
||||
properties: propertiesMap.get(row.id) ?? {}
|
||||
}));
|
||||
}
|
||||
|
||||
function dataImageToBuffer(dataUrl: string) {
|
||||
const match = dataUrl.match(/^data:(image\/png|image\/jpeg|image\/webp);base64,(.+)$/);
|
||||
if (!match) {
|
||||
@@ -193,28 +227,32 @@ export async function modelRoutes(app: FastifyInstance) {
|
||||
whereParts.push("m.type_id = ?");
|
||||
params.push(query.typeId);
|
||||
}
|
||||
if (query.keyword?.trim()) {
|
||||
const keyword = query.keyword?.trim() ?? "";
|
||||
const hasKeyword = Boolean(keyword);
|
||||
if (hasKeyword) {
|
||||
whereParts.push("(m.name LIKE ? OR m.original_filename LIKE ? OR mp.property_value LIKE ?)");
|
||||
const like = `%${query.keyword.trim()}%`;
|
||||
const like = `%${keyword}%`;
|
||||
params.push(like, like, like);
|
||||
}
|
||||
const where = whereParts.length > 0 ? `WHERE ${whereParts.join(" AND ")}` : "";
|
||||
const propertyJoin = hasKeyword ? "LEFT JOIN model_properties mp ON mp.model_id = m.id" : "";
|
||||
const distinct = hasKeyword ? "DISTINCT" : "";
|
||||
const totalStmt = db.prepare(`
|
||||
SELECT COUNT(DISTINCT m.id) as count
|
||||
SELECT COUNT(${distinct} m.id) as count
|
||||
FROM models m
|
||||
LEFT JOIN model_properties mp ON mp.model_id = m.id
|
||||
${propertyJoin}
|
||||
${where}
|
||||
`);
|
||||
const total = totalStmt.get(...params) as { count: number };
|
||||
const listStmt = db.prepare(`
|
||||
SELECT DISTINCT
|
||||
SELECT ${distinct}
|
||||
m.*,
|
||||
b.name AS brand_name,
|
||||
t.name AS type_name
|
||||
FROM models m
|
||||
LEFT JOIN brands b ON b.id = m.brand_id
|
||||
LEFT JOIN model_types t ON t.id = m.type_id
|
||||
LEFT JOIN model_properties mp ON mp.model_id = m.id
|
||||
${propertyJoin}
|
||||
${where}
|
||||
ORDER BY m.updated_at DESC, m.id DESC
|
||||
LIMIT ? OFFSET ?
|
||||
@@ -225,7 +263,7 @@ export async function modelRoutes(app: FastifyInstance) {
|
||||
total: total.count,
|
||||
page: query.page,
|
||||
pageSize: query.pageSize,
|
||||
items: rows.map((row) => modelPayload(row, request.userInfo))
|
||||
items: modelListPayload(rows, request.userInfo)
|
||||
};
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user