feat: wire real upload progress and subtype mapping
This commit is contained in:
@@ -147,8 +147,10 @@ export interface DocumentType {
|
||||
name: string;
|
||||
code?: string;
|
||||
entryModuleId?: number;
|
||||
entryModuleName?: string | null;
|
||||
isEnabled?: boolean;
|
||||
ruleSetIds?: number[];
|
||||
childDocumentTypeIds?: number[];
|
||||
}
|
||||
|
||||
export interface DocumentSubtypeGroup {
|
||||
@@ -233,6 +235,12 @@ export interface UploadResult {
|
||||
error?: string;
|
||||
}
|
||||
|
||||
export interface UploadProgressInfo {
|
||||
loaded: number;
|
||||
total: number;
|
||||
percent: number;
|
||||
}
|
||||
|
||||
// 旧接口上传响应(uploadContractTemplate / appendContractAttachments 仍在使用)
|
||||
interface LegacyUploadResponse {
|
||||
success: boolean;
|
||||
@@ -684,6 +692,7 @@ export async function uploadDocumentToServer(
|
||||
autoRun: boolean = true,
|
||||
speed: string = "normal",
|
||||
jwtToken?: string,
|
||||
onProgress?: (progress: UploadProgressInfo) => void,
|
||||
): Promise<{ data: UploadResult } | { error: string; status?: number; payload?: UploadErrorPayload }> {
|
||||
try {
|
||||
const formData = new FormData();
|
||||
@@ -711,7 +720,23 @@ export async function uploadDocumentToServer(
|
||||
headers["Authorization"] = `Bearer ${jwtToken}`;
|
||||
}
|
||||
|
||||
const response = await axios.post(`${API_BASE_URL}/api/upload`, formData, { headers });
|
||||
const response = await axios.post(`${API_BASE_URL}/api/upload`, formData, {
|
||||
headers,
|
||||
onUploadProgress: (event) => {
|
||||
const fileBlob = formData.get("file");
|
||||
const fallbackTotal = fileBlob instanceof Blob ? fileBlob.size : binaryData.byteLength;
|
||||
const total = Number(event.total || fallbackTotal);
|
||||
const loaded = Number(event.loaded || 0);
|
||||
if (!total || !onProgress) {
|
||||
return;
|
||||
}
|
||||
onProgress({
|
||||
loaded,
|
||||
total,
|
||||
percent: Math.min(100, Math.max(0, Number(((loaded / total) * 100).toFixed(2)))),
|
||||
});
|
||||
},
|
||||
});
|
||||
const body = response.data;
|
||||
|
||||
// Result<DocumentUploadVO> envelope
|
||||
@@ -826,8 +851,6 @@ export async function getDocumentTypes(token?: string): Promise<{data: DocumentT
|
||||
const params: Record<string, string> = {};
|
||||
if (selectedModuleId) {
|
||||
params.entry_module_id = String(selectedModuleId);
|
||||
} else if (documentTypeIds && documentTypeIds.length > 0) {
|
||||
params.ids = documentTypeIds.join(",");
|
||||
}
|
||||
|
||||
const headers: Record<string, string> = {};
|
||||
@@ -835,18 +858,52 @@ export async function getDocumentTypes(token?: string): Promise<{data: DocumentT
|
||||
headers["Authorization"] = `Bearer ${token}`;
|
||||
}
|
||||
|
||||
const response = await axios.get(`${API_BASE_URL}/api/document-types`, { params, headers });
|
||||
const [response, groupRoots] = await Promise.all([
|
||||
axios.get(`${API_BASE_URL}/api/v3/document-type-roots`, { params, headers }),
|
||||
fetchAllEvaluationPointGroupRoots(token),
|
||||
]);
|
||||
const body = response.data;
|
||||
|
||||
if (body?.data && Array.isArray(body.data)) {
|
||||
const types: DocumentType[] = body.data.map((item: { id: number; name: string; code?: string; entryModuleId?: number; isEnabled?: boolean; ruleSetIds?: number[] }) => ({
|
||||
id: item.id,
|
||||
name: item.name,
|
||||
code: item.code,
|
||||
entryModuleId: item.entryModuleId,
|
||||
isEnabled: item.isEnabled,
|
||||
ruleSetIds: item.ruleSetIds,
|
||||
}));
|
||||
let types: DocumentType[] = body.data.map((item: {
|
||||
id: number;
|
||||
name: string;
|
||||
code?: string;
|
||||
entryModuleId?: number | null;
|
||||
entryModuleName?: string | null;
|
||||
isEnabled?: boolean;
|
||||
ruleSetIds?: number[];
|
||||
}) => {
|
||||
const matchedRoot = groupRoots.find((root: any) => Number(root?.id || 0) === Number(item.id));
|
||||
const childDocumentTypeIds = Array.isArray(matchedRoot?.children)
|
||||
? Array.from(
|
||||
new Set(
|
||||
matchedRoot.children
|
||||
.map((child: any) => Number(child?.document_type_id || 0))
|
||||
.filter((childId: number) => childId > 0),
|
||||
),
|
||||
)
|
||||
: [];
|
||||
|
||||
return {
|
||||
id: item.id,
|
||||
name: item.name,
|
||||
code: item.code,
|
||||
entryModuleId: item.entryModuleId ?? null,
|
||||
entryModuleName: item.entryModuleName ?? null,
|
||||
isEnabled: item.isEnabled,
|
||||
ruleSetIds: item.ruleSetIds,
|
||||
childDocumentTypeIds,
|
||||
};
|
||||
});
|
||||
|
||||
if (!selectedModuleId && documentTypeIds && documentTypeIds.length > 0) {
|
||||
types = types.filter((item) =>
|
||||
documentTypeIds.includes(item.id) ||
|
||||
(item.childDocumentTypeIds || []).some((childId) => documentTypeIds.includes(childId)),
|
||||
);
|
||||
}
|
||||
|
||||
return { data: types };
|
||||
}
|
||||
return { error: body?.message || "获取文档类型失败", status: response.status };
|
||||
@@ -919,18 +976,26 @@ async function fetchAllEvaluationPointGroupRoots(token?: string): Promise<any[]>
|
||||
|
||||
function collectSubtypeGroupsFromRoots(
|
||||
roots: any[],
|
||||
documentTypeId: number,
|
||||
rootOrDocumentTypeId: number,
|
||||
entryModuleId?: number | null,
|
||||
): DocumentSubtypeGroup[] {
|
||||
return dedupeSubtypeGroups(
|
||||
roots.flatMap((root: any) => {
|
||||
if (!Array.isArray(root?.children)) return [];
|
||||
if (entryModuleId && Number(root?.entry_module_id || 0) !== Number(entryModuleId)) {
|
||||
return [];
|
||||
}
|
||||
const scopedRoots = roots.filter((root: any) => {
|
||||
if (entryModuleId && Number(root?.entry_module_id || 0) !== Number(entryModuleId)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
const matchedRoot = scopedRoots.find((root: any) => Number(root?.id || 0) === Number(rootOrDocumentTypeId));
|
||||
if (matchedRoot && Array.isArray(matchedRoot.children)) {
|
||||
return dedupeSubtypeGroups(matchedRoot.children.map((child: any) => mapSubtypeChild(child, matchedRoot)));
|
||||
}
|
||||
|
||||
return dedupeSubtypeGroups(
|
||||
scopedRoots.flatMap((root: any) => {
|
||||
if (!Array.isArray(root?.children)) return [];
|
||||
return root.children
|
||||
.filter((child: any) => Number(child?.document_type_id || 0) === Number(documentTypeId))
|
||||
.filter((child: any) => Number(child?.document_type_id || 0) === Number(rootOrDocumentTypeId))
|
||||
.map((child: any) => mapSubtypeChild(child, root));
|
||||
}),
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user