Commit 9db068bb authored by 张宏's avatar 张宏

1

parent 14c26670
...@@ -9,26 +9,19 @@ ...@@ -9,26 +9,19 @@
dart run build_runner build dart run build_runner build
dart run build_runner watch dart run build_runner watch
## 打包
### ✅ dev
flutter build apk --dart-define=APP_ENV=dev --flavor dev
### ✅ staging(不要写 test)
flutter build apk --dart-define=APP_ENV=staging --flavor staging
### ✅ prod
flutter build apk --dart-define=APP_ENV=prod --flavor prod
--- ---
### gitlab
git config --global user.name "xxx"
git config --global user.email "xxx"
Create a new repository
git clone http://git.ruanyiit.com/zhanghong/smart_hotel_app.git
cd smart_hotel_app
touch README.md
git add README.md
git commit -m "add README"
git push -u origin master
Existing folder
cd existing_folder
git init
git remote add origin http://git.ruanyiit.com/zhanghong/smart_hotel_app.git
git add .
git commit -m "Initial commit"
git push -u origin master
### 版本处理 ### 版本处理
版本对齐后,必须清除旧缓存,否则 Gradle 会继续读取损坏的元数据 版本对齐后,必须清除旧缓存,否则 Gradle 会继续读取损坏的元数据
......
...@@ -51,6 +51,29 @@ android { ...@@ -51,6 +51,29 @@ android {
versionName flutterVersionName versionName flutterVersionName
} }
flavorDimensions "environment"
productFlavors {
dev {
dimension "environment"
applicationIdSuffix ".dev"
versionNameSuffix "-dev"
resValue "string", "app_name", "智能酒店-dev"
}
staging {
dimension "environment"
applicationIdSuffix ".staging"
versionNameSuffix "-staging"
resValue "string", "app_name", "智能酒店-staging"
}
prod {
dimension "environment"
applicationIdSuffix ""
versionNameSuffix ""
resValue "string", "app_name", "智能酒店"
}
}
buildTypes { buildTypes {
release { release {
// TODO: Add your own signing config for the release build. // TODO: Add your own signing config for the release build.
...@@ -58,6 +81,17 @@ android { ...@@ -58,6 +81,17 @@ android {
signingConfig signingConfigs.debug signingConfig signingConfigs.debug
} }
} }
// 自定义 APK 输出文件名
applicationVariants.all { variant ->
variant.outputs.all {
if (variant.flavorName == "dev" || variant.flavorName == "staging") {
outputFileName = "app-${variant.flavorName}.apk"
} else {
outputFileName = "app-${variant.flavorName}-${variant.buildType.name}.apk"
}
}
}
} }
flutter { flutter {
......
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 {
namespace = "com.example.smart_hotel_app"
compileSdk = flutter.compileSdkVersion
ndkVersion = flutter.ndkVersion
compileOptions {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}
kotlinOptions {
jvmTarget = JavaVersion.VERSION_17.toString()
}
defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId = "com.example.smart_hotel_app"
// You can update the following values to match your application needs.
// For more information, see: https://flutter.dev/to/review-gradle-config.
minSdk = flutter.minSdkVersion
targetSdk = flutter.targetSdkVersion
versionCode = flutter.versionCode
versionName = flutter.versionName
}
buildTypes {
release {
// TODO: Add your own signing config for the release build.
// Signing with the debug keys for now, so `flutter run --release` works.
signingConfig = signingConfigs.getByName("debug")
}
}
}
flutter {
source = "../.."
}
<manifest xmlns:android="http://schemas.android.com/apk/res/android"> <manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application <application
android:label="智能酒店" android:label="@string/app_name"
android:name="${applicationName}" android:name="${applicationName}"
android:icon="@mipmap/ic_launcher"> android:icon="@mipmap/ic_launcher">
<activity <activity
......
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">智能酒店</string>
</resources>
allprojects {
repositories {
google()
mavenCentral()
}
}
val newBuildDir: Directory =
rootProject.layout.buildDirectory
.dir("../../build")
.get()
rootProject.layout.buildDirectory.value(newBuildDir)
subprojects {
val newSubprojectBuildDir: Directory = newBuildDir.dir(project.name)
project.layout.buildDirectory.value(newSubprojectBuildDir)
}
subprojects {
project.evaluationDependsOn(":app")
}
tasks.register<Delete>("clean") {
delete(rootProject.layout.buildDirectory)
}
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -41,6 +41,9 @@ class AuthBloc extends Bloc<AuthEvent, AuthState> { ...@@ -41,6 +41,9 @@ class AuthBloc extends Bloc<AuthEvent, AuthState> {
AuthTokenExpiredEvent event, AuthTokenExpiredEvent event,
Emitter<AuthState> emit, Emitter<AuthState> emit,
) async { ) async {
// 防止重复处理:如果已经在过期或登出状态,直接跳过
if (state is AuthTokenExpired || state is AuthLoggedOut) return;
await _storageService.deleteToken(); await _storageService.deleteToken();
await _storageService.deleteUserInfo(); await _storageService.deleteUserInfo();
await _storageService.deleteClientId(); await _storageService.deleteClientId();
......
class Constants { class Constants {
// ==================== 环境配置 ==================== // ==================== 环境配置 ====================
static const String baseUrl = 'http://121.41.57.178:9090'; /// 当前环境:dev / staging / prod,通过 --dart-define=APP_ENV=xxx 注入
// static const String baseUrl = 'http://192.168.0.168:9090'; static const String env = String.fromEnvironment('APP_ENV', defaultValue: 'dev');
// static const String baseUrl = 'http://192.168.1.7:9090';
/// 根据环境返回对应的 API 地址
static String get baseUrl {
switch (env) {
case 'dev':
return 'http://121.41.57.178:9090';
case 'staging':
return 'http://121.41.57.178:9090';
case 'prod':
return 'http://121.41.57.178:9090';
default:
return 'http://121.41.57.178:9090';
}
}
......
import 'package:dio/dio.dart'; import 'package:dio/dio.dart';
import '../constants.dart'; import '../constants.dart';
import '../event_bus.dart';
import 'exceptions/app_exception.dart'; import 'exceptions/app_exception.dart';
import 'interceptors/error_interceptor.dart'; import 'interceptors/error_interceptor.dart';
import 'interceptors/request_interceptor.dart'; import 'interceptors/request_interceptor.dart';
...@@ -338,11 +339,19 @@ class DioRequest { ...@@ -338,11 +339,19 @@ class DioRequest {
}; };
} }
return ResponseModel<T>.fromJson( final result = ResponseModel<T>.fromJson(
jsonData, jsonData,
uuid: uuid, uuid: uuid,
fromJsonT: fromJsonT, fromJsonT: fromJsonT,
); );
// 当后端返回 HTTP 200 但 body 中 code 为 401 时,
// 表示 token 已在后端失效,触发 token 过期事件
if (result.code == 401) {
eventBus.emit(TokenExpiredEvent());
}
return result;
} catch (e) { } catch (e) {
return _handleError<T>(e, uuid); return _handleError<T>(e, uuid);
} finally { } finally {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment