2024-12-30 08:26:40 +08:00
|
|
|
import { api } from "../trpc";
|
2025-02-06 16:32:52 +08:00
|
|
|
import { PostParams } from "../../singleton/DataHolder";
|
2024-12-30 08:26:40 +08:00
|
|
|
|
|
|
|
export function useVisitor() {
|
|
|
|
const utils = api.useUtils();
|
2025-02-06 16:32:52 +08:00
|
|
|
const postParams = PostParams.getInstance();
|
2024-12-30 08:26:40 +08:00
|
|
|
|
|
|
|
const create = api.visitor.create.useMutation({
|
|
|
|
onSuccess() {
|
|
|
|
utils.visitor.invalidate();
|
2025-02-06 16:32:52 +08:00
|
|
|
|
|
|
|
// utils.post.invalidate();
|
2024-12-30 08:26:40 +08:00
|
|
|
},
|
|
|
|
});
|
|
|
|
/**
|
|
|
|
* 通用的乐观更新mutation工厂函数
|
|
|
|
* @param updateFn 更新数据的具体逻辑函数
|
|
|
|
* @returns 封装后的mutation配置对象
|
|
|
|
*/
|
|
|
|
const createOptimisticMutation = (
|
|
|
|
updateFn: (item: any, variables: any) => any
|
|
|
|
) => ({
|
2025-02-06 16:32:52 +08:00
|
|
|
//在请求发送前执行本地数据预更新
|
|
|
|
onMutate: async (variables: any) => {
|
|
|
|
const previousDataList: any[] = [];
|
|
|
|
const previousDetailDataList: any[] = [];
|
|
|
|
|
|
|
|
// 处理列表数据
|
|
|
|
const paramsList = postParams.getItems();
|
|
|
|
for (const params of paramsList) {
|
|
|
|
await utils.post.findManyWithCursor.cancel();
|
|
|
|
const previousData =
|
|
|
|
utils.post.findManyWithCursor.getInfiniteData({
|
|
|
|
...params,
|
|
|
|
});
|
|
|
|
previousDataList.push(previousData);
|
|
|
|
utils.post.findManyWithCursor.setInfiniteData(
|
|
|
|
{
|
|
|
|
...params,
|
|
|
|
},
|
|
|
|
(oldData) => {
|
|
|
|
if (!oldData) return oldData;
|
|
|
|
return {
|
|
|
|
...oldData,
|
|
|
|
pages: oldData.pages.map((page) => ({
|
|
|
|
...page,
|
|
|
|
items: (page.items as any).map((item) =>
|
|
|
|
item.id === variables?.postId
|
|
|
|
? updateFn(item, variables)
|
|
|
|
: item
|
|
|
|
),
|
|
|
|
})),
|
|
|
|
};
|
|
|
|
}
|
|
|
|
);
|
|
|
|
}
|
2024-12-30 08:26:40 +08:00
|
|
|
|
2025-02-06 16:32:52 +08:00
|
|
|
// 处理详情数据
|
|
|
|
const detailParamsList = postParams.getDetailItems();
|
|
|
|
for (const params of detailParamsList) {
|
|
|
|
await utils.post.findFirst.cancel();
|
|
|
|
const previousDetailData = utils.post.findFirst.getData(params);
|
|
|
|
previousDetailDataList.push(previousDetailData);
|
|
|
|
utils.post.findFirst.setData(params, (oldData) => {
|
|
|
|
if (!oldData) return oldData;
|
|
|
|
return oldData.id === variables?.postId
|
|
|
|
? updateFn(oldData, variables)
|
|
|
|
: oldData;
|
|
|
|
});
|
|
|
|
}
|
2024-12-30 08:26:40 +08:00
|
|
|
|
2025-02-06 16:32:52 +08:00
|
|
|
return { previousDataList, previousDetailDataList };
|
|
|
|
},
|
|
|
|
// 错误处理:数据回滚
|
|
|
|
onError: (_err: any, _variables: any, context: any) => {
|
|
|
|
const paramsList = postParams.getItems();
|
|
|
|
paramsList.forEach((params, index) => {
|
|
|
|
if (context?.previousDataList?.[index]) {
|
|
|
|
utils.post.findManyWithCursor.setInfiniteData(
|
|
|
|
{ ...params },
|
|
|
|
context.previousDataList[index]
|
|
|
|
);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
},
|
|
|
|
// 成功后的缓存失效
|
|
|
|
onSuccess: async (_: any, variables: any) => {
|
|
|
|
await Promise.all([
|
|
|
|
utils.visitor.invalidate(),
|
|
|
|
utils.post.findFirst.invalidate({
|
|
|
|
where: {
|
|
|
|
id: (variables as any)?.postId,
|
|
|
|
},
|
|
|
|
}),
|
|
|
|
utils.post.findManyWithCursor.invalidate(),
|
|
|
|
]);
|
|
|
|
},
|
2024-12-30 08:26:40 +08:00
|
|
|
});
|
|
|
|
// 定义具体的mutation
|
|
|
|
const read = api.visitor.create.useMutation(
|
|
|
|
createOptimisticMutation((item) => ({
|
|
|
|
...item,
|
|
|
|
views: (item.views || 0) + 1,
|
|
|
|
readed: true,
|
|
|
|
}))
|
|
|
|
);
|
2025-02-06 16:32:52 +08:00
|
|
|
const like = api.visitor.create.useMutation(
|
|
|
|
createOptimisticMutation((item) => ({
|
|
|
|
...item,
|
|
|
|
likes: (item.likes || 0) + 1,
|
|
|
|
liked: true,
|
|
|
|
}))
|
|
|
|
);
|
|
|
|
const unLike = api.visitor.deleteMany.useMutation(
|
|
|
|
createOptimisticMutation((item) => ({
|
|
|
|
...item,
|
|
|
|
likes: item.likes - 1 || 0,
|
|
|
|
liked: false,
|
|
|
|
}))
|
|
|
|
);
|
|
|
|
|
|
|
|
const hate = api.visitor.create.useMutation(
|
|
|
|
createOptimisticMutation((item) => ({
|
|
|
|
...item,
|
|
|
|
hates: (item.hates || 0) + 1,
|
|
|
|
hated: true,
|
|
|
|
}))
|
|
|
|
);
|
|
|
|
const unHate = api.visitor.deleteMany.useMutation(
|
|
|
|
createOptimisticMutation((item) => ({
|
|
|
|
...item,
|
|
|
|
hates: item.hates - 1 || 0,
|
|
|
|
hated: false,
|
|
|
|
}))
|
|
|
|
);
|
2024-12-30 08:26:40 +08:00
|
|
|
|
|
|
|
const addStar = api.visitor.create.useMutation(
|
|
|
|
createOptimisticMutation((item) => ({
|
|
|
|
...item,
|
|
|
|
star: true,
|
|
|
|
}))
|
|
|
|
);
|
|
|
|
|
|
|
|
const deleteStar = api.visitor.deleteMany.useMutation(
|
|
|
|
createOptimisticMutation((item) => ({
|
|
|
|
...item,
|
|
|
|
star: false,
|
|
|
|
}))
|
|
|
|
);
|
|
|
|
|
|
|
|
const deleteMany = api.visitor.deleteMany.useMutation({
|
|
|
|
onSuccess() {
|
|
|
|
utils.visitor.invalidate();
|
|
|
|
},
|
|
|
|
});
|
|
|
|
|
|
|
|
const createMany = api.visitor.createMany.useMutation({
|
|
|
|
onSuccess() {
|
|
|
|
utils.visitor.invalidate();
|
|
|
|
utils.message.invalidate();
|
|
|
|
utils.post.invalidate();
|
|
|
|
},
|
|
|
|
});
|
|
|
|
|
|
|
|
return {
|
2025-02-06 16:32:52 +08:00
|
|
|
postParams,
|
2024-12-30 08:26:40 +08:00
|
|
|
create,
|
|
|
|
createMany,
|
|
|
|
deleteMany,
|
|
|
|
read,
|
|
|
|
addStar,
|
|
|
|
deleteStar,
|
2025-02-06 16:32:52 +08:00
|
|
|
like,
|
|
|
|
unLike,
|
|
|
|
hate,
|
|
|
|
unHate,
|
2024-12-30 08:26:40 +08:00
|
|
|
};
|
|
|
|
}
|