fix: speed up document type group loading

This commit is contained in:
wren
2026-05-06 11:05:35 +08:00
parent f1d77db79a
commit 8dbacb8bea
3 changed files with 72 additions and 28 deletions
+56 -10
View File
@@ -900,12 +900,7 @@ function dedupeSubtypeGroups(groups: DocumentSubtypeGroup[]): DocumentSubtypeGro
return Array.from(groupMap.values()); return Array.from(groupMap.values());
} }
export async function getDocumentSubtypeGroups( async function fetchAllEvaluationPointGroupRoots(token?: string): Promise<any[]> {
documentTypeId: number,
token?: string,
entryModuleId?: number | null,
): Promise<{ data: DocumentSubtypeGroup[]; error?: never } | { data?: never; error: string; status?: number }> {
try {
const headers: Record<string, string> = {}; const headers: Record<string, string> = {};
if (token) { if (token) {
headers["Authorization"] = `Bearer ${token}`; headers["Authorization"] = `Bearer ${token}`;
@@ -918,19 +913,70 @@ export async function getDocumentSubtypeGroups(
}, },
headers, headers,
}); });
const allRoots = extractApiData<any[]>(allResponse.data) || [];
const matchedFromTree = allRoots.flatMap((root: any) => { return extractApiData<any[]>(allResponse.data) || [];
}
function collectSubtypeGroupsFromRoots(
roots: any[],
documentTypeId: number,
entryModuleId?: number | null,
): DocumentSubtypeGroup[] {
return dedupeSubtypeGroups(
roots.flatMap((root: any) => {
if (!Array.isArray(root?.children)) return []; if (!Array.isArray(root?.children)) return [];
if (entryModuleId && Number(root?.entry_module_id || 0) !== Number(entryModuleId)) { if (entryModuleId && Number(root?.entry_module_id || 0) !== Number(entryModuleId)) {
return []; return [];
} }
return root.children return root.children
.filter((child: any) => Number(child?.document_type_id || 0) === Number(documentTypeId)) .filter((child: any) => Number(child?.document_type_id || 0) === Number(documentTypeId))
.map((child: any) => mapSubtypeChild(child, root)); .map((child: any) => mapSubtypeChild(child, root));
}); }),
);
}
export async function getDocumentSubtypeGroupsMap(
documentTypeIds: number[],
token?: string,
): Promise<{ data: Record<number, DocumentSubtypeGroup[]>; error?: never } | { data?: never; error: string; status?: number }> {
try {
if (!documentTypeIds.length) {
return { data: {} };
}
const roots = await fetchAllEvaluationPointGroupRoots(token);
const ids = Array.from(new Set(documentTypeIds.map((id) => Number(id)).filter(Boolean)));
const grouped = Object.fromEntries(
ids.map((documentTypeId) => [documentTypeId, collectSubtypeGroupsFromRoots(roots, documentTypeId)]),
);
return { data: grouped };
} catch (error) {
console.error("批量获取子类型分组失败:", error);
return {
error: error instanceof Error ? error.message : "批量获取子类型分组失败",
status: 500,
};
}
}
export async function getDocumentSubtypeGroups(
documentTypeId: number,
token?: string,
entryModuleId?: number | null,
): Promise<{ data: DocumentSubtypeGroup[]; error?: never } | { data?: never; error: string; status?: number }> {
try {
const headers: Record<string, string> = {};
if (token) {
headers["Authorization"] = `Bearer ${token}`;
}
const allRoots = await fetchAllEvaluationPointGroupRoots(token);
const matchedFromTree = collectSubtypeGroupsFromRoots(allRoots, documentTypeId, entryModuleId);
if (matchedFromTree.length > 0) { if (matchedFromTree.length > 0) {
return { data: dedupeSubtypeGroups(matchedFromTree) }; return { data: matchedFromTree };
} }
const response = await axios.get(`${API_BASE_URL}/api/v3/evaluation-point-groups/by-document-types`, { const response = await axios.get(`${API_BASE_URL}/api/v3/evaluation-point-groups/by-document-types`, {
+5 -7
View File
@@ -11,7 +11,7 @@ import {
type DocumentType, type DocumentType,
type EntryModuleOption, type EntryModuleOption,
} from "~/api/document-types/document-types"; } from "~/api/document-types/document-types";
import { getDocumentSubtypeGroups, type DocumentSubtypeGroup } from "~/api/files/files-upload"; import { getDocumentSubtypeGroupsMap, type DocumentSubtypeGroup } from "~/api/files/files-upload";
import documentTypesStyles from "~/styles/pages/document-types_index.css?url"; import documentTypesStyles from "~/styles/pages/document-types_index.css?url";
export function links() { export function links() {
@@ -44,17 +44,15 @@ export async function loader({ request }: LoaderFunctionArgs) {
]); ]);
const types = typesRes.data?.types || []; const types = typesRes.data?.types || [];
const subtypeGroupEntries = await Promise.all( const subtypeGroupsRes = await getDocumentSubtypeGroupsMap(
types.map(async (type) => { types.map((type) => type.id),
const groupsRes = await getDocumentSubtypeGroups(type.id, frontendJWT, type.entryModuleId || undefined); frontendJWT,
return [type.id, "data" in groupsRes && groupsRes.data ? groupsRes.data : []] as const;
}),
); );
return { return {
types, types,
entryModules: modulesRes.data || [], entryModules: modulesRes.data || [],
subtypeGroupsByTypeId: Object.fromEntries(subtypeGroupEntries), subtypeGroupsByTypeId: "data" in subtypeGroupsRes && subtypeGroupsRes.data ? subtypeGroupsRes.data : {},
frontendJWT, frontendJWT,
}; };
} catch (error) { } catch (error) {
+3 -3
View File
@@ -16,7 +16,7 @@ import {
type EntryModuleOption, type EntryModuleOption,
type RuleSetOption, type RuleSetOption,
} from "~/api/document-types/document-types"; } from "~/api/document-types/document-types";
import { getDocumentSubtypeGroups, type DocumentSubtypeGroup } from "~/api/files/files-upload"; import { getDocumentSubtypeGroupsMap, type DocumentSubtypeGroup } from "~/api/files/files-upload";
import newStyles from "~/styles/pages/document-types_new.css?url"; import newStyles from "~/styles/pages/document-types_new.css?url";
export function links() { export function links() {
@@ -52,9 +52,9 @@ export async function loader({ request }: LoaderFunctionArgs) {
const res = await getDocumentType(parseInt(editId), frontendJWT); const res = await getDocumentType(parseInt(editId), frontendJWT);
editType = res.data || null; editType = res.data || null;
if (editType?.id) { if (editType?.id) {
const groupsRes = await getDocumentSubtypeGroups(editType.id, frontendJWT, editType.entryModuleId || undefined); const groupsRes = await getDocumentSubtypeGroupsMap([editType.id], frontendJWT);
if ("data" in groupsRes && groupsRes.data) { if ("data" in groupsRes && groupsRes.data) {
runtimeSubtypeGroups = groupsRes.data; runtimeSubtypeGroups = groupsRes.data[editType.id] || [];
} }
} }
} }