模型库初版提交
This commit is contained in:
@@ -20,7 +20,7 @@ const updateSchema = z.object({
|
|||||||
function buildTree(rows: FolderRow[]) {
|
function buildTree(rows: FolderRow[]) {
|
||||||
const nodes = rows.map((row) => ({
|
const nodes = rows.map((row) => ({
|
||||||
id: String(row.id),
|
id: String(row.id),
|
||||||
text: row.name,
|
text: `${row.name}(${row.model_count ?? 0})`,
|
||||||
parentId: row.parent_id,
|
parentId: row.parent_id,
|
||||||
path: row.path,
|
path: row.path,
|
||||||
children: [] as unknown[]
|
children: [] as unknown[]
|
||||||
@@ -53,7 +53,15 @@ function assertCanRenameRoot(folder: FolderRow) {
|
|||||||
|
|
||||||
export async function folderRoutes(app: FastifyInstance) {
|
export async function folderRoutes(app: FastifyInstance) {
|
||||||
app.get("/api/folders", { preHandler: [requireAuth] }, async () => {
|
app.get("/api/folders", { preHandler: [requireAuth] }, async () => {
|
||||||
const rows = db.prepare("SELECT * FROM folders ORDER BY parent_id, name").all() as unknown as FolderRow[];
|
const rows = db.prepare(`
|
||||||
|
SELECT
|
||||||
|
f.*,
|
||||||
|
COUNT(m.id) AS model_count
|
||||||
|
FROM folders f
|
||||||
|
LEFT JOIN models m ON m.folder_id = f.id
|
||||||
|
GROUP BY f.id
|
||||||
|
ORDER BY f.parent_id, f.name
|
||||||
|
`).all() as unknown as FolderRow[];
|
||||||
return { folders: rows, tree: buildTree(rows) };
|
return { folders: rows, tree: buildTree(rows) };
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ export interface FolderRow {
|
|||||||
parent_id: number | null;
|
parent_id: number | null;
|
||||||
name: string;
|
name: string;
|
||||||
path: string;
|
path: string;
|
||||||
|
model_count?: number;
|
||||||
created_at: string;
|
created_at: string;
|
||||||
updated_at: string;
|
updated_at: string;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,7 +32,6 @@ export async function renderApp() {
|
|||||||
<div class="content-toolbar">
|
<div class="content-toolbar">
|
||||||
<div>
|
<div>
|
||||||
<h2>模型列表</h2>
|
<h2>模型列表</h2>
|
||||||
<p id="modelCount">0 个模型</p>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="content-actions">
|
<div class="content-actions">
|
||||||
${isAdmin ? `<button id="manageUsersBtn" type="button">人员权限</button>` : ""}
|
${isAdmin ? `<button id="manageUsersBtn" type="button">人员权限</button>` : ""}
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ type JsTreeNode = {
|
|||||||
|
|
||||||
function selectFolder(node: JsTreeNode) {
|
function selectFolder(node: JsTreeNode) {
|
||||||
appState.selectedFolderId = Number(node.id);
|
appState.selectedFolderId = Number(node.id);
|
||||||
appState.selectedFolderName = node.text;
|
appState.selectedFolderName = appState.folders.find((folder) => folder.id === Number(node.id))?.name ?? node.text;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function createFolder(parentId: number | null) {
|
async function createFolder(parentId: number | null) {
|
||||||
@@ -111,7 +111,7 @@ export async function loadFolders() {
|
|||||||
}
|
}
|
||||||
}).on("select_node.jstree", async (_event: JQuery.Event, data: { node: { id: string; text: string } }) => {
|
}).on("select_node.jstree", async (_event: JQuery.Event, data: { node: { id: string; text: string } }) => {
|
||||||
appState.selectedFolderId = Number(data.node.id);
|
appState.selectedFolderId = Number(data.node.id);
|
||||||
appState.selectedFolderName = data.node.text;
|
appState.selectedFolderName = appState.folders.find((folder) => folder.id === appState.selectedFolderId)?.name ?? data.node.text;
|
||||||
appState.page = 1;
|
appState.page = 1;
|
||||||
await loadModels();
|
await loadModels();
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -91,7 +91,6 @@ export async function loadModels() {
|
|||||||
appState.page -= 1;
|
appState.page -= 1;
|
||||||
return loadModels();
|
return loadModels();
|
||||||
}
|
}
|
||||||
document.querySelector("#modelCount")!.textContent = `${result.total} 个模型`;
|
|
||||||
renderPagination({
|
renderPagination({
|
||||||
container: document.querySelector<HTMLElement>("#modelPagination")!,
|
container: document.querySelector<HTMLElement>("#modelPagination")!,
|
||||||
total: result.total,
|
total: result.total,
|
||||||
|
|||||||
@@ -62,6 +62,9 @@ select {
|
|||||||
.jstree-default .jstree-anchor {
|
.jstree-default .jstree-anchor {
|
||||||
height: 24px;
|
height: 24px;
|
||||||
line-height: 24px;
|
line-height: 24px;
|
||||||
|
max-width: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
}
|
}
|
||||||
|
|
||||||
.jstree-default .jstree-icon:empty {
|
.jstree-default .jstree-icon:empty {
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ export type Folder = {
|
|||||||
parent_id: number | null;
|
parent_id: number | null;
|
||||||
name: string;
|
name: string;
|
||||||
path: string;
|
path: string;
|
||||||
|
model_count: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type ModelItem = {
|
export type ModelItem = {
|
||||||
|
|||||||
Reference in New Issue
Block a user