feat(user): sync entitlement snapshot

This commit is contained in:
2026-06-29 10:37:37 +08:00
parent 455204e1e4
commit 58cd2a7545
22 changed files with 479 additions and 54 deletions
+39 -11
View File
@@ -14,7 +14,6 @@
import { fromPromise } from "xstate";
import type { UserView } from "@/data/dto/user";
import { userRepository } from "@/data/repositories/user_repository";
import { authRepository } from "@/data/repositories/auth_repository";
import type {
@@ -23,7 +22,15 @@ import type {
} from "@/data/repositories/interfaces";
import { Result } from "@/utils";
import { type InitData, readInitData, toView, userStorage } from "./user-machine.helpers";
import {
applyEntitlementSnapshotToView,
type InitData,
readInitData,
toEntitlementSnapshot,
toView,
type UserFetchData,
userStorage,
} from "./user-machine.helpers";
// ============================================================
// 仓库注入
@@ -46,17 +53,38 @@ export const userInitActor = fromPromise<InitData>(async () => readInitData());
// Fetch actor:调 API 拉当前用户 + 持久化
// ============================================================
/**
* 调 `userRepo.getCurrentUser` 拉当前 user
* - 成功 → 转 UserView + 写本地(userStorage.setUser→ 返回 View
* - 失败 → 返回 nullmachine 走 onDonecontext 保持不变;onError 兜底)
* 调 `userRepo.getCurrentUser + getEntitlements` 拉当前 user 与权益
* - user 成功 → 转 UserView + 写本地(userStorage.setUser
* - entitlements 成功 → 提取 isVip/creditBalance 写本地轻量快照
* - 任一失败都不阻断另一方,machine 层负责保留已有 context
*/
export const userFetchActor = fromPromise<UserView | null>(async () => {
const result = await userRepo.getCurrentUser();
if (Result.isErr(result)) return null;
const view = toView(result.data.toJson());
export const userFetchActor = fromPromise<UserFetchData>(async () => {
const [userResult, entitlementsResult] = await Promise.all([
userRepo.getCurrentUser(),
userRepo.getEntitlements(),
]);
const snapshot = Result.isOk(entitlementsResult)
? toEntitlementSnapshot({
isVip: entitlementsResult.data.isVip,
creditBalance: entitlementsResult.data.creditBalance,
})
: null;
if (snapshot) {
await userStorage.setEntitlementSnapshot(snapshot);
}
if (Result.isErr(userResult)) {
return { user: null, snapshot };
}
const view = applyEntitlementSnapshotToView(
toView(userResult.data.toJson()),
snapshot,
);
// 持久化到本地
await userStorage.setUser(result.data.toJson());
return view;
await userStorage.setUser(userResult.data.toJson());
return { user: view, snapshot };
});
// ============================================================