feat: initialize ERP base platform (extracted from HMS)

- 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
This commit is contained in:
iven
2026-05-31 20:35:57 +08:00
commit 59856ac2fc
639 changed files with 124710 additions and 0 deletions

View File

@@ -0,0 +1,208 @@
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;
},
};