feat: menu
This commit is contained in:
@@ -1,116 +0,0 @@
|
||||
// hooks/useEnhancedTable.ts
|
||||
import { useRef, useState, useCallback } from "react";
|
||||
import { ActionType } from "@ant-design/pro-components";
|
||||
import { message } from "antd";
|
||||
import {
|
||||
UseEnhancedTableOptions,
|
||||
UseEnhancedTableReturn,
|
||||
} from "@/components/EnhancedProTable/types";
|
||||
|
||||
export function useEnhancedTable<T>(
|
||||
options: UseEnhancedTableOptions<T> = {}
|
||||
): UseEnhancedTableReturn<T> {
|
||||
const actionRef = useRef<ActionType>(undefined);
|
||||
const [selectedRowKeys, setSelectedRowKeys] = useState<React.Key[]>([]);
|
||||
const [selectedRows, setSelectedRows] = useState<T[]>([]);
|
||||
const [loading, setLoading] = useState(false);
|
||||
|
||||
const { onAdd, onEdit, onDelete, onView, onExport, onBatchDelete } = options;
|
||||
|
||||
// 刷新表格
|
||||
const reload = useCallback(() => {
|
||||
actionRef.current?.reload();
|
||||
}, []);
|
||||
|
||||
// 重置表格
|
||||
const reset = useCallback(() => {
|
||||
actionRef.current?.reset?.();
|
||||
setSelectedRowKeys([]);
|
||||
setSelectedRows([]);
|
||||
}, []);
|
||||
|
||||
// 清空选择
|
||||
const clearSelection = useCallback(() => {
|
||||
setSelectedRowKeys([]);
|
||||
setSelectedRows([]);
|
||||
}, []);
|
||||
|
||||
// 处理删除
|
||||
const handleDelete = useCallback(
|
||||
async (record: T) => {
|
||||
if (!onDelete) return;
|
||||
|
||||
setLoading(true);
|
||||
try {
|
||||
const success = await onDelete(record);
|
||||
if (success) {
|
||||
message.success("删除成功");
|
||||
reload();
|
||||
}
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
},
|
||||
[onDelete, reload]
|
||||
);
|
||||
|
||||
// 处理批量删除
|
||||
const handleBatchDelete = useCallback(
|
||||
async (keys: React.Key[]) => {
|
||||
if (!onBatchDelete || keys.length === 0) return;
|
||||
|
||||
setLoading(true);
|
||||
try {
|
||||
const success = await onBatchDelete(keys);
|
||||
if (success) {
|
||||
message.success("批量删除成功");
|
||||
clearSelection();
|
||||
reload();
|
||||
}
|
||||
} catch (error) {
|
||||
message.error("批量删除失败");
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
},
|
||||
[onBatchDelete, clearSelection, reload]
|
||||
);
|
||||
|
||||
// 处理导出
|
||||
const handleExport = useCallback(
|
||||
(rows: T[]) => {
|
||||
if (!onExport) return;
|
||||
if (rows.length === 0) {
|
||||
message.warning("请选择要导出的数据");
|
||||
return;
|
||||
}
|
||||
onExport(rows);
|
||||
},
|
||||
[onExport]
|
||||
);
|
||||
|
||||
return {
|
||||
actionRef,
|
||||
selectedRowKeys,
|
||||
selectedRows,
|
||||
loading,
|
||||
setSelectedRowKeys,
|
||||
setSelectedRows,
|
||||
reload,
|
||||
reset,
|
||||
clearSelection,
|
||||
handleDelete,
|
||||
handleBatchDelete,
|
||||
handleExport,
|
||||
actions: {
|
||||
add: onAdd,
|
||||
edit: onEdit,
|
||||
delete: handleDelete,
|
||||
view: onView,
|
||||
export: handleExport,
|
||||
batchDelete: handleBatchDelete,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export type { UseEnhancedTableOptions, UseEnhancedTableReturn };
|
||||
131
src/hooks/antd/useModal.ts
Normal file
131
src/hooks/antd/useModal.ts
Normal file
@@ -0,0 +1,131 @@
|
||||
import { App } from "antd";
|
||||
import { useCallback } from "react";
|
||||
|
||||
export interface ConfirmOptions {
|
||||
title: string;
|
||||
content?: string;
|
||||
okText?: string;
|
||||
cancelText?: string;
|
||||
onOk?: () => Promise<void> | void;
|
||||
onCancel?: () => void;
|
||||
type?: "confirm" | "info" | "success" | "error" | "warning";
|
||||
}
|
||||
|
||||
export const useModal = () => {
|
||||
const { modal, message } = App.useApp();
|
||||
|
||||
// 通用确认对话框
|
||||
const showConfirm = useCallback(
|
||||
(options: ConfirmOptions) => {
|
||||
const {
|
||||
title,
|
||||
content,
|
||||
okText = "确定",
|
||||
cancelText = "取消",
|
||||
onOk,
|
||||
onCancel,
|
||||
type = "confirm",
|
||||
} = options;
|
||||
|
||||
const modalMethod = modal[type];
|
||||
|
||||
return modalMethod({
|
||||
title,
|
||||
content,
|
||||
okText,
|
||||
cancelText,
|
||||
onOk,
|
||||
onCancel,
|
||||
});
|
||||
},
|
||||
[modal]
|
||||
);
|
||||
|
||||
// 删除确认对话框
|
||||
const showDeleteConfirm = useCallback(
|
||||
(
|
||||
onConfirm: () => Promise<void> | void,
|
||||
title: string = "删除确认",
|
||||
content: string = "确定要删除吗?此操作不可恢复。"
|
||||
) => {
|
||||
return modal.confirm({
|
||||
title,
|
||||
content,
|
||||
okText: "删除",
|
||||
cancelText: "取消",
|
||||
okType: "danger",
|
||||
onOk: async () => {
|
||||
try {
|
||||
await onConfirm();
|
||||
message.success("删除成功");
|
||||
} catch (error) {
|
||||
message.error("删除失败");
|
||||
throw error;
|
||||
}
|
||||
},
|
||||
});
|
||||
},
|
||||
[modal, message]
|
||||
);
|
||||
|
||||
// 编辑确认对话框
|
||||
const showEditConfirm = useCallback(
|
||||
(
|
||||
onConfirm: () => Promise<void> | void,
|
||||
title: string = "编辑确认",
|
||||
content: string = "确定要保存修改吗?"
|
||||
) => {
|
||||
return modal.confirm({
|
||||
title,
|
||||
content,
|
||||
okText: "保存",
|
||||
cancelText: "取消",
|
||||
onOk: async () => {
|
||||
try {
|
||||
await onConfirm();
|
||||
message.success("保存成功");
|
||||
} catch (error) {
|
||||
message.error("保存失败");
|
||||
throw error;
|
||||
}
|
||||
},
|
||||
});
|
||||
},
|
||||
[modal, message]
|
||||
);
|
||||
|
||||
// 状态切换确认对话框
|
||||
const showStatusConfirm = useCallback(
|
||||
(
|
||||
onConfirm: () => Promise<void> | void,
|
||||
action: string,
|
||||
itemName: string = "该项"
|
||||
) => {
|
||||
return modal.confirm({
|
||||
title: `${action}确认`,
|
||||
content: `确定要${action}${itemName}吗?`,
|
||||
okText: action,
|
||||
cancelText: "取消",
|
||||
onOk: async () => {
|
||||
try {
|
||||
await onConfirm();
|
||||
message.success(`${action}成功`);
|
||||
} catch (error) {
|
||||
message.error(`${action}失败`);
|
||||
throw error;
|
||||
}
|
||||
},
|
||||
});
|
||||
},
|
||||
[modal, message]
|
||||
);
|
||||
|
||||
return {
|
||||
modal,
|
||||
message,
|
||||
showConfirm,
|
||||
showDeleteConfirm,
|
||||
showEditConfirm,
|
||||
showStatusConfirm,
|
||||
};
|
||||
};
|
||||
51
src/hooks/antd/useRequest.ts
Normal file
51
src/hooks/antd/useRequest.ts
Normal file
@@ -0,0 +1,51 @@
|
||||
// hooks/useRequest.ts
|
||||
import { useState, useCallback } from "react";
|
||||
import { message } from "antd";
|
||||
|
||||
export interface UseRequestOptions<T> {
|
||||
onSuccess?: (data: T) => void;
|
||||
onError?: (error: any) => void;
|
||||
showErrorMessage?: boolean;
|
||||
}
|
||||
|
||||
export function useRequest<T = any, P = any>(
|
||||
requestFn: (params: P) => Promise<T>,
|
||||
options: UseRequestOptions<T> = {}
|
||||
) {
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [data, setData] = useState<T | null>(null);
|
||||
const [error, setError] = useState<any>(null);
|
||||
|
||||
const { onSuccess, onError, showErrorMessage = true } = options;
|
||||
|
||||
const run = useCallback(
|
||||
async (params: P) => {
|
||||
setLoading(true);
|
||||
setError(null);
|
||||
|
||||
try {
|
||||
const result = await requestFn(params);
|
||||
setData(result);
|
||||
onSuccess?.(result);
|
||||
return result;
|
||||
} catch (err) {
|
||||
setError(err);
|
||||
onError?.(err);
|
||||
if (showErrorMessage) {
|
||||
message.error("请求失败");
|
||||
}
|
||||
throw err;
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
},
|
||||
[requestFn, onSuccess, onError, showErrorMessage]
|
||||
);
|
||||
|
||||
return {
|
||||
loading,
|
||||
data,
|
||||
error,
|
||||
run,
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user