import { requestClient } from '#/api/request'; export namespace TraceabilityApi { export interface OssStoredValue { bucketName: string; objectName: string; tempUrl?: string; } export interface FieldStyle { bold?: boolean; color?: string; } export interface Overview { templateCount: number; batchCount: number; publishedCount: number; feedbackCount: number; totalScans: number; } export interface FieldDefinition { key: string; label: string; type: string; required: boolean; visible: boolean; fixedPreset?: boolean; placeholder?: string; defaultValue?: any; defaultPreviewUrl?: string; options?: string[]; fieldStyle?: FieldStyle; } export interface TemplateNode { id?: string; sort?: number; category: 'business' | 'public' | string; name: string; description: string; locked?: boolean; consumerVisible: boolean; fields: FieldDefinition[]; } export interface PreviewNode { id?: string; sort?: number; category: 'business' | 'public' | string; name: string; description: string; consumerVisible: boolean; values: Record; valuePreviewUrls?: Record; fields: FieldDefinition[]; } export interface NodeLibraryItem { id: string; category: 'business' | 'public' | string; name: string; description: string; consumerVisible: boolean; fields: FieldDefinition[]; updatedAt: string; } export interface TemplateSummary { id: string; name: string; description: string; productName: string; industryName: string; coverImage: string; coverImagePreviewUrl?: string; themeColor: string; status: string; nodeCount: number; batchCount: number; updatedAt: string; } export interface TemplateDetail extends TemplateSummary { nodes: TemplateNode[]; } export interface PreviewPageSummary { id: string; name: string; previewCode: string; description: string; productName: string; coverImage: string; coverImagePreviewUrl?: string; themeColor: string; tags: string[]; publicUrl: string; updatedAt: string; } export interface PreviewPageDetail extends PreviewPageSummary { nodes: PreviewNode[]; } export interface BatchStep { id: string; templateNodeId?: string; sort: number; category: string; name: string; description: string; locked?: boolean; consumerVisible: boolean; status: string; operatorName: string; values: Record; valuePreviewUrls?: Record; completedAt: string; fields: FieldDefinition[]; } export interface BatchSummary { id: string; templateId: string; templateName: string; batchName: string; batchCode: string; productName: string; summary: string; coverImage: string; coverImagePreviewUrl?: string; tags: string[]; status: string; currentStep: number; scanCount: number; publicUrl: string; updatedAt: string; } export interface BatchDetail extends BatchSummary { steps: BatchStep[]; publishedAt: string; } export interface PublicDetail { batch: BatchDetail; companySectionTitle: string; publicSections: BatchStep[]; businessSections: BatchStep[]; } export interface FeedbackItem { id: string; batchId: string; batchCode: string; batchName: string; type: string; contact: string; content: string; source: string; rating: number; createdAt: string; } export interface OssFileResult { bucketName: string; objectName: string; uploadUrl?: string; tempUrl?: string; contentType?: string; fileName?: string; size?: number; } export interface FileAssetItem { id: string; assetType: string; bucketName: string; objectName: string; fileName: string; contentType: string; size: number; previewUrl: string; createdAt: string; } } export function getTraceabilityOverview() { return requestClient.get('/traceability/overview'); } export function getTraceabilityTemplates() { return requestClient.get( '/traceability/templates', ); } export function getTraceabilityPreviews() { return requestClient.get( '/traceability/previews', ); } export function getTraceabilityPreview(id: string) { return requestClient.get( `/traceability/previews/${id}`, ); } export function createTraceabilityPreview( data: Omit, ) { return requestClient.post('/traceability/previews', data); } export function updateTraceabilityPreview( id: string, data: Omit, ) { return requestClient.post(`/traceability/previews/${id}`, data); } export function deleteTraceabilityPreview(id: string) { return requestClient.delete(`/traceability/previews/${id}`); } export function syncTraceabilityPreviewToTemplate(id: string) { return requestClient.post(`/traceability/previews/${id}/sync-template`); } export function getTraceabilityNodeLibrary() { return requestClient.get( '/traceability/node-library', ); } export function createTraceabilityNodeLibrary( data: Omit, ) { return requestClient.post( '/traceability/node-library', data, ); } export function updateTraceabilityNodeLibrary( id: string, data: Omit, ) { return requestClient.post( `/traceability/node-library/${id}`, data, ); } export function deleteTraceabilityNodeLibrary(id: string) { return requestClient.delete(`/traceability/node-library/${id}`); } export function getTraceabilityTemplate(id: string) { return requestClient.get( `/traceability/templates/${id}`, ); } export function createTraceabilityTemplate( data: Omit, ) { return requestClient.post('/traceability/templates', data); } export function updateTraceabilityTemplate( id: string, data: Omit, ) { return requestClient.post(`/traceability/templates/${id}`, data); } export function deleteTraceabilityTemplate(id: string) { return requestClient.delete(`/traceability/templates/${id}`); } export function getTraceabilityBatches() { return requestClient.get( '/traceability/batches', ); } export function getTraceabilityBatch(id: string) { return requestClient.get( `/traceability/batches/${id}`, ); } export function createTraceabilityBatch(data: { templateId: string; batchName: string; batchCode: string; productName?: string; summary?: string; coverImage?: string; tags?: string[]; }) { return requestClient.post('/traceability/batches', data); } export function deleteTraceabilityBatch(id: string) { return requestClient.delete(`/traceability/batches/${id}`); } export function updateTraceabilityBatchBase(id: string, data: any) { return requestClient.post(`/traceability/batches/${id}/base`, data); } export function updateTraceabilityBatchStep( batchId: string, stepId: string, data: { operatorName?: string; status?: string; values?: Record; completedAt?: string; }, ) { return requestClient.post(`/traceability/batches/${batchId}/steps/${stepId}`, data); } export function publishTraceabilityBatch(id: string) { return requestClient.post(`/traceability/batches/${id}/publish`); } export function getTraceabilityPublicDetail(code: string) { return requestClient.get( `/traceability/public/by-code/${code}`, ); } export function getTraceabilityPreviewDetail(code: string) { return requestClient.get( `/traceability/public/preview/by-code/${code}`, ); } export function getTraceabilityFeedbackList() { return requestClient.get( '/traceability/feedback', ); } export function submitTraceabilityFeedback(data: { batchCode?: string; batchId?: string; type: string; contact?: string; content: string; source?: string; rating?: number; }) { return requestClient.post('/traceability/public/feedback', data); } export function uploadTraceabilityImage(data: FormData) { return requestClient.post( '/traceability/files/upload-image', data, { headers: { 'Content-Type': 'multipart/form-data', }, }, ); } export function getTraceabilityFileAssets(assetType: string, limit = 24) { return requestClient.get( '/traceability/files/history', { params: { assetType, limit } }, ); } export function deleteTraceabilityFileAsset(id: string) { return requestClient.post('/traceability/files/history/delete', { id }); } export function getTraceabilityUploadToken(data: { bucketName?: string; objectName: string; expiresMinutes?: number; }) { return requestClient.post( '/traceability/files/presigned-put', data, ); } export function getTraceabilityTempUrl(data: { bucketName?: string; objectName?: string; objectDir?: string; expiresSeconds?: number; }) { return requestClient.post( '/traceability/files/temp-url', data, ); } export function moveTraceabilityFile(data: { bucketName?: string; sourceObjectName: string; targetObjectName: string; }) { return requestClient.post( '/traceability/files/move', data, ); } export function deleteTraceabilityFile(data: { bucketName?: string; objectName: string; }) { return requestClient.post('/traceability/files/delete', data); }