repo_description: Professional Antigravity Account Manager & Switcher. One-click seamless account switching for Antigravity Tools. Built with Tauri v2 + React (Rust).专业的 Antigravity 账号管理与切换工具。为 Antigravity 提供一键无缝账号切换功能。
repo_topics: account-manager antigravity
code: import { create } from 'zustand';
  import { Account } from '../types/account';
  import * as accountService from '../services/accountService';
  
  interface AccountState {
      accounts: Account[];
      currentAccount: Account | null;
      loading: boolean;
      error: string | null;
  
      // Actions
      fetchAccounts: () => Promise<void>;
      fetchCurrentAccount: () => Promise<void>;
      addAccount: (email: string, refreshToken: string) => Promise<void>;
      deleteAccount: (accountId: string) => Promise<void>;
      deleteAccounts: (accountIds: string[]) => Promise<void>;
      switchAccount: (accountId: string) => Promise<void>;
      refreshQuota: (accountId: string) => Promise<void>;
      refreshAllQuotas: () => Promise<accountService.RefreshStats>;
      reorderAccounts: (accountIds: string[]) => Promise<void>;
  
      // 新增 actions
      startOAuthLogin: () => Promise<void>;
      completeOAuthLogin: () => Promise<void>;
      cancelOAuthLogin: () => Promise<void>;
      importV1Accounts: () => Promise<void>;
      importFromDb: () => Promise<void>;
      importFromCustomDb: (path: string) => Promise<void>;
      syncAccountFromDb: () => Promise<void>;
      toggleProxyStatus: (accountId: string, enable: boolean, reason?: string) => Promise<void>;
      warmUpAccounts: () => Promise<string>;
      warmUpAccount: (accountId: string) => Promise<string>;
      updateAccountLabel: (accountId: string, label: string) => Promise<void>;
  }
  
  export const useAccountStore = create<AccountState>((set, get) => ({
      accounts: [],
      currentAccount: null,
      loading: false,
      error: null,
  
      fetchAccounts: async () => {
          set({ loading: true, error: null });
          try {
              console.log('[Store] Fetching accounts...');
              const accounts = await accountService.listAccounts();
              set({ accounts, loading: false });
          } catch (error) {
              console.error('[Store] Fetch accounts failed:', error);
              set({ error: String(error), loading: false });
          }
      },
  
      fetchCurrentAccount: async () => {
          set({ loading: true, error: null });
          try {
              const account = await accountService.getCurrentAccount();
              set({ currentAccount: account, loading: false });
          } catch (error) {
              set({ error: String(error), loading: false });
          }
      },
  
      addAccount: async (email: string, refreshToken: string) => {
          set({ loading: true, error: null });
          try {
              await accountService.addAccount(email, refreshToken);
              await get().fetchAccounts();
              set({ loading: false });
          } catch (error) {
              set({ error: String(error), loading: false });
              throw error;
          }
      },
  
      deleteAccount: async (accountId: string) => {
          set({ loading: true, error: null });
          try {
              await accountService.deleteAccount(accountId);
              await Promise.all([
                  get().fetchAccounts(),
                  get().fetchCurrentAccount()
              ]);
              set({ loading: false });
          } catch (error) {
              set({ error: String(error), loading: false });
              throw error;
          }
      },
  
      deleteAccounts: async (accountIds: string[]) => {
          set({ loading: true, error: null });
          try {
              await accountService.deleteAccounts(accountIds);
              await Promise.all([
                  get().fetchAccounts(),
                  get().fetchCurrentAccount()
              ]);
              set({ loading: false });
          } catch (error) {
              set({ error: String(error), loading: false });
              throw error;
          }
      },
  
      switchAccount: async (accountId: string) => {
          set({ loading: true, error: null });
          try {
              await accountService.switchAccount(accountId);
              await get().fetchCurrentAccount();
              set({ loading: false });
          } catch (error) {
              set({ error: String(error), loading: false });
              throw error;
          }
      },
  
      refreshQuota: async (accountId: string) => {
          set({ loading: true, error: null });
          try {
              await accountService.fetchAccountQuota(accountId);
              await get().fetchAccounts();
              set({ loading: false });
          } catch (error) {
              set({ error: String(error), loading: false });
              throw error;
          }
      },
  
      refreshAllQuotas: async () => {
          set({ loading: true, error: null });
          try {
              const stats = await accountService.refreshAllQuotas();
              await get().fetchAccounts();
              set({ loading: false });
              return stats;
          } catch (error) {
              set({ error: String(error), loading: false });
              throw error;
          }
      },
  
      /**
       * 重新排序账号列表
       * 采用乐观更新策略：先更新本地状态再调用后端持久化，以提供流畅的拖拽体验
       */
      reorderAccounts: async (accountIds: string[]) => {
          const { accounts } = get();
  
          // 创建 ID 到账号的映射
          const accountMap = new Map(accounts.map(acc => [acc.id, acc]));
  
          // 按新顺序重建账号数组
          const reorderedAccounts = accountIds
              .map(id => accountMap.get(id))
              .filter((acc): acc is Account => acc !== undefined);
  
          // 添加未在新顺序中的账号（保持原有顺序）
          const remainingAccounts = accounts.filter(acc => !accountIds.includes(acc.id));
          const finalAccounts = [...reorderedAccounts, ...remainingAccounts];
  
          // 乐观更新本地状态
          set({ accounts: finalAccounts });
  
          try {
              await accountService.reorderAccounts(accountIds);
          } catch (error) {
              // 后端失败时回滚到原始顺序
              console.error('[AccountStore] Reorder accounts failed:', error);
              set({ accounts });
              throw error;
          }
      },
  
      startOAuthLogin: async () => {
          set({ loading: true, error: null });
          try {
              await accountService.startOAuthLogin();
              await get().fetchAccounts();
              set({ loading: false });
          } catch (error) {
              set({ error: String(error), loading: false });
              throw error;
          }
      },
  
      completeOAuthLogin: async () => {
          set({ loading: true, error: null });
          try {
              await accountService.completeOAuthLogin();
              await get().fetchAccounts();
              set({ loading: false });
          } catch (error) {
              set({ error: String(error), loading: false });
              throw error;
          }
      },
  
      cancelOAuthLogin: async () => {
          try {
              await accountService.cancelOAuthLogin();
              set({ loading: false, error: null });
          } catch (error) {
              console.error('[Store] Cancel OAuth failed:', error);
          }
      },
  
      importV1Accounts: async () => {
          set({ loading: true, error: null });
          try {
              await accountService.importV1Accounts();
              await get().fetchAccounts();
              set({ loading: false });
          } catch (error) {
              set({ error: String(error), loading: false });
              throw error;
          }
      },
  
      importFromDb: async () => {
          set({ loading: true, error: null });
          try {
              await accountService.importFromDb();
              await Promise.all([
                  get().fetchAccounts(),
                  get().fetchCurrentAccount()
              ]);
              set({ loading: false });
          } catch (error) {
              set({ error: String(error), loading: false });
              throw error;
          }
      },
  
      importFromCustomDb: async (path: string) => {
          set({ loading: true, error: null });
          try {
              await accountService.importFromCustomDb(path);
              await Promise.all([
                  get().fetchAccounts(),
                  get().fetchCurrentAccount()
              ]);
              set({ loading: false });
          } catch (error) {
              set({ error: String(error), loading: false });
              throw error;
          }
      },
  
      syncAccountFromDb: async () => {
          try {
              const syncedAccount = await accountService.syncAccountFromDb();
              if (syncedAccount) {
                  console.log('[AccountStore] Account synced from DB:', syncedAccount.email);
                  await get().fetchAccounts();
                  set({ currentAccount: syncedAccount });
              }
          } catch (error) {
              console.error('[AccountStore] Sync from DB failed:', error);
          }
      },
  
      toggleProxyStatus: async (accountId: string, enable: boolean, reason?: string) => {
          try {
              await accountService.toggleProxyStatus(accountId, enable, reason);
              await get().fetchAccounts();
          } catch (error) {
              console.error('[AccountStore] Toggle proxy status failed:', error);
              throw error;
          }
      },
  
      warmUpAccounts: async () => {
          set({ loading: true, error: null });
          try {
              const result = await accountService.warmUpAllAccounts();
              set({ loading: false });
              return result;
          } catch (error) {
              set({ error: String(error), loading: false });
              throw error;
          } finally {
              await get().fetchAccounts();
          }
      },
  
      warmUpAccount: async (accountId: string) => {
          set({ loading: true, error: null });
          try {
              const result = await accountService.warmUpAccount(accountId);
              set({ loading: false });
              return result;
          } catch (error) {
              set({ error: String(error), loading: false });
              throw error;
          } finally {
              await get().fetchAccounts();
          }
      },
  
      updateAccountLabel: async (accountId: string, label: string) => {
          try {
              await accountService.updateAccountLabel(accountId, label);
              // 乐观更新本地状态
              const { accounts } = get();
              const updatedAccounts = accounts.map(acc =>
                  acc.id === accountId ? { ...acc, custom_label: label || undefined } : acc
              );
              set({ accounts: updatedAccounts });
          } catch (error) {
              console.error('[AccountStore] Update label failed:', error);
              throw error;
          }
      },
  }));
  