chore: 初始化脚手架 — sunny_mochi 企业级 Flutter 模板

Core 基础设施:Flavor 三包体系、Drift+SQLCipher 加密数据库
7 拦截器 Dio 网络栈、CrashReporter 崩溃日志、Sealed Failure 错误体系
5 色板主题系统、Auth 认证骨架(Clean Architecture)、Dev Panel、Mock Adapter

通过验证:flutter analyze(0 errors)、flutter test(全绿)、staging APK 74.8MB
This commit is contained in:
SkyJourney
2026-05-14 12:51:05 +08:00
commit 61017f1c39
204 changed files with 15386 additions and 0 deletions
+116
View File
@@ -0,0 +1,116 @@
import java.util.Properties
plugins {
id("com.android.application")
id("kotlin-android")
// The Flutter Gradle Plugin must be applied after the Android and Kotlin Gradle plugins.
id("dev.flutter.flutter-gradle-plugin")
}
// 签名配置(android/key.properties 存在时启用;本地开发可不创建,CI/CD 必须提供)
val keystorePropertiesFile = rootProject.file("key.properties")
val keystoreProperties = Properties().also { props ->
if (keystorePropertiesFile.exists()) {
props.load(keystorePropertiesFile.inputStream())
}
}
android {
namespace = "com.example.sunny_mochi"
// v1.2 锁定(详见 docs/flutter-architecture-design.md §十一.6):
// compileSdk = 36(编译期 API;插件生态已要求 36+)
// minSdk = 24Android 7OMA 安全推荐 + 主流国内 App 基线)
// targetSdk = 35Google Play 2026 强制要求;运行时声明目标)
compileSdk = 36
ndkVersion = flutter.ndkVersion
compileOptions {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}
kotlinOptions {
jvmTarget = JavaVersion.VERSION_17.toString()
}
defaultConfig {
applicationId = "com.example.sunny_mochi"
minSdk = 24
targetSdk = 35
versionCode = flutter.versionCode
versionName = flutter.versionName
}
// ── Flavor 三包共存(dev / staging / prod)────────────────────────────
// 注意:Android Kotlin DSL 中 "test" 是保留字,测试环境 flavor 命名为 staging
flavorDimensions += "environment"
productFlavors {
create("dev") {
dimension = "environment"
applicationIdSuffix = ".dev"
versionNameSuffix = "-dev"
resValue("string", "app_name", "MyApp(开发版)")
}
create("staging") {
dimension = "environment"
applicationIdSuffix = ".staging"
versionNameSuffix = "-staging"
resValue("string", "app_name", "MyApp(测试版)")
}
create("prod") {
dimension = "environment"
// 正式包无后缀,applicationId 与 namespace 保持一致
resValue("string", "app_name", "MyApp")
}
}
// ──────────────────────────────────────────────────────────────────────
signingConfigs {
// release signingConfigkey.properties 存在时填充;否则 buildTypes.release 回退 debug
create("release") {
if (keystorePropertiesFile.exists()) {
keyAlias = keystoreProperties.getProperty("keyAlias")
keyPassword = keystoreProperties.getProperty("keyPassword")
storeFile = file(keystoreProperties.getProperty("storeFile"))
storePassword = keystoreProperties.getProperty("storePassword")
}
}
}
buildTypes {
debug {
isMinifyEnabled = false
isDebuggable = true
}
release {
// dev / staging release 包:shrink 资源但不混淆(方便调试)
// prod release 包:全开 R8 混淆(配合 proguard-rules.pro
isMinifyEnabled = true
isShrinkResources = true
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
// key.properties 存在时用 release 签名,否则回退 debug 签名(本地开发)
signingConfig = if (keystorePropertiesFile.exists()) {
signingConfigs.getByName("release")
} else {
signingConfigs.getByName("debug")
}
}
}
// sqlcipher_flutter_libs 提供加密版 libsqlite3.so
// tencent_cloud_chat_sdk 也打包了原版同名 .so,AGP 会报冲突并随机丢弃其中一份。
// pickFirsts 保证遇到重名时优先保留(sqlcipher 插件在 classpath 中排前面)。
packaging {
jniLibs {
pickFirsts += setOf("**/libsqlite3.so")
}
}
}
flutter {
source = "../.."
}