import 'package:flutter/foundation.dart'; /// 全局编译期环境配置。所有值通过 `--dart-define-from-file` 注入,明文 secrets 不入代码。 /// /// 三套环境对应 Flavor: /// - `dev` → dev Flavor,开发调试(可开 Mock) /// - `test` → staging Flavor,连测试服务器 /// - `release` → prod Flavor,正式发布 /// /// 用法: /// ```bash /// # 开发 + Mock(无需后端) /// flutter run --flavor dev --dart-define-from-file=dart-defines/dev.json /// /// # 临时覆盖 API URL(不修改源码) /// flutter run --dart-define=API_BASE_URL=https://my-private.example.com /// ``` /// /// **需要填写的字段**:见 dart-defines/dev.json(所有字段带 TODO 注释) /// **API 路径**:见 lib/core/config/api_paths.dart /// **baseUrl 决策**:见 lib/core/config/api_config.dart abstract class Env { /// 当前环境名:dev / test / release static const String name = String.fromEnvironment( 'ENV', defaultValue: 'dev', ); /// API baseUrl 临时覆盖(CI/CD / 私有环境调试用)。 /// /// 正常情况下留空 — 由 [api_config.dart] 按 [name] 自动选择。 /// 仅当需要临时连私有/临时环境时通过 dart-define 注入: /// `--dart-define=API_BASE_URL=https://my-private.example.com` static const String apiBaseUrlOverride = String.fromEnvironment( 'API_BASE_URL', ); /// Sentry DSN。空字符串时 SentryFlutter.init 自动跳过实际上报。 /// TODO: prod 环境通过 dart-defines/prod.json 填入真实 DSN。 static const String sentryDsn = String.fromEnvironment('SENTRY_DSN'); /// 是否为内部测试包(控制 Talker 调试面板入口是否挂载)。 static const bool isInternalBuild = bool.fromEnvironment('INTERNAL_BUILD'); /// 是否启用 Mock 模式(绕过真实网络,使用 assets/fixtures/ 下的 JSON)。 /// TODO: dev.json 默认 true,上线前确认 staging/prod 为 false。 static const bool useMock = bool.fromEnvironment('USE_MOCK'); /// RSA 公钥(DER-SPKI Base64)— 用于登录密码加密。 /// TODO: 从后端获取公钥后填入 dart-defines/*.json 的 RSA_PUBLIC_KEY 字段。 /// 若后端不需要 RSA 加密,可忽略此字段并移除 auth_repository_impl 中的加密逻辑。 static const String rsaPublicKey = String.fromEnvironment('RSA_PUBLIC_KEY'); /// TLS 证书绑定指纹列表(SHA-256,逗号分隔,支持多指纹轮换)。 /// TODO: 填入 PINNED_FINGERPRINTS 字段;dev 留空时 CertPinning 拦截器自动跳过。 static List get pinnedFingerprints { const raw = String.fromEnvironment('PINNED_FINGERPRINTS'); if (raw.isEmpty) return const []; return raw.split(',').map((s) => s.trim()).where((s) => s.isNotEmpty).toList(); } // ── 便捷判断 ────────────────────────────────────────────────────────────── static bool get isDev => name == 'dev'; static bool get isTest => name == 'test'; static bool get isRelease => name == 'release'; /// Talker / Riverpod observer 等调试工具的门控。 /// Debug 包(flutter run)或 INTERNAL_BUILD=true 时开启。 static bool get enableDevPanel => kDebugMode || isInternalBuild; }