Template
docs: 新增完整文档体系(setup-project / setup-android / setup-ios / CLAUDE.md)
This commit is contained in:
@@ -0,0 +1,233 @@
|
||||
# Android 配置指南
|
||||
|
||||
本文档覆盖 Android 端从 Flavor 验证到正式签名发布包所需的全部配置步骤。
|
||||
|
||||
---
|
||||
|
||||
## 前提
|
||||
|
||||
- Android Studio Meerkat (2024.3) 或更高版本
|
||||
- Android SDK:API 34(compileSdk)/ API 21(minSdk)
|
||||
- JDK 17(Android Gradle Plugin 要求)
|
||||
- 已完成 [setup-project.md](setup-project.md) 的 Step 1–4
|
||||
|
||||
---
|
||||
|
||||
## 1. 验证 Flavor 构建
|
||||
|
||||
脚手架预配置了三个 Flavor:`dev` / `staging` / `prod`,对应三套应用名和包名后缀。
|
||||
|
||||
```bash
|
||||
# 确认三个 Flavor 都能构建(debug 模式,速度最快)
|
||||
make build-apk-dev # com.example.sunny_mochi.dev
|
||||
|
||||
flutter build apk --flavor staging --debug \
|
||||
--dart-define-from-file=dart-defines/staging.json
|
||||
# com.example.sunny_mochi.staging
|
||||
|
||||
flutter build apk --flavor prod --debug \
|
||||
--dart-define-from-file=dart-defines/prod.json
|
||||
# com.example.sunny_mochi
|
||||
```
|
||||
|
||||
若构建失败,检查 `android/app/build.gradle.kts` 中的 `flavorDimensions` 和 `productFlavors` 配置。
|
||||
|
||||
---
|
||||
|
||||
## 2. 修改包名(业务项目必须)
|
||||
|
||||
编辑 `android/app/build.gradle.kts`,找到 `productFlavors` 和 `defaultConfig`:
|
||||
|
||||
```kotlin
|
||||
defaultConfig {
|
||||
applicationId = "com.your_company.your_app" // ← 修改
|
||||
// ...
|
||||
}
|
||||
|
||||
productFlavors {
|
||||
create("dev") {
|
||||
applicationIdSuffix = ".dev"
|
||||
// applicationId 实际为 com.your_company.your_app.dev
|
||||
resValue("string", "app_name", "YourApp Dev") // ← 修改应用名
|
||||
}
|
||||
create("staging") {
|
||||
applicationIdSuffix = ".staging"
|
||||
resValue("string", "app_name", "YourApp Beta") // ← 修改应用名
|
||||
}
|
||||
create("prod") {
|
||||
resValue("string", "app_name", "YourApp") // ← 修改应用名
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
同步修改 `android/app/src/main/AndroidManifest.xml` 确认使用 `@string/app_name`(脚手架默认已使用)。
|
||||
|
||||
---
|
||||
|
||||
## 3. 配置 Release 签名
|
||||
|
||||
### 3.1 生成 Keystore(首次)
|
||||
|
||||
```bash
|
||||
mkdir -p android/keystore
|
||||
keytool -genkey -v \
|
||||
-keystore android/keystore/release.jks \
|
||||
-alias your-key-alias \
|
||||
-keyalg RSA \
|
||||
-keysize 2048 \
|
||||
-validity 10000
|
||||
```
|
||||
|
||||
> ⚠️ **Keystore 丢失无法找回,必须妥善保管。** 建议:
|
||||
> - 备份到加密云存储(1Password / Bitwarden Vault)
|
||||
> - CI/CD 系统通过 secret 变量注入,不放在仓库中
|
||||
> - `android/keystore/` 目录已在 `.gitignore` 中
|
||||
|
||||
### 3.2 填写 key.properties
|
||||
|
||||
```bash
|
||||
cp android/key.properties.template android/key.properties
|
||||
```
|
||||
|
||||
编辑 `android/key.properties`(相对于 `android/app/` 目录):
|
||||
|
||||
```properties
|
||||
storePassword=your-keystore-password
|
||||
keyPassword=your-key-password
|
||||
keyAlias=your-key-alias
|
||||
storeFile=../keystore/release.jks
|
||||
```
|
||||
|
||||
> `key.properties` 已在 `android/.gitignore` 中,不会被提交。
|
||||
|
||||
### 3.3 验证签名配置
|
||||
|
||||
```bash
|
||||
# 构建 staging release APK(使用 release 签名)
|
||||
make build-staging
|
||||
|
||||
# 查看签名信息
|
||||
apksigner verify --print-certs \
|
||||
build/app/outputs/flutter-apk/app-staging-release.apk
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. 配置 Firebase(可选)
|
||||
|
||||
若业务项目使用 Firebase(推送通知 / Analytics):
|
||||
|
||||
1. 在 [Firebase Console](https://console.firebase.google.com) 为每个 Flavor 创建应用(不同包名)
|
||||
2. 下载各包名对应的 `google-services.json`,放置到对应 Flavor 目录:
|
||||
|
||||
```
|
||||
android/app/src/
|
||||
├── dev/google-services.json
|
||||
├── staging/google-services.json
|
||||
└── main/google-services.json # prod 用 main
|
||||
```
|
||||
|
||||
3. 在 `android/app/build.gradle.kts` 添加 Google Services 插件:
|
||||
|
||||
```kotlin
|
||||
plugins {
|
||||
// ...
|
||||
id("com.google.gms.google-services")
|
||||
}
|
||||
```
|
||||
|
||||
4. 将 `google-services.json` 加入 `.gitignore`(含 API key,勿提交):
|
||||
|
||||
```
|
||||
# 在根 .gitignore 中添加
|
||||
**/google-services.json
|
||||
```
|
||||
|
||||
> `google-services.json` 已在 `android/.gitignore` 中有注释行,取消注释即可。
|
||||
|
||||
---
|
||||
|
||||
## 5. 配置 ProGuard / R8(Release 混淆)
|
||||
|
||||
脚手架的 `android/app/build.gradle.kts` 已预启用 R8:
|
||||
|
||||
```kotlin
|
||||
buildTypes {
|
||||
release {
|
||||
isMinifyEnabled = true
|
||||
proguardFiles(
|
||||
getDefaultProguardFile("proguard-android-optimize.txt"),
|
||||
"proguard-rules.pro"
|
||||
)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
`android/app/proguard-rules.pro` 中已预留 Drift / Sentry / Riverpod 保留规则注释,按需取消注释。
|
||||
|
||||
---
|
||||
|
||||
## 6. SQLCipher 注意事项
|
||||
|
||||
脚手架已在 `build.gradle.kts` 中处理 SQLCipher 的 native library 冲突:
|
||||
|
||||
```kotlin
|
||||
packaging {
|
||||
jniLibs {
|
||||
pickFirsts += setOf("**/libsqlite3.so")
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
若后续新增包时出现 `libsqlite3.so` 重复错误,在此处追加相同模式即可。
|
||||
|
||||
---
|
||||
|
||||
## 7. CI/CD 构建(示例:GitHub Actions)
|
||||
|
||||
以下为生产包构建的 workflow 关键步骤:
|
||||
|
||||
```yaml
|
||||
- name: Decode keystore
|
||||
run: |
|
||||
echo "${{ secrets.KEYSTORE_BASE64 }}" | base64 --decode \
|
||||
> android/keystore/release.jks
|
||||
|
||||
- name: Write key.properties
|
||||
run: |
|
||||
cat > android/key.properties <<EOF
|
||||
storePassword=${{ secrets.KEYSTORE_PASSWORD }}
|
||||
keyPassword=${{ secrets.KEY_PASSWORD }}
|
||||
keyAlias=${{ secrets.KEY_ALIAS }}
|
||||
storeFile=../keystore/release.jks
|
||||
EOF
|
||||
|
||||
- name: Write prod.json
|
||||
run: |
|
||||
echo '${{ secrets.PROD_DART_DEFINES }}' > dart-defines/prod.json
|
||||
|
||||
- name: Build AAB
|
||||
run: make build-prod
|
||||
```
|
||||
|
||||
Secrets 清单:`KEYSTORE_BASE64`、`KEYSTORE_PASSWORD`、`KEY_PASSWORD`、`KEY_ALIAS`、`PROD_DART_DEFINES`
|
||||
|
||||
---
|
||||
|
||||
## 常见问题
|
||||
|
||||
### Gradle sync 失败,报找不到 compileSdk
|
||||
|
||||
确认 Android SDK Platform 34 已安装(Android Studio → SDK Manager → Android 14)。
|
||||
|
||||
### `libsqlite3.so` duplicate 错误
|
||||
|
||||
在 `build.gradle.kts` 的 `packaging.jniLibs.pickFirsts` 中追加冲突的 .so 路径。
|
||||
|
||||
### Release APK 运行时崩溃,Debug APK 正常
|
||||
|
||||
通常是 ProGuard 混淆了不应混淆的类。查看 `build/outputs/mapping/` 下的 `seeds.txt` 和 Logcat,在 `proguard-rules.pro` 添加对应的 `-keep` 规则。
|
||||
|
||||
### 签名 APK 安装时提示"应用已安装但签名不同"
|
||||
|
||||
设备上已安装其他签名版本,需先卸载再安装,或换测试设备。
|
||||
@@ -0,0 +1,243 @@
|
||||
# iOS 配置指南
|
||||
|
||||
本文档覆盖 iOS 端从 CocoaPods 安装到 Archive 发布所需的全部配置步骤。
|
||||
|
||||
> **平台要求**:macOS 系统 + Xcode 16+。Windows / Linux 无法进行 iOS 开发。
|
||||
|
||||
---
|
||||
|
||||
## 前提
|
||||
|
||||
- macOS 14 (Sonoma) 或更高版本
|
||||
- Xcode 16.0(从 App Store 安装,包含 iOS 18 SDK)
|
||||
- CocoaPods 1.15+:`sudo gem install cocoapods`
|
||||
- Apple Developer 账户(真机运行需 Free 账户,发布需 Paid 账户 $99/年)
|
||||
- 已完成 [setup-project.md](setup-project.md) 的 Step 1–4
|
||||
|
||||
---
|
||||
|
||||
## 1. 安装 CocoaPods 依赖
|
||||
|
||||
```bash
|
||||
cd ios
|
||||
pod install
|
||||
cd ..
|
||||
```
|
||||
|
||||
首次执行会拉取依赖,耗时 5–15 分钟(取决于网络)。成功后生成:
|
||||
- `ios/Pods/` 目录(gitignore,不提交)
|
||||
- `ios/Podfile.lock`(版本锁定,**应提交**)
|
||||
|
||||
> 如果 `pod install` 卡住,检查 CocoaPods 源:
|
||||
> ```bash
|
||||
> pod repo update
|
||||
> ```
|
||||
|
||||
---
|
||||
|
||||
## 2. 验证基础构建
|
||||
|
||||
```bash
|
||||
# 无签名编译验证(不需要 Apple 账户)
|
||||
flutter build ios --no-codesign --flavor dev \
|
||||
--dart-define-from-file=dart-defines/dev.json
|
||||
|
||||
# 预期输出:
|
||||
# ✓ Built build/ios/iphoneos/Runner.app
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. 配置 Bundle Identifier
|
||||
|
||||
打开 Xcode(**必须通过 .xcworkspace 打开**):
|
||||
|
||||
```bash
|
||||
open ios/Runner.xcworkspace
|
||||
```
|
||||
|
||||
在 Xcode 中:
|
||||
1. 左侧导航选择 **Runner** 项目
|
||||
2. 选择 **Runner** Target → **General** 选项卡
|
||||
3. **Bundle Identifier** 改为业务项目实际 ID:
|
||||
|
||||
| Build Configuration | Bundle ID |
|
||||
|---------------------|-----------|
|
||||
| Debug(dev 开发调试)| `com.your_company.your_app.dev` |
|
||||
| Debug-staging | `com.your_company.your_app.staging` |
|
||||
| Release(prod 发布)| `com.your_company.your_app` |
|
||||
|
||||
> 脚手架默认使用单个 Bundle ID,Flavor 区分由 xcconfig 控制。若需要三个独立 Bundle ID,在 `ios/Flutter/flavors/` 的 xcconfig 文件中添加 `PRODUCT_BUNDLE_IDENTIFIER` 覆盖。
|
||||
|
||||
---
|
||||
|
||||
## 4. 配置 Xcode Build Configuration 和 Scheme
|
||||
|
||||
脚手架已在 `ios/Flutter/flavors/` 中提供三套 xcconfig:
|
||||
|
||||
| 文件 | 对应 Flavor |
|
||||
|------|-----------|
|
||||
| `dev.xcconfig` | 开发包(Debug-dev)|
|
||||
| `staging.xcconfig` | 测试包(Debug-staging / Release-staging)|
|
||||
| `prod.xcconfig` | 正式包(Release)|
|
||||
|
||||
### 关联 xcconfig 到 Build Configuration
|
||||
|
||||
1. Xcode → **Runner** 项目 → **Info** 选项卡 → **Configurations**
|
||||
2. 展开每个 Configuration,点击 Runner 旁的下拉:
|
||||
|
||||
| Configuration 名称 | 关联 xcconfig |
|
||||
|--------------------|---------------|
|
||||
| Debug | `Flutter/flavors/dev.xcconfig` |
|
||||
| Release | `Flutter/flavors/prod.xcconfig` |
|
||||
| Profile | `Flutter/flavors/prod.xcconfig` |
|
||||
|
||||
> 若需要 staging 独立 Configuration,在此添加 `Debug-staging` / `Release-staging`。
|
||||
|
||||
### 添加 dev / staging Scheme(推荐)
|
||||
|
||||
1. Xcode → **Product** → **Scheme** → **Manage Schemes**
|
||||
2. 复制 `Runner` Scheme,重命名为 `dev`
|
||||
3. 编辑 `dev` Scheme:
|
||||
- **Build Configuration**(Run)→ `Debug`
|
||||
- 在 **Arguments** 中确认无硬编码的 dart-defines(Flutter 通过 `--dart-define-from-file` 注入)
|
||||
|
||||
---
|
||||
|
||||
## 5. 配置代码签名
|
||||
|
||||
### 5.1 自动签名(开发调试,推荐)
|
||||
|
||||
1. Xcode → **Runner** Target → **Signing & Capabilities**
|
||||
2. 勾选 **Automatically manage signing**
|
||||
3. **Team** 选择你的 Apple Developer 账户
|
||||
4. Xcode 会自动创建 Provisioning Profile 和 Signing Certificate
|
||||
|
||||
### 5.2 手动签名(CI/CD 或发布版)
|
||||
|
||||
1. 在 [Apple Developer Portal](https://developer.apple.com/account) 创建:
|
||||
- Distribution Certificate(可签发 App Store / Ad Hoc 包)
|
||||
- App ID(对应 Bundle Identifier)
|
||||
- Provisioning Profile(Distribution 类型)
|
||||
2. 下载 `.mobileprovision` 文件,双击安装到 Xcode
|
||||
3. 取消勾选 **Automatically manage signing**
|
||||
4. 选择对应的 **Signing Certificate** 和 **Provisioning Profile**
|
||||
|
||||
---
|
||||
|
||||
## 6. 真机运行
|
||||
|
||||
```bash
|
||||
# 确认设备已连接
|
||||
flutter devices
|
||||
|
||||
# 运行到真机(dev 包)
|
||||
flutter run --flavor dev \
|
||||
--dart-define-from-file=dart-defines/dev.json \
|
||||
-d <device-id>
|
||||
|
||||
# 或通过 Xcode 直接运行(选择 dev Scheme + 目标设备)
|
||||
```
|
||||
|
||||
首次在设备上运行需要:
|
||||
- 设备 → **设置 → 通用 → VPN 与设备管理** → 信任开发者证书
|
||||
|
||||
---
|
||||
|
||||
## 7. 构建 TestFlight / App Store Archive
|
||||
|
||||
```bash
|
||||
# 1. 确保 prod.json 已配置正确
|
||||
cat dart-defines/prod.json
|
||||
|
||||
# 2. 构建 iOS Release
|
||||
flutter build ios --flavor prod --release \
|
||||
--dart-define-from-file=dart-defines/prod.json
|
||||
|
||||
# 3. 在 Xcode 中 Archive(需要 Distribution Certificate)
|
||||
# Product → Archive → Distribute App → App Store Connect
|
||||
```
|
||||
|
||||
### CI/CD Archive(Fastlane 示例)
|
||||
|
||||
```ruby
|
||||
# Fastfile
|
||||
lane :beta do
|
||||
build_app(
|
||||
workspace: "ios/Runner.xcworkspace",
|
||||
scheme: "Runner", # 或 prod scheme
|
||||
configuration: "Release",
|
||||
export_method: "app-store",
|
||||
export_options: {
|
||||
provisioningProfiles: {
|
||||
"com.your_company.your_app" => "Your App Store Profile"
|
||||
}
|
||||
}
|
||||
)
|
||||
upload_to_testflight
|
||||
end
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 8. 常用 xcconfig 字段说明
|
||||
|
||||
`ios/Flutter/flavors/dev.xcconfig`:
|
||||
|
||||
```xcconfig
|
||||
// 覆盖 Display Name(桌面图标显示的应用名)
|
||||
DISPLAY_NAME=YourApp Dev
|
||||
|
||||
// 覆盖 Bundle ID(若三包使用不同 ID)
|
||||
// PRODUCT_BUNDLE_IDENTIFIER=com.your_company.your_app.dev
|
||||
|
||||
// 覆盖 App Icon(若三包使用不同图标)
|
||||
// ASSETCATALOG_COMPILER_APPICON_NAME=AppIconDev
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 9. 最低 iOS 版本
|
||||
|
||||
`Podfile` 已锁定 iOS 15.0:
|
||||
|
||||
```ruby
|
||||
platform :ios, '15.0'
|
||||
```
|
||||
|
||||
若业务需要支持更低版本,修改此行并运行 `pod install`。同时在 Xcode → Target → **Deployment Info** → **iOS Deployment Target** 同步修改。
|
||||
|
||||
---
|
||||
|
||||
## 常见问题
|
||||
|
||||
### `pod install` 报 `CocoaPods could not find compatible versions`
|
||||
|
||||
```bash
|
||||
pod repo update # 更新本地 CocoaPods 源
|
||||
pod install --repo-update
|
||||
```
|
||||
|
||||
### Xcode 打开 `.xcodeproj` 而非 `.xcworkspace`
|
||||
|
||||
必须打开 `.xcworkspace`,否则 CocoaPods 的依赖不会加载:
|
||||
```bash
|
||||
open ios/Runner.xcworkspace # ✓ 正确
|
||||
# 不要 open ios/Runner.xcodeproj ✗
|
||||
```
|
||||
|
||||
### 真机运行报 `Untrusted Developer`
|
||||
|
||||
设备 → 设置 → 通用 → VPN 与设备管理 → 找到 Developer App → 信任。
|
||||
|
||||
### Archive 失败,报 `Provisioning profile doesn't include the entitlement`
|
||||
|
||||
在 Apple Developer Portal 重新生成 Provisioning Profile(选中全部所需 Entitlements),重新下载安装。
|
||||
|
||||
### Flutter build 报 `The iOS deployment target is set to xxx, but the range of supported deployment targets is`
|
||||
|
||||
更新 `Podfile` 中的 `platform :ios` 版本,运行 `pod install`,并在 Xcode Target → Deployment Info 同步修改。
|
||||
|
||||
### 模拟器运行正常,真机崩溃(SecureStorage 相关)
|
||||
|
||||
iOS 模拟器的 Keychain 行为与真机不同。确认 Xcode → Target → **Signing & Capabilities** → 已添加 **Keychain Sharing** Capability(脚手架默认不需要,但某些系统版本可能要求)。
|
||||
@@ -0,0 +1,234 @@
|
||||
# 项目配置指南(所有开发者必读)
|
||||
|
||||
本文档覆盖从克隆脚手架到可以运行第一个 dev 包所需的全部步骤。
|
||||
Android 和 iOS 的平台专属配置请分别参阅 [setup-android.md](setup-android.md) 和 [setup-ios.md](setup-ios.md)。
|
||||
|
||||
---
|
||||
|
||||
## 前提条件
|
||||
|
||||
| 工具 | 最低版本 | 安装方式 |
|
||||
|------|---------|---------|
|
||||
| Flutter SDK | 3.41.0 | [flutter.dev](https://docs.flutter.dev/get-started/install) |
|
||||
| Dart SDK | 3.7.0 | 随 Flutter 一起安装 |
|
||||
| Android Studio | Meerkat (2024.3) | [developer.android.com](https://developer.android.com/studio) |
|
||||
| Xcode | 16.0 | Mac App Store(仅 iOS 开发需要)|
|
||||
| CocoaPods | 1.15+ | `sudo gem install cocoapods` |
|
||||
| make | 系统内置 | macOS/Linux 自带;Windows 用 Git Bash 或 WSL |
|
||||
|
||||
验证安装:
|
||||
```bash
|
||||
flutter --version # 应显示 ≥ 3.41.0
|
||||
flutter doctor # 确认 Android toolchain + Xcode 全绿
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Step 1 — 克隆与初始化
|
||||
|
||||
```bash
|
||||
git clone https://gitea.example.com/your-org/your-project.git # TODO: 替换实际地址
|
||||
cd your-project
|
||||
|
||||
flutter pub get # 拉取所有依赖
|
||||
make gen # 生成 .g.dart / .freezed.dart(约 1 分钟)
|
||||
make gen-i18n # 生成 lib/i18n/strings.g.dart
|
||||
```
|
||||
|
||||
> **注意**:如果 `make gen` 报错 `build_runner` 找不到,请先确认 `dart` 在 PATH 中:
|
||||
> ```bash
|
||||
> dart --version
|
||||
> ```
|
||||
|
||||
---
|
||||
|
||||
## Step 2 — 填入项目 API 路径
|
||||
|
||||
编辑 `lib/core/config/api_paths.dart`,将所有空字符串替换为实际后端路径:
|
||||
|
||||
```dart
|
||||
// 示例(sa-token + Spring Boot)
|
||||
static const String authLoginSms = '/sys/auth/sms-login';
|
||||
static const String authLoginPwd = '/sys/auth/password-login';
|
||||
static const String authSmsSend = '/sys/auth/send-sms';
|
||||
static const String authLogout = '/sys/auth/logout';
|
||||
static const String authRefresh = '/sys/auth/refresh-token';
|
||||
static const String userProfile = '/sys/sys-user/app/userInfo';
|
||||
// ... 其余路径按业务填写
|
||||
```
|
||||
|
||||
所有 datasource 文件通过 `ApiPaths.xxx` 引用路径,**严禁字符串字面量散落**。
|
||||
|
||||
---
|
||||
|
||||
## Step 3 — 配置环境变量(dart-defines)
|
||||
|
||||
### 3.1 开发环境(dev.json)
|
||||
|
||||
```bash
|
||||
# 直接编辑,此文件可提交(含占位符,无真实密钥)
|
||||
nano dart-defines/dev.json
|
||||
```
|
||||
|
||||
需填入的字段:
|
||||
|
||||
```json
|
||||
{
|
||||
"ENV": "dev",
|
||||
"USE_MOCK": "true", // true = 使用 Mock Adapter(不调真实服务)
|
||||
"INTERNAL_BUILD": "true", // true = 显示 Dev Panel 入口
|
||||
"SENTRY_DSN": "", // dev 通常留空
|
||||
"PINNED_FINGERPRINTS": "", // 证书指纹(dev 可留空跳过 SSL 绑定)
|
||||
"API_BASE_URL": "http://192.168.1.100:8080", // TODO: 实际 dev 服务器
|
||||
"RSA_PUBLIC_KEY": "MIIBIjANBg..." // TODO: 后端 RSA 公钥(Base64 DER)
|
||||
}
|
||||
```
|
||||
|
||||
### 3.2 测试环境(staging.json)
|
||||
|
||||
```json
|
||||
{
|
||||
"ENV": "test",
|
||||
"USE_MOCK": "false",
|
||||
"INTERNAL_BUILD": "true",
|
||||
"SENTRY_DSN": "",
|
||||
"PINNED_FINGERPRINTS": "",
|
||||
"API_BASE_URL": "https://staging.your-domain.com", // TODO
|
||||
"RSA_PUBLIC_KEY": "MIIBIjANBg..." // TODO
|
||||
}
|
||||
```
|
||||
|
||||
### 3.3 生产环境(prod.json)
|
||||
|
||||
```bash
|
||||
cp dart-defines/prod.json.template dart-defines/prod.json
|
||||
nano dart-defines/prod.json
|
||||
```
|
||||
|
||||
```json
|
||||
{
|
||||
"ENV": "prod",
|
||||
"USE_MOCK": "false",
|
||||
"INTERNAL_BUILD": "false",
|
||||
"SENTRY_DSN": "https://xxx@sentry.io/yyy", // TODO: Sentry 项目 DSN
|
||||
"PINNED_FINGERPRINTS": "AA:BB:CC:...", // TODO: 服务器证书 SHA-256 指纹
|
||||
"API_BASE_URL": "https://api.your-domain.com",// TODO
|
||||
"RSA_PUBLIC_KEY": "MIIBIjANBg..." // TODO
|
||||
}
|
||||
```
|
||||
|
||||
> **prod.json 已在 .gitignore 中**,不会被提交。CI/CD 系统通过 secret 变量注入。
|
||||
|
||||
### 获取 RSA 公钥
|
||||
|
||||
后端一般提供 RSA 公钥的 Base64 DER 编码。若后端使用 sa-token + RSA:
|
||||
|
||||
```bash
|
||||
# Java 后端:从 public.key 文件提取(去掉 PEM header/footer,拼接成单行)
|
||||
cat public.key | grep -v "BEGIN\|END" | tr -d '\n'
|
||||
```
|
||||
|
||||
### 获取证书 SHA-256 指纹
|
||||
|
||||
```bash
|
||||
# 方法 1:openssl(推荐)
|
||||
echo | openssl s_client -connect api.your-domain.com:443 2>/dev/null \
|
||||
| openssl x509 -fingerprint -sha256 -noout \
|
||||
| sed 's/SHA256 Fingerprint=//'
|
||||
|
||||
# 方法 2:Chrome → 锁图标 → 证书 → 指纹
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Step 4 — 验证首次运行
|
||||
|
||||
```bash
|
||||
# 方式 1:使用 Mock(推荐首次验证,不需要后端服务)
|
||||
# 确保 dart-defines/dev.json 中 USE_MOCK=true
|
||||
make run-dev
|
||||
|
||||
# 方式 2:连接真实后端
|
||||
# 确保 dart-defines/dev.json 中 USE_MOCK=false + API_BASE_URL 已填入
|
||||
make run-dev
|
||||
```
|
||||
|
||||
**期望结果:**
|
||||
- APP 启动,显示登录页(手机号 + SMS/密码双模式)
|
||||
- 右上角(或侧滑)可进入 Dev Panel(Talker 日志面板)
|
||||
- `flutter analyze` 输出 `103 issues found`(均为 info 级别,0 errors)
|
||||
|
||||
---
|
||||
|
||||
## Step 5 — 更新包名(业务项目必须)
|
||||
|
||||
脚手架默认包名为 `com.example.sunny_mochi`,接手后必须替换:
|
||||
|
||||
### Android
|
||||
编辑 `android/app/build.gradle.kts`:
|
||||
```kotlin
|
||||
// dev Flavor
|
||||
applicationId = "com.your_company.your_app.dev"
|
||||
|
||||
// staging Flavor
|
||||
applicationId = "com.your_company.your_app.staging"
|
||||
|
||||
// prod / release
|
||||
defaultConfig {
|
||||
applicationId = "com.your_company.your_app"
|
||||
}
|
||||
```
|
||||
|
||||
### iOS
|
||||
在 Xcode 中修改 Bundle Identifier(见 [setup-ios.md](setup-ios.md) Step 3)。
|
||||
|
||||
### pubspec.yaml + Dart 导入路径
|
||||
```yaml
|
||||
name: your_app_name # 修改后所有 import 路径也需要更新
|
||||
```
|
||||
|
||||
批量替换导入:
|
||||
```bash
|
||||
# macOS / Linux
|
||||
find lib -name "*.dart" -exec sed -i '' 's/package:sunny_mochi/package:your_app_name/g' {} \;
|
||||
|
||||
# Windows PowerShell
|
||||
Get-ChildItem -Path lib -Recurse -Filter "*.dart" |
|
||||
ForEach-Object { (Get-Content $_.FullName) -replace 'sunny_mochi', 'your_app_name' |
|
||||
Set-Content $_.FullName }
|
||||
```
|
||||
|
||||
运行 `make gen` 重新生成后确认无编译错误。
|
||||
|
||||
---
|
||||
|
||||
## Step 6 — 平台专属配置
|
||||
|
||||
- **Android**(签名 / Flavor 验证 / 发布包构建)→ [setup-android.md](setup-android.md)
|
||||
- **iOS**(Xcode Scheme / CocoaPods / 证书 / Archive)→ [setup-ios.md](setup-ios.md)
|
||||
|
||||
---
|
||||
|
||||
## 常见问题
|
||||
|
||||
### `build_runner` 生成失败,报 analyzer 版本冲突
|
||||
|
||||
确认 `pubspec.yaml` 中的 `dependency_overrides`:
|
||||
```yaml
|
||||
dependency_overrides:
|
||||
drift: 2.31.0
|
||||
json_serializable: 6.13.0
|
||||
```
|
||||
若被修改,恢复后重跑 `flutter pub get && make gen`。
|
||||
|
||||
### App 启动后 token 丢失 / 每次重启都跳登录
|
||||
|
||||
SecureStorage 在 iOS Simulator 上可能行为异常。请在真机测试,或检查 `Keychain Sharing` 是否开启。
|
||||
|
||||
### Mock 模式下请求崩溃 `Unable to load asset`
|
||||
|
||||
检查 `assets/fixtures/` 下是否有对应的 JSON 文件,且 `pubspec.yaml` 中的 `assets:` 包含了对应子目录。
|
||||
|
||||
### `flutter analyze` 报错(非 info 级别)
|
||||
|
||||
先运行 `make gen` 确保生成文件是最新的,再重新 analyze。
|
||||
Reference in New Issue
Block a user