Template
fix: 清除 platform-flutter 残留代码,重构文档与开发者体验
P0 代码修复:删除 imSdkAppId、清除内网 IP 与原项目域名、修正 USE_MOCK 默认值 P1 CLAUDE.md 重组:零容忍规则前置,新增 dart-defines 字段对照表 P2 文档优化:先跑再配的 setup 流程,新增 architecture.md 架构图
This commit is contained in:
+38
-76
@@ -1,109 +1,71 @@
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:sentry_flutter/sentry_flutter.dart' show SentryFlutter;
|
||||
|
||||
/// 全局编译期环境配置。所有值通过 --dart-define 注入,避免明文 secrets。
|
||||
/// 全局编译期环境配置。所有值通过 `--dart-define-from-file` 注入,明文 secrets 不入代码。
|
||||
///
|
||||
/// **环境名与 iOS NetworkConfig.swift 对齐**:dev / test / release
|
||||
/// 三套环境对应 Flavor:
|
||||
/// - `dev` → dev Flavor,开发调试(可开 Mock)
|
||||
/// - `test` → staging Flavor,连测试服务器
|
||||
/// - `release` → prod Flavor,正式发布
|
||||
///
|
||||
/// 用法:
|
||||
/// ```bash
|
||||
/// # 开发环境 + mock(默认)
|
||||
/// flutter run --dart-define=ENV=dev --dart-define=USE_MOCK=true
|
||||
/// # 开发 + Mock(无需后端)
|
||||
/// flutter run --flavor dev --dart-define-from-file=dart-defines/dev.json
|
||||
///
|
||||
/// # 测试环境(连真服 dev.yixiong-tech.com:8081)
|
||||
/// flutter run --dart-define=ENV=test
|
||||
///
|
||||
/// # 正式环境(连 bac.new.hamkke.top)
|
||||
/// flutter build apk --release --dart-define=ENV=release \
|
||||
/// --dart-define=SENTRY_DSN=https://...@sentry/1
|
||||
///
|
||||
/// # CI/CD 临时覆盖 API URL(不修改源码)
|
||||
/// # 临时覆盖 API URL(不修改源码)
|
||||
/// flutter run --dart-define=API_BASE_URL=https://my-private.example.com
|
||||
/// ```
|
||||
///
|
||||
/// 详见:
|
||||
/// - `docs/flutter-architecture-design.md` §九.1 / §十一.5
|
||||
/// - `docs/real-environment-verification.md`(环境就绪后填值)
|
||||
/// - `lib/core/config/api_config.dart`(baseUrl 决策权威)
|
||||
/// **需要填写的字段**:见 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**(与 iOS NetworkConfig 三态对齐)。默认 dev。
|
||||
///
|
||||
/// - dev:开发环境(局域网 192.168.1.201:24801 / mock 模式可用)
|
||||
/// - test:测试环境(dev.yixiong-tech.com:8081 — 与 iOS test 同源)
|
||||
/// - release:正式环境(bac.new.hamkke.top — Release 包应锁定此值)
|
||||
static const String name = String.fromEnvironment('ENV', defaultValue: 'dev');
|
||||
/// 当前环境名:dev / test / release
|
||||
static const String name = String.fromEnvironment(
|
||||
'ENV',
|
||||
defaultValue: 'dev',
|
||||
);
|
||||
|
||||
/// API baseUrl 临时覆盖(CI/CD / 私有环境调试用)。
|
||||
///
|
||||
/// **正常情况下不应使用此变量** — 让 [ApiConfig.baseUrl] 按 [name] 自动选择
|
||||
/// iOS 同源 URL。仅当需要连私有/临时环境时通过 dart-define 注入。
|
||||
///
|
||||
/// ```bash
|
||||
/// flutter run --dart-define=API_BASE_URL=https://my-private.example.com
|
||||
/// ```
|
||||
/// 正常情况下留空 — 由 [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。**Q9 待答前**为空,[SentryFlutter.init] 自动跳过实际上报。
|
||||
static const String sentryDsn = String.fromEnvironment(
|
||||
'SENTRY_DSN',
|
||||
);
|
||||
/// Sentry DSN。空字符串时 SentryFlutter.init 自动跳过实际上报。
|
||||
/// TODO: prod 环境通过 dart-defines/prod.json 填入真实 DSN。
|
||||
static const String sentryDsn = String.fromEnvironment('SENTRY_DSN');
|
||||
|
||||
/// 是否为内部测试包(决定 TalkerScreen 调试面板是否挂载)。
|
||||
/// 详见 docs/real-environment-verification.md §M4 / §Talker 准入。
|
||||
static const bool isInternalBuild = bool.fromEnvironment(
|
||||
'INTERNAL_BUILD',
|
||||
);
|
||||
/// 是否为内部测试包(控制 Talker 调试面板入口是否挂载)。
|
||||
static const bool isInternalBuild = bool.fromEnvironment('INTERNAL_BUILD');
|
||||
|
||||
/// 是否启用 mock fixtures 路径(绕过真实网络请求)。
|
||||
/// 详见 plan §Mock 与真实环境验证分层策略。
|
||||
static const bool useMock = bool.fromEnvironment(
|
||||
'USE_MOCK',
|
||||
);
|
||||
|
||||
/// 腾讯云 IM SDKAppID(数字 ID)。
|
||||
/// **Q3 待答前**为 0(无效值,init 会返回失败但不崩溃)。
|
||||
/// 沙箱测试用控制台测试 SDKAppID;生产用真实业务 SDKAppID。
|
||||
/// 注入:--dart-define=IM_SDK_APP_ID=1400xxxxxx
|
||||
static const int imSdkAppId = int.fromEnvironment(
|
||||
'IM_SDK_APP_ID',
|
||||
);
|
||||
/// 是否启用 Mock 模式(绕过真实网络,使用 assets/fixtures/ 下的 JSON)。
|
||||
/// TODO: dev.json 默认 true,上线前确认 staging/prod 为 false。
|
||||
static const bool useMock = bool.fromEnvironment('USE_MOCK');
|
||||
|
||||
/// RSA 公钥(DER-SPKI Base64)— 用于登录密码加密。
|
||||
/// 默认值 = iOS dev 公钥(对应 platform-ios/.../RSAEncryption.swift 中的 publicKeyString)。
|
||||
/// 生产 / Q6 答复后通过 --dart-define=RSA_PUBLIC_KEY=... 注入真实公钥。
|
||||
static const String rsaPublicKey = String.fromEnvironment(
|
||||
'RSA_PUBLIC_KEY',
|
||||
defaultValue:
|
||||
'MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCmZfR/bA9X3vp86y1aEpvwzXJYKRRF1fLau2+05/ZtaITLpV8bhkmSf3neSy/Q9gAdvG75Fr73E+GWE+K5b0BpvIS1jDGo319+PpZR39SaZTKZ27XFXrosmJTZutN79t819HS1VseleunHAFgMVufE9U5jP6LGzl/wbkSy01GhzwIDAQAB',
|
||||
);
|
||||
/// TODO: 从后端获取公钥后填入 dart-defines/*.json 的 RSA_PUBLIC_KEY 字段。
|
||||
/// 若后端不需要 RSA 加密,可忽略此字段并移除 auth_repository_impl 中的加密逻辑。
|
||||
static const String rsaPublicKey = String.fromEnvironment('RSA_PUBLIC_KEY');
|
||||
|
||||
/// TLS 证书绑定指纹列表(SHA-256,多指纹支持轮换)。
|
||||
/// **Q2 待答前**为空,CertificatePinningInterceptor 在空列表时跳过校验。
|
||||
/// 真实指纹通过 --dart-define=PINNED_FINGERPRINTS=AA:BB,CC:DD 注入。
|
||||
/// TLS 证书绑定指纹列表(SHA-256,逗号分隔,支持多指纹轮换)。
|
||||
/// TODO: 填入 PINNED_FINGERPRINTS 字段;dev 留空时 CertPinning 拦截器自动跳过。
|
||||
static List<String> get pinnedFingerprints {
|
||||
const raw = String.fromEnvironment(
|
||||
'PINNED_FINGERPRINTS',
|
||||
);
|
||||
const raw = String.fromEnvironment('PINNED_FINGERPRINTS');
|
||||
if (raw.isEmpty) return const [];
|
||||
return raw
|
||||
.split(',')
|
||||
.map((s) => s.trim())
|
||||
.where((s) => s.isNotEmpty)
|
||||
.toList();
|
||||
return raw.split(',').map((s) => s.trim()).where((s) => s.isNotEmpty).toList();
|
||||
}
|
||||
|
||||
// ---- 便捷判断(对齐 iOS NetworkConfig.Environment 三态)----
|
||||
// ── 便捷判断 ──────────────────────────────────────────────────────────────
|
||||
|
||||
static bool get isDev => name == 'dev';
|
||||
static bool get isTest => name == 'test';
|
||||
static bool get isRelease => name == 'release';
|
||||
|
||||
/// 兼容旧调用 — 历史代码可能用 isProd 判断
|
||||
/// @Deprecated 新代码请用 [isRelease]
|
||||
static bool get isProd => isRelease;
|
||||
|
||||
/// Release 包除非 INTERNAL_BUILD=true,否则视为生产模式。
|
||||
/// 用于 TalkerScreen / Riverpod observer 等开发面板的门控。
|
||||
/// Talker / Riverpod observer 等调试工具的门控。
|
||||
/// Debug 包(flutter run)或 INTERNAL_BUILD=true 时开启。
|
||||
static bool get enableDevPanel => kDebugMode || isInternalBuild;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user