feat(web): 积分中心 - 改为全局弹窗并去掉独立钱包页

顶栏、账户菜单、命令面板、画布余额和 /wallet 回跳都打开同一积分中心弹窗,支付结果不再跳进整页超市。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
ddCat
2026-09-17 23:32:19 +08:00
parent bb2a79d365
commit 87d92fcf8b
15 changed files with 183 additions and 772 deletions

View File

@@ -1,13 +1,18 @@
import { useQuery, useQueryClient } from "@tanstack/react-query";
import { useEffect } from "react";
import { getWallet } from "@/services/api/wallet";
import { getWallet, type WalletSummary } from "@/services/api/wallet";
// 余额不是页面心跳数据。工作区内多个位置共享同一个 Query,只在首次进入、显式
// wallet:updated 事件或用户主动刷新时访问服务端,避免常驻布局产生永久轮询。
const WALLET_STALE_TIME_MS = 5 * 60_000;
const walletBalanceQueryKey = (userId: string) => ["wallet-balance", userId] as const;
export type WalletSnapshot = {
availableMicrocredits: number;
policy: WalletSummary["policy"];
};
export function useWalletBalance(userId?: string, enabled = true) {
const activeUserId = enabled ? userId || "" : "";
const queryClient = useQueryClient();
@@ -15,10 +20,10 @@ export function useWalletBalance(userId?: string, enabled = true) {
const query = useQuery({
queryKey,
enabled: Boolean(activeUserId),
queryFn: async () => {
queryFn: async (): Promise<WalletSnapshot> => {
const wallet = await getWallet(1, 1);
if (wallet.account.userId !== activeUserId) throw new Error("积分账户与当前用户不一致");
return wallet.account.availableMicrocredits;
return { availableMicrocredits: wallet.account.availableMicrocredits, policy: wallet.policy };
},
staleTime: WALLET_STALE_TIME_MS,
refetchOnWindowFocus: false,
@@ -38,7 +43,8 @@ export function useWalletBalance(userId?: string, enabled = true) {
}, [query.error]);
return {
availableMicrocredits: query.data ?? null,
availableMicrocredits: query.data?.availableMicrocredits ?? null,
policy: query.data?.policy ?? null,
refreshing: query.isFetching,
refresh: query.refetch,
};