#!/usr/bin/env bash set -euo pipefail # ============================================================= # Genex Frontend Flutter Build Script # 用法: ./build.sh [platform] # # app: mobile | admin-app # mode: debug | release | clean # platform: apk | appbundle | ios (默认 apk) # # 示例: # ./build.sh mobile debug # 构建消费者App debug APK # ./build.sh mobile release # 构建消费者App release APK # ./build.sh admin-app debug # 构建发行方App debug APK # ./build.sh admin-app release apk # 构建发行方App release APK # ./build.sh admin-app release appbundle # 构建 AAB (Google Play) # ./build.sh mobile clean # 清理构建缓存 # ./build.sh all debug # 同时构建两个App # ============================================================= SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" OUTPUT_DIR="$SCRIPT_DIR/build-output" # 颜色 RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' log() { echo -e "${BLUE}[BUILD]${NC} $*"; } ok() { echo -e "${GREEN}[OK]${NC} $*"; } warn() { echo -e "${YELLOW}[WARN]${NC} $*"; } err() { echo -e "${RED}[ERROR]${NC} $*" >&2; } usage() { echo "" echo "用法: $0 [platform]" echo "" echo " app: mobile | admin-app | all" echo " mode: debug | release | clean | run" echo " platform: apk | appbundle | ios (默认 apk)" echo "" echo "示例:" echo " $0 mobile debug # debug APK" echo " $0 mobile release # release APK" echo " $0 admin-app release # release APK" echo " $0 admin-app release appbundle # release AAB" echo " $0 mobile run # 连接设备运行 debug" echo " $0 mobile clean # 清理缓存" echo " $0 all debug # 构建全部" echo "" exit 1 } check_flutter() { if ! command -v flutter &>/dev/null; then err "Flutter SDK 未安装或不在 PATH 中" exit 1 fi log "Flutter $(flutter --version --machine 2>/dev/null | grep -o '"frameworkVersion":"[^"]*"' | cut -d'"' -f4 || flutter --version | head -1)" } get_app_dir() { local app="$1" case "$app" in mobile) echo "$SCRIPT_DIR/mobile" ;; admin-app) echo "$SCRIPT_DIR/admin-app" ;; *) err "未知 app: $app"; exit 1 ;; esac } get_app_name() { local app="$1" case "$app" in mobile) echo "Genex Consumer (消费者端)" ;; admin-app) echo "Genex Issuer (发行方端)" ;; esac } do_clean() { local app="$1" local app_dir app_dir="$(get_app_dir "$app")" log "清理 $(get_app_name "$app") ..." cd "$app_dir" flutter clean ok "清理完成" } do_build() { local app="$1" local mode="$2" local platform="${3:-apk}" local app_dir app_dir="$(get_app_dir "$app")" local app_name app_name="$(get_app_name "$app")" log "=========================================" log "构建: $app_name" log "模式: $mode | 平台: $platform" log "=========================================" cd "$app_dir" # 获取依赖 log "获取依赖..." flutter pub get # 构建 local build_cmd="" local output_path="" case "$platform" in apk) build_cmd="flutter build apk --$mode" if [ "$mode" = "release" ]; then output_path="$app_dir/build/app/outputs/flutter-apk/app-release.apk" else output_path="$app_dir/build/app/outputs/flutter-apk/app-debug.apk" fi ;; appbundle) build_cmd="flutter build appbundle --$mode" output_path="$app_dir/build/app/outputs/bundle/${mode}/app-${mode}.aab" ;; ios) if [ "$mode" = "debug" ]; then build_cmd="flutter build ios --debug --no-codesign" else build_cmd="flutter build ios --release" fi ;; *) err "未知平台: $platform" exit 1 ;; esac log "执行: $build_cmd" $build_cmd # 复制产物到统一输出目录 if [ -n "$output_path" ] && [ -f "$output_path" ]; then mkdir -p "$OUTPUT_DIR" local filename if [ "$platform" = "apk" ]; then filename="${app}-${mode}.apk" else filename="${app}-${mode}.aab" fi cp "$output_path" "$OUTPUT_DIR/$filename" ok "构建成功!" ok "产物: $OUTPUT_DIR/$filename" ok "大小: $(du -h "$OUTPUT_DIR/$filename" | cut -f1)" else ok "构建成功!" [ "$platform" = "ios" ] && ok "iOS 产物在: $app_dir/build/ios/" fi echo "" } do_run() { local app="$1" local app_dir app_dir="$(get_app_dir "$app")" log "运行 $(get_app_name "$app") (debug模式)..." cd "$app_dir" flutter pub get flutter run } # ============================================================= # 主逻辑 # ============================================================= [ $# -lt 2 ] && usage APP="$1" MODE="$2" PLATFORM="${3:-apk}" check_flutter case "$MODE" in clean) if [ "$APP" = "all" ]; then do_clean mobile do_clean admin-app else do_clean "$APP" fi ;; run) if [ "$APP" = "all" ]; then err "不能同时运行两个 App,请指定一个" exit 1 fi do_run "$APP" ;; debug|release) if [ "$APP" = "all" ]; then do_build mobile "$MODE" "$PLATFORM" do_build admin-app "$MODE" "$PLATFORM" echo "" ok "=========================================" ok "全部构建完成! 产物目录: $OUTPUT_DIR/" ok "=========================================" ls -lh "$OUTPUT_DIR/" 2>/dev/null || true else do_build "$APP" "$MODE" "$PLATFORM" fi ;; *) err "未知模式: $MODE" usage ;; esac