37 lines
1.1 KiB
TypeScript
37 lines
1.1 KiB
TypeScript
import type { Metadata } from 'next';
|
|
import { publicApi } from '@/lib/services';
|
|
import { ManualLayout } from '@/components/front/ManualLayout';
|
|
import type { Manual, ManualTreeNode } from '@/lib/types';
|
|
|
|
export const revalidate = 60;
|
|
|
|
export const metadata: Metadata = {
|
|
title: '使用手册',
|
|
description: '产品使用手册与文档',
|
|
};
|
|
|
|
/** 扁平化树为「仅文档」节点,用于查找第一篇可显示的文档 */
|
|
function flattenDocIds(nodes: ManualTreeNode[]): number[] {
|
|
const out: number[] = [];
|
|
const walk = (list: ManualTreeNode[]) => {
|
|
for (const n of list) {
|
|
if (n.type === 1) out.push(n.id);
|
|
if (n.children.length > 0) walk(n.children);
|
|
}
|
|
};
|
|
walk(nodes);
|
|
return out;
|
|
}
|
|
|
|
export default async function ManualIndexPage() {
|
|
const tree = await publicApi.getManualTree().catch(() => [] as ManualTreeNode[]);
|
|
const docIds = flattenDocIds(tree);
|
|
|
|
// 优先展示第一篇文档的内容;树中无文档节点时显示空态
|
|
const firstDoc: Manual | null = docIds[0]
|
|
? await publicApi.getManualDetail(docIds[0]).catch(() => null)
|
|
: null;
|
|
|
|
return <ManualLayout tree={tree} doc={firstDoc} />;
|
|
}
|