collect-system/packages/client/src/api/hooks/useEntity.ts

118 lines
4.5 KiB
TypeScript
Raw Normal View History

2025-02-06 16:32:52 +08:00
import type { UseTRPCMutationResult } from "@trpc/react-query/shared";
import { api, type RouterInputs, type RouterOutputs } from "../trpc";
/**
* MutationType mutation
* @template T - 'post', 'user'
* @description RouterInputs[T] mutation 'create', 'update'
*/
type MutationType<T extends keyof RouterInputs> = keyof {
[K in keyof RouterInputs[T]]: K extends
| "create"
| "update"
| "deleteMany"
| "softDeleteByIds"
| "restoreByIds"
| "updateOrder"
? RouterInputs[T][K]
: never;
};
/**
* MutationOptions mutation
* @template T -
* @template K - mutation
* @description onSuccess mutation
*/
type MutationOptions<
T extends keyof RouterInputs,
K extends MutationType<T>,
> = {
onSuccess?: (
data: RouterOutputs[T][K], // mutation 成功后的返回数据
variables: RouterInputs[T][K], // mutation 的输入参数
context?: unknown // 可选的上下文信息
) => void;
};
/**
* EntityOptions mutation
* @template T -
* @description mutation MutationOptions
*/
type EntityOptions<T extends keyof RouterInputs> = {
[K in MutationType<T>]?: MutationOptions<T, K>;
};
/**
* UseTRPCMutationResult
* @template T -
* @template K - mutation
* @description UseTRPCMutationResult 使
*/
export type MutationResult<
T extends keyof RouterInputs,
K extends MutationType<T>,
> = UseTRPCMutationResult<
RouterOutputs[T][K], // mutation 成功后的返回数据
unknown, // mutation 的错误类型
RouterInputs[T][K], // mutation 的输入参数
unknown // mutation 的上下文类型
>;
/**
* Hook mutation
* @template T - 'post', 'user'
* @param {T} key -
* @param {EntityOptions<T>} [options] - mutation
* @returns mutation
* @description Hook mutation create, update, deleteMany mutation
*/
export function useEntity<T extends keyof RouterInputs>(
key: T,
options?: EntityOptions<T>
) {
const utils = api.useUtils(); // 获取 tRPC 的工具函数,用于操作缓存
/**
* mutation
* @template K - mutation
* @param {K} mutation - mutation
* @returns mutation
* @description mutation mutation onSuccess
*/
const createMutationHandler = <K extends MutationType<T>>(mutation: K) => {
const mutationFn = api[key as any][mutation]; // 获取对应的 tRPC mutation 函数
return mutationFn.useMutation({
onSuccess: (data, variables, context) => {
utils[key].invalidate(); // 失效指定实体的缓存
options?.[mutation]?.onSuccess?.(data, variables, context); // 调用用户自定义的 onSuccess 回调
},
});
};
// 返回包含多个 mutation 函数的对象
return {
create: createMutationHandler("create") as MutationResult<T, "create">, // 创建实体的 mutation 函数
createCourse: createMutationHandler("createCourse") as MutationResult<
T,
"createCourse"
>, // 创建实体的 mutation 函数
update: createMutationHandler("update") as MutationResult<T, "create">, // 更新实体的 mutation 函数
deleteMany: createMutationHandler("deleteMany") as MutationResult<
T,
"deleteMany"
>, // 批量删除实体的 mutation 函数
softDeleteByIds: createMutationHandler(
"softDeleteByIds"
) as MutationResult<T, "softDeleteByIds">, // 软删除实体的 mutation 函数
restoreByIds: createMutationHandler("restoreByIds") as MutationResult<
T,
"restoreByIds"
>, // 恢复软删除实体的 mutation 函数
updateOrder: createMutationHandler("updateOrder") as MutationResult<
T,
"updateOrder"
>, // 更新实体顺序的 mutation 函数
};
}