feat(P19ERP3-3,P19ERP3-4): 新增资产ERP轨道接口与前端卡片挂件

这个提交包含在:
2026-03-09 11:15:21 +08:00
父节点 0168ebfe2e
当前提交 07fac7d2d2
共修改 4 个文件,包含 604 行新增和 0 行删除
+93
查看文件
@@ -134,6 +134,81 @@ export type AssetMovementResponse = {
transferId?: string | null;
};
export type AssetErpTrackStatus =
| "not_triggered"
| "pending"
| "processing"
| "succeeded"
| "failed"
| "dead_letter"
| "skipped";
export type AssetErpBinding = {
id: string;
provider: string;
entityType: string;
localId: string;
externalId: string | null;
externalCode: string | null;
lastSyncedAt: string | null;
};
export type AssetErpOutbox = {
id: string;
eventType: string;
status: string;
attempts: number;
lastError: string | null;
processedAt: string | null;
updatedAt: string | null;
};
export type AssetErpStage = {
eligible: boolean;
reason: string | null;
deliveryStatus: AssetErpTrackStatus | string;
actionHint: "none" | "backfill" | "retry" | "resync";
preview: {
changeType: string | null;
sourceEventName: string | null;
categoryCode: string | null;
legalEntityCode: string | null;
costCenterCode: string | null;
status: string | null;
};
outbox: AssetErpOutbox | null;
binding: AssetErpBinding | null;
};
export type AssetErpTrack = {
asset: {
id: string;
assetNo: string | null;
name: string | null;
status: string | null;
legalEntity: {
id: string;
code: string | null;
name: string | null;
} | null;
costCenter: {
id: string;
code: string | null;
name: string | null;
} | null;
purchaseRequest: {
id: string;
requestNo: string | null;
title: string | null;
} | null;
};
stage: AssetErpStage;
permissions: {
canRetry: boolean;
canSeeExternalRefs: boolean;
};
};
function toQueryString(query: Record<string, string | boolean | undefined>) {
const params = new URLSearchParams();
for (const [key, value] of Object.entries(query)) {
@@ -232,3 +307,21 @@ export async function transferAsset(
body: JSON.stringify(payload),
});
}
export async function fetchAssetErpTrack(assetId: string) {
return apiRequestData<AssetErpTrack>(`/api/integrations/erp/assets/${assetId}/track`);
}
export async function requeueAssetErpSync(assetId: string, runNow = true) {
const query = runNow ? '?runNow=1' : '?runNow=0';
return apiRequestData<{
outboxId: string;
status: string;
duplicated: boolean;
requeued: boolean;
eventType: string;
}>(`/api/integrations/erp/assets/${assetId}/requeue${query}`, {
method: 'POST',
body: JSON.stringify({}),
});
}