Files
flutter-template/README.md
T
SkyJourney b8b63282ee fix: 清除 platform-flutter 残留代码,重构文档与开发者体验
P0 代码修复:删除 imSdkAppId、清除内网 IP 与原项目域名、修正 USE_MOCK 默认值
P1 CLAUDE.md 重组:零容忍规则前置,新增 dart-defines 字段对照表
P2 文档优化:先跑再配的 setup 流程,新增 architecture.md 架构图
2026-05-14 13:21:06 +08:00

169 lines
7.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# sunny_mochi — Flutter 企业级脚手架
> **新项目接手后,请将本文件第一行替换为实际项目名和简介。**
基于 Flutter 3.x 的企业级 APP 模板底座,涵盖开发 / 测试 / 生产三包共存体系、加密本地数据库、完整网络安全栈、崩溃与错误日志、主题系统和认证骨架,让新项目从第一天就拥有生产级基础设施。
---
## 30 秒可运行验证
```bash
flutter pub get && make gen && make gen-i18n
make run-dev # USE_MOCK=true,无需后端,显示登录页即为成功
```
> 登录:任意手机号 + 验证码 `123456`Mock 自动填入)→ 跳 Home 占位页 ✅
---
## 已实现的基础设施
### 构建体系
- **Flavor 三包**devMock 可开)/ staging(连测试服)/ prod(正式签名)
- **dart-defines JSON**:环境变量与代码完全解耦,CI/CD 通过 secret 注入 prod 配置
- **Android productFlavors + iOS xcconfig**:三套应用名、ID、签名互不干扰
### 网络层(Dio,7 拦截器固定顺序)
| 顺序 | 拦截器 | 作用 |
|------|--------|------|
| 1 | CertPinning | SSL 证书绑定,防 MITM |
| 2 | Auth | 注入 sa-token 动态 headertokenName 从 SecureStorage 读取)|
| 3 | TokenRefresh | 401 时静默刷新,Completer 互斥防并发重复消耗 |
| 4 | Retry | 网络超时 / 5xx 指数退避重试(最多 3 次)|
| 5 | Error | DioException → sealed Failure 映射 |
| 6 | AuthLogout | AuthFailure(unauthorized/refreshFailed) → 清 token + 跳登录 |
| 7 | Log | TalkerDioLogger(仅 dev/Internal 包输出)|
### 本地存储
- **Drift 2.31.0 + SQLCipher**AES-256 加密 SQLite,密钥由 `DbKeyProvider` 派生并存入 Keychain
- **SecureStorage**token / refreshToken / tokenName / userId 的唯一真源(Keychain on iOSEncryptedSharedPreferences on Android
- **Offline-First 同步框架**`SyncService` + `SyncColumns` mixin4 字段脏数据追踪骨架
### 错误体系
```
Failure (sealed)
├── NetworkFailure → 超时 / 无网络 / 证书错误 / 请求取消
├── AuthFailure → 未授权 / token 过期 / 刷新失败 / 无权限 / 加密失败
├── ServerFailure → HTTP 4xx/5xx / 业务码非 00000
├── CacheFailure → Drift / IO 异常
└── UnknownFailure → 兜底
```
### 崩溃日志
三步生命周期:`preInit()` → 启动 → `consumePending()`(读取上次崩溃)→ `installHooks()`(接管 Flutter/Zone 全局异常)。崩溃数据同步写文件(不依赖异步),重启后弹窗展示并提供上报入口。
### 主题系统
5 套色板(blue / red / green / purple / teal)× 浅色/深色模式,通过 `ThemeNotifier`SharedPreferences 持久化)+ Riverpod 全局响应式切换。
### 认证骨架(Clean Architecture
```
domain/entities/UserEntity ← 纯 Dart,无框架依赖
domain/repositories/AuthRepository ← abstract interface
data/models/UserModel ← Freezed + JSON,含 toEntity()
data/datasources/AuthRemoteDatasource ← Dio 调用
data/repositories/AuthRepositoryImpl ← 接口实现
presentation/notifiers/AuthNotifier ← @riverpodgeneration 计数防竞态
presentation/notifiers/AuthStatusController ← ValueNotifier<bool?> 三态门面
presentation/pages/LoginPage ← 手机号 + SMS/密码双模式骨架
```
### 可观测性
- **Talker**:全局 `appTalker`dev/Internal 包输出,Release 编译期关闭
- **Sentry**`SentrySetup.init()` 包裹 `runApp`,空 DSN 时自动跳过,Release 才上报
- **DevPanel Feature**Internal 包内 TalkerScreen 入口,方便调试网络 / 状态变化
### 通用 Widget 库
`AppToast`Overlay 动画条)、`AppButton`(带 loading)、`AppTextField``EmptyView``ErrorView``LoadingOverlay``ConfirmDialog``SectionCard``SectionTitle``Skeleton``InfoRow``CountDownButton``AvatarWidget``TagChip`
---
## 技术栈版本
| 技术 | 版本 | 说明 |
|------|------|------|
| Flutter | ≥ 3.41.0 | |
| Dart | ≥ 3.7.0 | |
| flutter_riverpod | ^3.3.0 | |
| go_router | ^17.0.0 | TypedRoutes + StatefulShellRoute |
| drift | 2.31.0 | **锁定**2.32+ analyzer 冲突 |
| sqlcipher_flutter_libs | ^0.6.0 | |
| freezed_annotation | ^3.0.0 | |
| json_serializable | 6.13.0 | **锁定**6.13.1+ analyzer 冲突 |
| dio | ^5.9.0 | |
| flutter_secure_storage | ^10.0.0 | |
| slang | ^4.0.0 | i18nzh-CN 基准 |
| talker_flutter | ^5.0.0 | |
| sentry_flutter | ^9.0.0 | |
| flutter_screenutil | ^5.9.0 | 设计基准 375×812pt |
| pointycastle + asn1lib | ^4.0.0 / ^1.5.0 | RSA PKCS#1 v1.5 |
---
## 快速开始
**前提**:已安装 Flutter ≥ 3.41.0、Android StudioAndroid SDK)、Xcode 16+iOS 开发)。
```bash
# 1. 克隆(替换为业务项目实际地址)
git clone https://gitea.example.com/your-org/your-project.git
cd your-project
# 2. 安装依赖
flutter pub get
# 3. 代码生成
make gen # 生成 .g.dart / .freezed.dart
make gen-i18n # 生成 lib/i18n/strings.g.dart
# 4. 运行(dev 包,Mock 模式)
make run-dev
```
> 首次运行前请阅读 [docs/setup-project.md](docs/setup-project.md) 完成环境配置。
---
## 项目结构
```
├── android/
│ ├── app/build.gradle.kts # Flavor 三包 + SQLCipher + 签名配置
│ ├── key.properties.template # 签名配置模板(复制为 key.properties 并填入密码)
│ └── keystore/ # 存放 .jks 文件(gitignore,勿提交)
├── ios/
│ ├── Flutter/flavors/ # dev / staging / prod xcconfig
│ └── Podfile # iOS 15.0+pod install 后生成 Pods/
├── dart-defines/
│ ├── dev.json # 开发环境(占位符,可提交)
│ ├── staging.json # 测试环境(占位符,可提交)
│ ├── prod.json.template # 生产模板(复制为 prod.json 并填入真实值)
│ └── prod.json # 生产真实配置(gitignore,勿提交)
├── assets/
│ ├── fonts/ # HarmonyOS Sans SC4 字重)
│ ├── fixtures/ # Mock JSONdev 调试用)
│ └── themes/ # 主题图片(业务项目按 AppColorScheme 放置)
├── lib/ # 详见 CLAUDE.md 目录结构
├── docs/
│ ├── setup-project.md # 完整项目配置指南
│ ├── setup-android.md # Android Flavor / 签名详细配置
│ └── setup-ios.md # iOS Scheme / CocoaPods / 签名详细配置
├── CLAUDE.md # AI 辅助开发上下文(技术栈 / 规范 / 零容忍规则)
├── Makefile # 常用命令
├── pubspec.yaml # 依赖(含版本锁定 dependency_overrides
└── slang.yaml # i18n 配置(base_locale: zh-CN
```
---
## 文档导航
| 文档 | 适用人群 | 内容 |
|------|---------|------|
| **本文(README.md** | 所有成员 | 项目概述、技术栈、快速开始 |
| [docs/setup-project.md](docs/setup-project.md) | 所有开发者 | 先跑起来、dart-defines 字段表、API 路径、包名替换 |
| [docs/setup-android.md](docs/setup-android.md) | Android / 全栈 | Flavor、签名、keystore、构建 |
| [docs/setup-ios.md](docs/setup-ios.md) | iOS / 全栈 | Scheme、CocoaPods、证书、Archive |
| [docs/architecture.md](docs/architecture.md) | 所有开发者 + AI | 数据流 / 认证流 / 错误链 / 拦截器链 ASCII 图 |
| [CLAUDE.md](CLAUDE.md) | AI 辅助开发 | 零容忍规则、禁止改的文件、开发范式、新项目 Checklist |