2026-06-18 15:05:02 +08:00
|
|
|
|
import { requestClient } from '#/api/request';
|
|
|
|
|
|
|
|
|
|
|
|
const prefix = 'file-gallery/';
|
|
|
|
|
|
|
|
|
|
|
|
export interface FileGalleryItem {
|
|
|
|
|
|
id: number;
|
|
|
|
|
|
url: string;
|
2026-06-18 16:42:51 +08:00
|
|
|
|
file_name?: string;
|
2026-06-18 15:05:02 +08:00
|
|
|
|
file_size: number;
|
|
|
|
|
|
file_size_text: string;
|
2026-06-18 16:42:51 +08:00
|
|
|
|
type?: number;
|
|
|
|
|
|
type_text?: string;
|
|
|
|
|
|
type_icon?: string;
|
2026-07-06 17:03:35 +08:00
|
|
|
|
group_ids?: number[];
|
2026-06-18 15:05:02 +08:00
|
|
|
|
created_at?: string;
|
|
|
|
|
|
original_name?: string;
|
2026-06-18 16:42:51 +08:00
|
|
|
|
object_key?: string;
|
|
|
|
|
|
source?: number;
|
2026-08-18 09:12:07 +08:00
|
|
|
|
is_qrcode?: number;
|
|
|
|
|
|
ref_count?: number;
|
|
|
|
|
|
folder_id?: number;
|
2026-06-18 15:05:02 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-06-18 16:42:51 +08:00
|
|
|
|
export interface FileTypeItem {
|
|
|
|
|
|
id: number;
|
|
|
|
|
|
name: string;
|
|
|
|
|
|
icon?: string;
|
|
|
|
|
|
value: number;
|
|
|
|
|
|
suffix: string;
|
|
|
|
|
|
sort: number;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-10-19 16:20:07 +08:00
|
|
|
|
/** 扫描写入的引用位置(详情展示,含表/字段注释) */
|
|
|
|
|
|
export interface FileGalleryRefLoc {
|
|
|
|
|
|
connection: string;
|
|
|
|
|
|
connection_text: string;
|
|
|
|
|
|
table: string;
|
|
|
|
|
|
/** 表 COMMENT,可能为空 */
|
|
|
|
|
|
table_comment?: string;
|
|
|
|
|
|
column: string;
|
|
|
|
|
|
/** 字段 COMMENT,可能为空 */
|
|
|
|
|
|
column_comment?: string;
|
|
|
|
|
|
count: number;
|
|
|
|
|
|
label: string;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-06-18 16:42:51 +08:00
|
|
|
|
export interface FileGalleryDetail extends FileGalleryItem {
|
|
|
|
|
|
source_text?: string;
|
|
|
|
|
|
updated_at?: string;
|
2026-10-19 16:20:07 +08:00
|
|
|
|
ref_scanned_at?: number | string;
|
|
|
|
|
|
/** 引用位置列表,未扫描或未命中为空数组 */
|
|
|
|
|
|
ref_locs?: FileGalleryRefLoc[];
|
2026-06-18 16:42:51 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-08-18 09:12:07 +08:00
|
|
|
|
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;
|
2026-10-19 16:20:07 +08:00
|
|
|
|
/** 上次 OSS 同步完成日期 YYYYMMDD,空表示尚未同步 */
|
|
|
|
|
|
oss_last_sync_date?: string;
|
2026-08-18 09:12:07 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export interface FileGalleryListParams {
|
2026-06-18 16:42:51 +08:00
|
|
|
|
page?: number;
|
|
|
|
|
|
page_size?: number;
|
|
|
|
|
|
pid?: number;
|
|
|
|
|
|
type?: number;
|
2026-07-06 17:03:35 +08:00
|
|
|
|
group_id?: number;
|
2026-06-18 16:42:51 +08:00
|
|
|
|
keyword?: string;
|
2026-08-18 09:12:07 +08:00
|
|
|
|
exclude_qrcode?: number;
|
2026-10-19 16:20:07 +08:00
|
|
|
|
/** all|referenced|unreferenced */
|
|
|
|
|
|
ref_filter?: string;
|
|
|
|
|
|
/** @deprecated 用 ref_filter=unreferenced */
|
2026-08-18 09:12:07 +08:00
|
|
|
|
unref_only?: number;
|
|
|
|
|
|
folder_id?: number;
|
|
|
|
|
|
unfiled?: number;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export async function getFileGalleryList(params?: FileGalleryListParams) {
|
2026-06-18 15:05:02 +08:00
|
|
|
|
return requestClient.get<{
|
|
|
|
|
|
items: FileGalleryItem[];
|
|
|
|
|
|
page: number;
|
|
|
|
|
|
page_size: number;
|
2026-08-18 09:12:07 +08:00
|
|
|
|
total: number;
|
2026-06-18 15:05:02 +08:00
|
|
|
|
}>(`${prefix}list`, { params });
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-06-18 16:42:51 +08:00
|
|
|
|
export async function getFileGalleryDetail(id: number) {
|
2026-08-18 09:12:07 +08:00
|
|
|
|
return requestClient.get<FileGalleryDetail>(`${prefix}detail`, {
|
|
|
|
|
|
params: { id },
|
|
|
|
|
|
});
|
2026-06-18 16:42:51 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-08-18 09:12:07 +08:00
|
|
|
|
export async function deleteFileGalleryItem(id: number | number[]) {
|
|
|
|
|
|
const data = Array.isArray(id) ? { ids: id } : { id };
|
|
|
|
|
|
return requestClient.post<any>(`${prefix}delete`, data);
|
2026-06-18 15:05:02 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-06-18 16:42:51 +08:00
|
|
|
|
export async function renameFileGalleryItem(id: number, file_name: string) {
|
|
|
|
|
|
return requestClient.post<any>(`${prefix}rename`, { id, file_name });
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export async function moveFileGalleryType(id: number, type: number) {
|
|
|
|
|
|
return requestClient.post<any>(`${prefix}move-type`, { id, type });
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export async function batchArchiveFiles() {
|
|
|
|
|
|
return requestClient.post<{
|
|
|
|
|
|
file_name_filled: number;
|
2026-08-18 09:12:07 +08:00
|
|
|
|
reclassified: number;
|
2026-06-18 16:42:51 +08:00
|
|
|
|
}>(`${prefix}batch-archive`);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export async function getFileTypes() {
|
|
|
|
|
|
return requestClient.get<FileTypeItem[]>(`${prefix}file-types`);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-10-19 16:20:07 +08:00
|
|
|
|
/** 规划 OSS 同步日期分组(full 全部 / incremental 从上次同步日期起) */
|
|
|
|
|
|
export async function planFileGalleryOssSync(data?: {
|
|
|
|
|
|
mode?: 'full' | 'incremental';
|
|
|
|
|
|
}) {
|
2026-09-30 17:02:54 +08:00
|
|
|
|
return requestClient.post<{
|
2026-10-19 16:20:07 +08:00
|
|
|
|
last_sync_date: string;
|
2026-09-30 17:02:54 +08:00
|
|
|
|
mode: 'full' | 'incremental';
|
|
|
|
|
|
prefixes: string[];
|
|
|
|
|
|
since_date: string;
|
2026-10-19 16:20:07 +08:00
|
|
|
|
total: number;
|
2026-09-30 17:02:54 +08:00
|
|
|
|
}>(`${prefix}sync-oss-plan`, data ?? {});
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-10-19 16:20:07 +08:00
|
|
|
|
/** 从 OSS 同步一批(按日期 prefix + marker;全部组结束后 finalize=1 并落库 last_sync_date) */
|
2026-09-30 17:02:54 +08:00
|
|
|
|
export async function syncFileGalleryFromOss(data?: {
|
2026-10-19 16:20:07 +08:00
|
|
|
|
finalize?: number;
|
|
|
|
|
|
last_sync_date?: string;
|
2026-09-30 17:02:54 +08:00
|
|
|
|
limit?: number;
|
|
|
|
|
|
marker?: string;
|
|
|
|
|
|
prefix?: string;
|
|
|
|
|
|
}) {
|
2026-08-18 09:12:07 +08:00
|
|
|
|
return requestClient.post<{
|
2026-09-30 17:02:54 +08:00
|
|
|
|
done: boolean;
|
|
|
|
|
|
folder_created: number;
|
2026-10-19 16:20:07 +08:00
|
|
|
|
last_sync_date?: string;
|
|
|
|
|
|
next_marker: string;
|
2026-09-30 17:02:54 +08:00
|
|
|
|
prefix: string;
|
2026-10-19 16:20:07 +08:00
|
|
|
|
scanned: number;
|
|
|
|
|
|
skipped: number;
|
|
|
|
|
|
synced: number;
|
2026-09-30 17:02:54 +08:00
|
|
|
|
}>(`${prefix}sync-oss`, data ?? {});
|
2026-06-18 15:05:02 +08:00
|
|
|
|
}
|
2026-07-06 17:03:35 +08:00
|
|
|
|
|
|
|
|
|
|
/** 文件加入自定义分组 */
|
|
|
|
|
|
export async function addFileToGroup(file_id: number, group_id: number) {
|
2026-08-18 09:12:07 +08:00
|
|
|
|
return requestClient.post<any>(`${prefix}add-to-group`, {
|
|
|
|
|
|
file_id,
|
|
|
|
|
|
group_id,
|
|
|
|
|
|
});
|
2026-07-06 17:03:35 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/** 文件移出自定义分组 */
|
|
|
|
|
|
export async function removeFileFromGroup(file_id: number, group_id: number) {
|
2026-08-18 09:12:07 +08:00
|
|
|
|
return requestClient.post<any>(`${prefix}remove-from-group`, {
|
|
|
|
|
|
file_id,
|
|
|
|
|
|
group_id,
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/** 素材库统计:总数 / 容量 / 未引用 / 可回收 */
|
|
|
|
|
|
export async function getFileGalleryStats() {
|
|
|
|
|
|
return requestClient.get<FileGalleryStats>(`${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,
|
|
|
|
|
|
},
|
|
|
|
|
|
);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-10-19 16:20:07 +08:00
|
|
|
|
/** 扫描计划中的单表: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;
|
|
|
|
|
|
}) {
|
2026-08-18 09:12:07 +08:00
|
|
|
|
return requestClient.post<{
|
2026-10-19 16:20:07 +08:00
|
|
|
|
batch_size: number;
|
|
|
|
|
|
batch_tables?: FileRefScanTableItem[];
|
|
|
|
|
|
current_table?: string;
|
|
|
|
|
|
done: boolean;
|
|
|
|
|
|
done_table_count?: number;
|
|
|
|
|
|
elapsed_ms?: number;
|
|
|
|
|
|
job_id: string;
|
2026-08-18 09:12:07 +08:00
|
|
|
|
mysql_columns: number;
|
|
|
|
|
|
mysql_failed: number;
|
|
|
|
|
|
old_mysql_columns: number;
|
|
|
|
|
|
old_mysql_failed: number;
|
2026-10-19 16:20:07 +08:00
|
|
|
|
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 ?? {});
|
2026-08-18 09:12:07 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/** 批量加入分组(移动到文件夹) */
|
|
|
|
|
|
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,
|
|
|
|
|
|
},
|
|
|
|
|
|
);
|
2026-07-06 17:03:35 +08:00
|
|
|
|
}
|