# maqt-desktop 相2:逻辑层 & 页面 ## 任务 在已搭建好的 maqt-desktop 项目中,创建状态管理、API 服务层、Hooks 和所有页面。 ## 路径 /Users/guchen/.openclaw/workspace/maqt-desktop/ ## 后端 API https://gch3n.online/delta ## 1. 全局配置 **src/services/api.ts** - Axios 实例 ```typescript import axios from 'axios'; const API_BASE = 'https://gch3n.online/delta'; const api = axios.create({ baseURL: API_BASE, timeout: 15000, headers: { 'Content-Type': 'application/json' }, }); // 请求拦截器 - 自动添加 token api.interceptors.request.use((config) => { const token = localStorage.getItem('auth_token'); if (token) config.headers.Authorization = `Bearer ${token}`; return config; }); // 响应拦截器 - 401 自动清除 token api.interceptors.response.use( (res) => res, (err) => { if (err.response?.status === 401) { localStorage.removeItem('auth_token'); localStorage.removeItem('auth_user'); } return Promise.reject(err); } ); export default api; ``` ## 2. Stores (Zustand) **src/stores/authStore.ts** ```typescript // 状态: { token, user, isLoggedIn } // 动作: login, logout, setUser, checkSession (调 /api/session-status) // 持久化: token + user 存 localStorage // hydrate: 启动时从 localStorage 读取 ``` **src/stores/navigationStore.ts** ```typescript // 状态: { currentPage: 'home' | 'optimization' | 'exposure' | ... } // 动作: navigate(page), goBack() // isHome: computed currentPage === 'home' ``` **src/stores/settingsStore.ts** ```typescript // 状态: { autoLaunch, closePreference, theme } // 持久化: localStorage ``` ## 3. API Services 每个文件导出函数,使用 api 实例调用对应端点。 **src/services/auth.api.ts** - login(username, password, installId, deviceHash, platform, osVersion, appVersion) - register(username, password, email) - getSessionStatus() - getVipStatus() - activateVip(cardKey) - getUserStats(userId) - getUserLimits(userId) **src/services/schemes.api.ts** - getSchemes(params: {sort?, page?, limit?, source?, weaponCategory?, weaponName?}) - getSchemeById(id) - getCategory(code) - useScheme(id, source?) - getUserSchemes(userId) - getUserFavoritedCount(userId) **src/services/favorites.api.ts** - getFavorites() - getFavoritesCount() - checkFavorite(schemeId, source) - addFavorite(data) - removeFavorite(id) **src/services/filters.api.ts** - getFilters(params?) - getFilterById(id) - uploadFilter(data) **src/services/popups.api.ts** - getPopups(id) - getSoftwareVersionAd() - getAfterSaleTutorialPopup() - getUpdateConfig() ## 4. Hooks **src/hooks/useAuth.ts** - 封装 authStore,提供便捷的登录/登出方法 **src/hooks/useApi.ts** - 通用请求 hook,loading/error 状态 **src/hooks/useVip.ts** - VIP 状态检查 + 自动刷新 **src/hooks/useElectron.ts** - 类型安全地调用 window.electronAPI **src/hooks/useLocalStorage.ts** - 带类型安全的 localStorage ## 5. 页面 **src/pages/Home.tsx** - 桌面首页 - TopBar (顶部HUD) - DesktopGrid (2x3 桌面图标) - 快速优化 (bolt icon) - 画面滤镜 (palette icon) - 滤镜社区 (photo_filter icon) - 改枪方案 (military_tech icon) - 游戏准星 (center_focus_strong icon) - 神秘力量 (bull icon) - 嘉豪之力 (stealth_ninja icon) - 社区快捷栏 (教程/微信/官网) - 启动按钮: 硬件监控 + 码枪堂2.0 图标点击 → 检查登录/VIP → 导航到对应页面 **src/pages/Login.tsx** - 登录/注册页 - 切换 登录/注册 标签 - 登录表单: username + password - 注册表单: username + password + email - VIP 卡密激活栏 - 登录成功后 → 跳转首页 **src/pages/Settings.tsx** - 设置页 - 开机自启 (toggle) - 关闭偏好 (ask/tray/quit) - 版本号 **其他页面** (骨架,含标题 + 返回按钮): - Optimization.tsx - 快速优化(暂空) - Exposure.tsx - 画面滤镜(暂空) - FilterCommunity.tsx - 滤镜社区(暂空) - WeaponSchemes.tsx - 改枪方案(暂空) - Crosshair.tsx - 游戏准星(暂空) - XixiHaha.tsx - 神秘力量(暂空) - ForbiddenForce.tsx - 嘉豪之力(暂空) - SchemeDetail.tsx - 方案详情(暂空) ## 6. App.tsx 路由配置 ```tsx // 使用 react-router-dom v7 // Routes 配置: // / → Home // /login → Login // /optimization → Optimization // /exposure → Exposure // /filter-community → FilterCommunity // /weapon → WeaponSchemes // /scheme/:id → SchemeDetail // /crosshair → Crosshair // /xixi-haha → XixiHaha // /forbidden-force → ForbiddenForce // /settings → Settings // // 布局: 所有 / 以外的路由共享 BottomDock // 首页 (/) 不显示 BottomDock ``` ## 7. TypeScript 类型定义 **src/types/index.ts**: ```typescript export interface User { id: string; username: string; email: string; avatar: string | null; isVip: boolean; vipExpireAt: string | null; vipLevel: number; } export interface Scheme { id: string; title: string | null; weaponName: string | null; category: string | null; userId: string; description: string | null; viewsCount: number; downloadsCount: number; likesCount: number; favoritesCount: number; price: number; status: string; isOfficial: boolean; createdAt: string; user?: { username: string; avatar: string | null }; } export interface Category { code: string; name: string; icon: string; } ```