import { requestClient } from '#/api/request'; const prefix = 'file-gallery/'; export interface FileGalleryItem { id: number; url: string; file_name?: string; file_size: number; file_size_text: string; type?: number; type_text?: string; type_icon?: string; group_ids?: number[]; created_at?: string; original_name?: string; object_key?: string; source?: number; is_qrcode?: number; ref_count?: number; folder_id?: number; } export interface FileTypeItem { id: number; name: string; icon?: string; value: number; suffix: string; sort: number; } /** 扫描写入的引用位置(详情展示,含表/字段注释) */ export interface FileGalleryRefLoc { connection: string; connection_text: string; table: string; /** 表 COMMENT,可能为空 */ table_comment?: string; column: string; /** 字段 COMMENT,可能为空 */ column_comment?: string; count: number; label: string; } export interface FileGalleryDetail extends FileGalleryItem { source_text?: string; updated_at?: string; ref_scanned_at?: number | string; /** 引用位置列表,未扫描或未命中为空数组 */ ref_locs?: FileGalleryRefLoc[]; } export interface FileGalleryStats { total_count: number; total_size: number; total_size_text: string; unref_count: number; recyclable_size: number; recyclable_size_text: string; has_scanned: boolean; /** 上次 OSS 同步完成日期 YYYYMMDD,空表示尚未同步 */ oss_last_sync_date?: string; } export interface FileGalleryListParams { page?: number; page_size?: number; pid?: number; type?: number; group_id?: number; keyword?: string; exclude_qrcode?: number; /** all|referenced|unreferenced */ ref_filter?: string; /** @deprecated 用 ref_filter=unreferenced */ unref_only?: number; folder_id?: number; unfiled?: number; } export async function getFileGalleryList(params?: FileGalleryListParams) { return requestClient.get<{ items: FileGalleryItem[]; page: number; page_size: number; total: number; }>(`${prefix}list`, { params }); } export async function getFileGalleryDetail(id: number) { return requestClient.get(`${prefix}detail`, { params: { id }, }); } export async function deleteFileGalleryItem(id: number | number[]) { const data = Array.isArray(id) ? { ids: id } : { id }; return requestClient.post(`${prefix}delete`, data); } export async function renameFileGalleryItem(id: number, file_name: string) { return requestClient.post(`${prefix}rename`, { id, file_name }); } export async function moveFileGalleryType(id: number, type: number) { return requestClient.post(`${prefix}move-type`, { id, type }); } export async function batchArchiveFiles() { return requestClient.post<{ file_name_filled: number; reclassified: number; }>(`${prefix}batch-archive`); } export async function getFileTypes() { return requestClient.get(`${prefix}file-types`); } /** 规划 OSS 同步日期分组(full 全部 / incremental 从上次同步日期起) */ export async function planFileGalleryOssSync(data?: { mode?: 'full' | 'incremental'; }) { return requestClient.post<{ last_sync_date: string; mode: 'full' | 'incremental'; prefixes: string[]; since_date: string; total: number; }>(`${prefix}sync-oss-plan`, data ?? {}); } /** 从 OSS 同步一批(按日期 prefix + marker;全部组结束后 finalize=1 并落库 last_sync_date) */ export async function syncFileGalleryFromOss(data?: { finalize?: number; last_sync_date?: string; limit?: number; marker?: string; prefix?: string; }) { return requestClient.post<{ done: boolean; folder_created: number; last_sync_date?: string; next_marker: string; prefix: string; scanned: number; skipped: number; synced: number; }>(`${prefix}sync-oss`, data ?? {}); } /** 文件加入自定义分组 */ export async function addFileToGroup(file_id: number, group_id: number) { return requestClient.post(`${prefix}add-to-group`, { file_id, group_id, }); } /** 文件移出自定义分组 */ export async function removeFileFromGroup(file_id: number, group_id: number) { return requestClient.post(`${prefix}remove-from-group`, { file_id, group_id, }); } /** 素材库统计:总数 / 容量 / 未引用 / 可回收 */ export async function getFileGalleryStats() { return requestClient.get(`${prefix}stats`); } /** 右键标记或取消二维码 */ export async function markFileQrcode(id: number, is_qrcode: number) { return requestClient.post<{ id: number; is_qrcode: number }>( `${prefix}mark-qrcode`, { id, is_qrcode, }, ); } /** 扫描计划中的单表:pending 未开始 / scanning 扫描中 / done 完成 */ export interface FileRefScanTableItem { connection: string; table: string; /** 兼容字段,等同 total_columns */ columns: number; total_columns?: number; done_columns?: number; failed: number; status?: 'done' | 'pending' | 'scanning'; } /** 预览将扫描的表清单(全部 pending,不开始扫) */ export async function planFileGalleryScanRefs() { return requestClient.get<{ column_total: number; plan_tables: FileRefScanTableItem[]; table_count: number; }>(`${prefix}scan-refs-plan`); } /** 分批扫描业务表 URL 引用;循环传 job_id 直到 done,支持断点续扫 */ export async function scanFileGalleryRefs(data?: { batch_size?: number; job_id?: string; }) { return requestClient.post<{ batch_size: number; batch_tables?: FileRefScanTableItem[]; current_table?: string; done: boolean; done_table_count?: number; elapsed_ms?: number; job_id: string; mysql_columns: number; mysql_failed: number; old_mysql_columns: number; old_mysql_failed: number; pending_table_count?: number; phase: string; plan_tables?: FileRefScanTableItem[]; processed: number; progress: number; referenced?: number; scanned_files?: number; scanned_tables?: FileRefScanTableItem[]; scanning_table_count?: number; table_count?: number; total: number; unreferenced?: number; }>(`${prefix}scan-refs`, data ?? {}); } /** 批量加入分组(移动到文件夹) */ export async function batchAddFilesToGroup(ids: number[], group_id: number) { return requestClient.post<{ count: number; group_id: number }>( `${prefix}batch-add-to-group`, { ids, group_id, }, ); } /** 批量移入真实文件夹 */ export async function batchMoveFilesToFolder(ids: number[], folder_id: number) { return requestClient.post<{ count: number; folder_id: number }>( `${prefix}batch-move-to-folder`, { ids, folder_id, }, ); }