- Stripped 11 business crates (health, ai, dialysis, plugins) - Cleaned AppState, AppConfig, main.rs from business coupling - Reduced migrations from 169 to 53 (base-only) - Removed health_provider trait from erp-core - Removed business integration tests - Removed gateway rate limiting middleware - Base capabilities: auth, RBAC, JWT, config, workflow, message, plugin, audit, crypto, RLS, multi-tenant Cargo check: OK Cargo test: OK
209 lines
5.0 KiB
TypeScript
209 lines
5.0 KiB
TypeScript
import client from '../client';
|
||
import type { PaginatedResponse } from '../types';
|
||
|
||
// ---------------------------------------------------------------------------
|
||
// 媒体文件类型
|
||
// ---------------------------------------------------------------------------
|
||
|
||
export interface MediaItem {
|
||
id: string;
|
||
tenant_id: string;
|
||
folder_id?: string;
|
||
filename: string;
|
||
storage_path: string;
|
||
thumbnail_path?: string;
|
||
content_type: string;
|
||
file_size: number;
|
||
width?: number;
|
||
height?: number;
|
||
alt_text?: string;
|
||
is_public: boolean;
|
||
created_at: string;
|
||
updated_at: string;
|
||
created_by?: string;
|
||
updated_by?: string;
|
||
version: number;
|
||
}
|
||
|
||
export interface MediaListParams {
|
||
page?: number;
|
||
page_size?: number;
|
||
folder_id?: string;
|
||
content_type?: string;
|
||
keyword?: string;
|
||
is_public?: boolean;
|
||
}
|
||
|
||
export interface UpdateMediaReq {
|
||
filename?: string;
|
||
alt_text?: string;
|
||
is_public?: boolean;
|
||
folder_id?: string;
|
||
version: number;
|
||
}
|
||
|
||
export interface MoveMediaReq {
|
||
folder_id?: string;
|
||
version: number;
|
||
}
|
||
|
||
export interface CropReq {
|
||
x: number;
|
||
y: number;
|
||
width: number;
|
||
height: number;
|
||
version: number;
|
||
}
|
||
|
||
// ---------------------------------------------------------------------------
|
||
// 文件夹类型
|
||
// ---------------------------------------------------------------------------
|
||
|
||
export interface FolderItem {
|
||
id: string;
|
||
tenant_id: string;
|
||
name: string;
|
||
parent_id?: string;
|
||
sort_order: number;
|
||
children: FolderItem[];
|
||
item_count: number;
|
||
created_at: string;
|
||
updated_at: string;
|
||
version: number;
|
||
}
|
||
|
||
export interface CreateFolderReq {
|
||
name: string;
|
||
parent_id?: string;
|
||
sort_order?: number;
|
||
}
|
||
|
||
export interface UpdateFolderReq {
|
||
name?: string;
|
||
parent_id?: string;
|
||
sort_order?: number;
|
||
version: number;
|
||
}
|
||
|
||
// ---------------------------------------------------------------------------
|
||
// 媒体文件 API
|
||
// ---------------------------------------------------------------------------
|
||
|
||
export const mediaApi = {
|
||
/** 分页查询媒体文件列表 */
|
||
list: async (params: MediaListParams) => {
|
||
const { data } = await client.get<{
|
||
success: boolean;
|
||
data: PaginatedResponse<MediaItem>;
|
||
}>('/health/media', { params });
|
||
return data.data;
|
||
},
|
||
|
||
/** 上传媒体文件(multipart/form-data) */
|
||
upload: async (formData: FormData) => {
|
||
const { data } = await client.post<{
|
||
success: boolean;
|
||
data: MediaItem;
|
||
}>('/health/media/upload', formData, {
|
||
headers: { 'Content-Type': 'multipart/form-data' },
|
||
});
|
||
return data.data;
|
||
},
|
||
|
||
/** 获取单个媒体文件详情 */
|
||
get: async (id: string) => {
|
||
const { data } = await client.get<{
|
||
success: boolean;
|
||
data: MediaItem;
|
||
}>(`/health/media/${id}`);
|
||
return data.data;
|
||
},
|
||
|
||
/** 更新媒体文件信息 */
|
||
update: async (id: string, req: UpdateMediaReq) => {
|
||
const { data } = await client.put<{
|
||
success: boolean;
|
||
data: MediaItem;
|
||
}>(`/health/media/${id}`, req);
|
||
return data.data;
|
||
},
|
||
|
||
/** 删除媒体文件 */
|
||
delete: async (id: string, version: number) => {
|
||
const { data } = await client.delete<{
|
||
success: boolean;
|
||
data: null;
|
||
}>(`/health/media/${id}`, { data: { version } });
|
||
return data.data;
|
||
},
|
||
|
||
/** 移动媒体文件到指定文件夹 */
|
||
move: async (id: string, req: MoveMediaReq) => {
|
||
const { data } = await client.post<{
|
||
success: boolean;
|
||
data: MediaItem;
|
||
}>(`/health/media/${id}/move`, req);
|
||
return data.data;
|
||
},
|
||
|
||
/** 批量删除媒体文件 */
|
||
batchDelete: async (ids: string[]) => {
|
||
const { data } = await client.post<{
|
||
success: boolean;
|
||
data: null;
|
||
}>('/health/media/batch-delete', { ids });
|
||
return data.data;
|
||
},
|
||
|
||
/** 裁剪媒体文件 */
|
||
crop: async (id: string, req: CropReq) => {
|
||
const { data } = await client.post<{
|
||
success: boolean;
|
||
data: MediaItem;
|
||
}>(`/health/media/${id}/crop`, req);
|
||
return data.data;
|
||
},
|
||
};
|
||
|
||
// ---------------------------------------------------------------------------
|
||
// 文件夹 API
|
||
// ---------------------------------------------------------------------------
|
||
|
||
export const mediaFolderApi = {
|
||
/** 获取文件夹树形结构 */
|
||
tree: async () => {
|
||
const { data } = await client.get<{
|
||
success: boolean;
|
||
data: FolderItem[];
|
||
}>('/health/media-folders');
|
||
return data.data;
|
||
},
|
||
|
||
/** 创建文件夹 */
|
||
create: async (req: CreateFolderReq) => {
|
||
const { data } = await client.post<{
|
||
success: boolean;
|
||
data: FolderItem;
|
||
}>('/health/media-folders', req);
|
||
return data.data;
|
||
},
|
||
|
||
/** 更新文件夹 */
|
||
update: async (id: string, req: UpdateFolderReq) => {
|
||
const { data } = await client.put<{
|
||
success: boolean;
|
||
data: FolderItem;
|
||
}>(`/health/media-folders/${id}`, req);
|
||
return data.data;
|
||
},
|
||
|
||
/** 删除文件夹 */
|
||
delete: async (id: string, version: number) => {
|
||
const { data } = await client.delete<{
|
||
success: boolean;
|
||
data: null;
|
||
}>(`/health/media-folders/${id}`, { data: { version } });
|
||
return data.data;
|
||
},
|
||
};
|