# 见势 · Veyra App React Native + Expo + TypeScript,白底、石墨黑与柔紫。源码路由采用 Expo Router,服务端查询使用 TanStack Query,当前账户使用 Zustand。 当前已接通开发登录、安全会话、账户、候选证据、计划预算、成交及冲正、持仓、站内通知和复盘。偏好、正式认证与远程推送仍待开发。未完成 iPhone 真机验证,尚未生成可安装 IPA。 ## 开发运行 在仓库根目录执行 `npm --prefix apps/mobile ci`,使用 Node 22.18 或更高版本(测试使用 Node 的 TypeScript 支持)。Go 后端初始化完成后运行 `go run . -command user-create -role USER` 创建 App 的 USER 测试身份,再运行 `go run .`。管理员身份无法登录 App,登录信息从本地环境配置获取,不打包到客户端。 ```sh cp apps/mobile/.env.example apps/mobile/.env npm --prefix apps/mobile run start ``` 填写 `apps/mobile/.env` 中 `EXPO_PUBLIC_API_URL`: - iOS 模拟器:`http://127.0.0.1:8080`。 - Android 默认模拟器:`http://10.0.2.2:8080`。 - 真机:开发电脑的内网 IP,例如 `http://<开发电脑内网IP>:8080`,后端 `HTTP_ADDR` 需绑定可访问的监听地址;与数据库地址无关。 Expo 的 `i` / `a` 可打开已经安装的 iOS / Android 模拟器,也可用兼容 SDK 的 Expo Go 扫码运行。地址变化后重启 Metro。接口地址留空时会明确提示未配置。正式环境应配置 HTTPS;当前开发密码接口只在 local/test 后端开放。 `EXPO_PUBLIC_*` 会进入客户端包,只允许公开 API 地址,禁止放入数据库、Redis、模型或行情源密钥。供应商由管理员在后台配置,App 不直接调用供应商。 ## 验证与产物 ```sh npm --prefix apps/mobile run typecheck && npm --prefix apps/mobile run test npm --prefix apps/mobile run build ``` 类型检查与测试命令 检查 TypeScript 与 API/金额边界测试;构建命令 导出 iOS 和 Android Metro/Hermes bundle 到本目录 `dist`,验证路由和原生依赖可打包。导出包不等于 APK、IPA,也不代表已完成真机或商店验证;后续原生包需通过开发构建或 EAS/本地编译生成。 依赖已按 Expo SDK 57 配套更新:expo 57.0.27、React Native 0.86.3、React 19.2.3。管理端依赖独立维护。类型检查、12 项测试、双平台 Hermes 导出、Expo Doctor 21/21 已通过;真机运行仍等待实际扫码验证。 会话使用 [Expo SecureStore](https://docs.expo.dev/versions/v55.0.0/sdk/securestore/),不会写进 Zustand、URL 或日志。退出撤销服务端会话;网络中断保留原始会话供恢复,401 或到期清理身份与查询缓存。旧会话的迟到响应不会污染新登录用户。切换账户会中断旧查询、清理账户详情缓存;金额使用十进制字符串与整数校验,不做浮点账本计算。 ## iPhone 当前测试:Expo Go 手机 Expo Go 57.0.9 支持 SDK 57,项目已匹配。不需要本机 Xcode,也不生成独立 IPA。Mac 与手机连接同一 Wi-Fi,启动 Metro 后用 iPhone 相机扫码,允许 Expo Go 本地网络访问。 ```sh REACT_NATIVE_PACKAGER_HOSTNAME="$(ipconfig getifaddr en0)" npm --prefix apps/mobile run start -- --go --lan --port 8081 ``` Expo Go 与电脑 CLI 必须登录同一个 Expo 账号。在 App 目录执行 `npx expo login --browser`,完成后重启 Metro;登录令牌由 CLI 本机保存,不加入 Git。 当前入口 `exp://192.168.100.2:8081`,二维码 `/tmp/veyra-expo57-qr.png`。电脑换网后重新获取 IP;使用 VPN 时显式指定真实局域网地址。App API 连接公开域名,但 Expo Go 仍需要本机 Metro 在线,不能当作独立安装包或域名直接下载。 ## 后续独立安装(普通 Apple ID) 当前公开 API 为 `https://veyra.sundynix.cn`,已写入环境模板和本机私有配置;地址通过配置读取,不写死到请求代码。App 使用 USER 身份,管理员不能登录。 普通 Apple ID 可以通过 Xcode Personal Team 在自己的 iPhone 上运行 App,不需要上架。免费设备签名有效期为 7 天,到期需要重新安装。参见 [Apple 开发者账号说明](https://developer.apple.com/help/account/basics/about-your-developer-account)。 1. Mac 从 App Store 安装完整 Xcode,打开并完成首次初始化,在 Xcode Settings → Accounts 登录自己的 Apple ID。 2. 数据线连接 iPhone,信任电脑,按系统提示开启 Developer Mode。 3. 在仓库根目录执行 `npm --prefix apps/mobile run ios:device`,选择手机和个人开发团队。使用 Release 配置,安装完成后无需电脑 Metro 持续运行;后端通过 HTTPS 域名连接。 4. 若自动签名需要在 Xcode 中确认,在生成的 `apps/mobile/ios` 工程中选择目标,Signing & Capabilities 选择 Personal Team 并开启自动签名,再选择手机运行。 个人签名和生成的原生工程不提交。当前本机为 Intel / macOS 14.8.2,只有 Command Line Tools;完整 Xcode 还须符合 SDK 57 的系统要求。此路线尚未验证,当前先采用上述 Expo Go 测试。 Gitea Release 可以托管安装包,但下载 IPA 本身不会绕过 iOS 签名。tag 自动上传可安装 iOS 包仍需要 macOS/Xcode 构建环境与有效签名;现有 Linux 后端 CI 只检查 Hermes 导出,并未生成 IPA。当前采用 Expo Go 测试;tag 自动上传独立安装包尚未接入,不把 Hermes bundle 冒充 IPA。 ## iPhone 安装包 Expo 云构建项目为 `@blizzard-zhang/veyra`。`ios-unsigned` 使用云端 Xcode 编译设备版本并嵌入 JS,生成 `Veyra-unsigned.ipa`,无需本机 Xcode或云端 Apple 签名凭据。该 IPA 未签名,不能直接从网页安装;普通 Apple ID 需要在个人签名工具中重签后安装,安装期限由 Apple 个人签名规则决定。`preview` 为有签名凭据时的内部安装构建,不上架。 ```sh npx eas-cli@24.12.1 build --platform ios --profile ios-unsigned ``` 构建脚本必须在云端 macOS/Xcode 执行。Hermes 导出和模拟器 `.app` 均不是设备 IPA。不要将 `.env`、签名证书或后端配置上传到构建服务;首次实际云构建使用独立 App 源码目录上传。