提交 5345b482 authored 作者: 王鹏飞's avatar 王鹏飞

chore: update

上级 e70c4011
......@@ -48,3 +48,7 @@ app.*.map.json
# fvm
.fvm/
# App Store Connect / iOS signing secrets
.asc/
signing/
# Repository Guidelines
## Project Structure & Module Organization
This is a Flutter mobile app for Android and iOS. Application code lives in `lib/`:
- `lib/main.dart` and `lib/global.dart`: startup and global service initialization.
- `lib/pages/`: feature pages and controllers.
- `lib/routes/`: GoRouter configuration and route observers.
- `lib/services/`, `lib/apis/`, `lib/models/`: HTTP, API wrappers, and typed data models.
- `lib/store/`: GetX stores for user/session and configuration state.
- `lib/widgets/`, `lib/utils/`: shared UI components and helpers.
Assets are under `assets/`, including the embedded reader HTML in `assets/html/`. Native projects are in `android/` and `ios/`. Tests are in `test/`.
## Build, Test, and Development Commands
Use Flutter SDK `3.29.3` for this repository.
```bash
flutter pub get
```
Install Dart and Flutter dependencies.
```bash
cd ios && pod install && cd ..
flutter run -d ios
flutter run -d android
```
Install iOS pods, then run on iOS or Android.
```bash
flutter analyze
flutter test
```
Run static analysis and widget/unit tests.
```bash
flutter build apk --release
flutter build ios --release --no-codesign
flutter build ipa --release --export-options-plist=ios/ExportOptions.plist
```
Build Android, unsigned iOS, or App Store IPA artifacts.
## Coding Style & Naming Conventions
Follow Dart style with 2-space indentation and `flutter_lints` from `analysis_options.yaml`. Use `dart format` before larger changes. Prefer existing patterns: static API classes in `lib/apis/`, model classes in `lib/models/`, page-level controllers beside views, and shared widgets in `lib/widgets/`.
Name Dart files in `snake_case.dart`; classes, controllers, and models use `PascalCase`. Keep route names and paths centralized in `lib/routes/routes.dart`.
## Testing Guidelines
Use `flutter_test`; place tests in `test/` and name files `*_test.dart`. Add focused tests for routing, service behavior, utilities, and widget regressions when changing shared logic. Run `flutter test` and `flutter analyze` before submitting changes.
## Commit & Pull Request Guidelines
Recent history uses short Conventional Commit-style prefixes, often in Chinese, such as `fix: ...`, `chore: ...`, and `docs: ...`. Keep commits scoped and descriptive.
Pull requests should include a clear summary, affected platforms (`iOS`, `Android`, or both), test results, and screenshots or screen recordings for UI changes. Link related issues when available and call out release-sensitive changes such as signing, payments, permissions, app version, or native dependency updates.
## Security & Configuration Tips
Do not commit new secrets. Existing signing and app configuration files may contain sensitive values; avoid moving or printing them in logs. Keep Kotlin at `1.8.22` because payment dependencies rely on it, and preserve the iOS deployment target at `13.0+` unless release requirements change.
# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## 项目概述
清控紫荆数智学堂 — Flutter 移动端数字学习平台,支持 Android 和 iOS。包含课程阅读、图书馆浏览、购书、笔记、讨论、支付(微信/支付宝/内购)、离线阅读等功能。
## 关键约束
- **Flutter SDK 版本固定为 3.29.3**
- **Kotlin 必须保持在 1.8.22**,不可升级到 2.x — fluwx(微信支付)和 tobias(支付宝)与此版本耦合
- AGP 8.7.0,minSdk 24,target Java 17
- iOS 部署目标 13.0+
## 常用命令
```bash
# 安装依赖
flutter pub get
# iOS (首次及每次修改 native 依赖后需 pod install)
cd ios && pod install && cd ..
flutter run -d ios
# Android
flutter run -d android
# 静态分析
flutter analyze
# 构建
flutter build apk --release # Android
flutter build ios --release --no-codesign # iOS
```
## 架构总览
### 入口与应用初始化 (`lib/main.dart`)
`Global.init()` 在 `main()` 中首先调用,依次执行:
1. 锁定竖屏方向
2. 初始化 SQLite(`SqlManager.init()`)
3. 注册 GetX 服务:`StorageService`、`HttpService`、`UserStore`、`ConfigStore`
4. 监听网络恢复事件,自动上传离线数据
5. 恢复登录态:`UserStore.to.profile()`
应用根组件包裹在 `ScreenUtilInit`(设计稿 375x667)、`GetBuilder<ConfigStore>`(主题切换)和 `MaterialApp.router`(GoRouter)中。
### 状态管理 — GetX
`lib/store/` 中包含两个核心 Store:
- **`UserStore`**:登录态、token、用户信息。`_isLogin` 控制鉴权,`needLogin` 是一个 `ValueNotifier<bool>`,作为 GoRouter 的 `refreshListenable` 用于路由守卫。
- **`ConfigStore`**:主题模式(亮色/暗色/跟随系统)。
各页面通过 `GetBuilder` 订阅 Store 变化。
### 路由 — GoRouter (`lib/routes/routes.dart`)
约 45 条命名路由。关键守卫逻辑:
- GoRouter 的 `redirect` 回调检查 `UserStore.to.needLogin`:未登录且目标路由非主页/登录页时,重定向到 `/login`
- 部分独立页面(如 `book_detail`)通过 `_RouteRedirect.auth()` 在 `builder` 中二次校验
- 自定义 `RouteObserver` 追踪导航历史
- `BottomToTopTransitionPage` 用于图片查看器
首页是 4 个底部 tab:课程 (`/course`)、图书馆 (`/library`)、书架 (`/shop`)、我的 (`/mine`)。图书馆是默认 tab(index 1)。
### HTTP 层 (`lib/services/http.dart`)
基于 **Dio** 的单例服务,注册为 GetX 的 lazy singleton。
- **请求签名**:每个请求自动附加 `appId`、`appSecret`、`timestamp`、`Sign`(参数按 key 排序后 MD5 + appSecret 二次 MD5)
- **Token 刷新**:`_RequestInterceptor` 拦截 403 响应,调用 `/v1/members/login/getToken` 刷新 token 后重试原请求;刷新失败则登出并跳转登录页
- **响应缓存**:`_CacheInterceptor` 使用 `flutter_cache_manager`,默认 TTL 12 小时
- 响应统一包装为 `ResponseModel(code, msg, data)`
### API 层 (`lib/apis/`)
所有 API 类为 abstract static 类,调用 `HttpService.to.get()` / `.post()` 并返回类型化模型。不持有状态。
### 本地存储
- **SharedPreferences**(通过 `StorageService`):token、用户信息、隐私协议接受状态、主题、搜索历史
- **SQLite**(通过 `lib/utils/sql.dart` 的 `SqlManager`):离线笔记/划线(`members_book_notes` 表)、阅读历史(`read_history` 表)
- 离线同步:网络恢复时,`Global.init()` 中注册的 `ConnectivitySubscription` 触发 `LibraryAPI.uploadOffline()` 上传离线队列中的笔记
### 核心阅读器 (`lib/pages/read_web/`)
基于 `flutter_inappwebview` 加载本地 HTML 资源(`assets/html/read.html`)。HTML 内嵌 Vue 2、jQuery、MathJax 和公式编辑器。支持高亮、划线、笔记、音频播放、TTS 和全文搜索。
### 安全
- 请求签名:MD5(`lib/utils/sign.dart`)
- 加密:AES + MD5(`lib/utils/encrypt_util.dart`),用于下载时的资源解密
- `lib/utils/app_config.dart` 包含 `appId`、`appSecret` 和加密密钥
- 服务端基础 URL:`https://project-api.ezijing.com/api/book`(定义在 `lib/utils/constants.dart`)
### 支付
三通道支付:微信(fluwx)、支付宝(tobias)、iOS 内购(flutter_inapp_purchase)。应用内还有"紫荆币"虚拟货币体系。
### 文件上传
通过后端接口获取临时凭证后,使用 `flutter_oss_aliyun` 直传阿里云 OSS。
## 注意事项
- `analysis_options.yaml` 使用 `flutter_lints` v2,不要升级到 v5(需要 Flutter SDK 3.29+ 的兼容版本)
- `lib/utils/app_config.dart` 和 `android/key.properties` 包含密钥,已提交到仓库
- release keystore 已提交到仓库根目录
org.gradle.jvmargs=-Xmx1536M
org.gradle.jvmargs=-Xmx4G -XX:+HeapDumpOnOutOfMemoryError
android.useAndroidX=true
android.enableJetifier=true
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>destination</key>
<string>export</string>
<key>generateAppStoreInformation</key>
<true/>
<key>method</key>
<string>app-store</string>
<key>provisioningProfiles</key>
<dict>
<key>com.zijing.book.flutterBook</key>
<string>book-app-app-store-20260514</string>
</dict>
<key>signingStyle</key>
<string>automatic</string>
<key>teamID</key>
<string>MYN43C5WGE</string>
<key>uploadBitcode</key>
<false/>
<key>uploadSymbols</key>
<true/>
</dict>
</plist>
......@@ -20,7 +20,5 @@
<string>????</string>
<key>CFBundleVersion</key>
<string>1.0</string>
<key>MinimumOSVersion</key>
<string>12.0</string>
</dict>
</plist>
......@@ -36,9 +36,6 @@ PODS:
- OrderedSet (6.0.3)
- package_info_plus (0.4.5):
- Flutter
- path_provider_foundation (0.0.1):
- Flutter
- FlutterMacOS
- permission_handler_apple (9.3.0):
- Flutter
- ReachabilitySwift (5.2.4)
......@@ -68,7 +65,6 @@ DEPENDENCIES:
- image_picker_ios (from `.symlinks/plugins/image_picker_ios/ios`)
- just_audio (from `.symlinks/plugins/just_audio/darwin`)
- package_info_plus (from `.symlinks/plugins/package_info_plus/ios`)
- path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`)
- permission_handler_apple (from `.symlinks/plugins/permission_handler_apple/ios`)
- shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`)
- sqflite_darwin (from `.symlinks/plugins/sqflite_darwin/darwin`)
......@@ -106,8 +102,6 @@ EXTERNAL SOURCES:
:path: ".symlinks/plugins/just_audio/darwin"
package_info_plus:
:path: ".symlinks/plugins/package_info_plus/ios"
path_provider_foundation:
:path: ".symlinks/plugins/path_provider_foundation/darwin"
permission_handler_apple:
:path: ".symlinks/plugins/permission_handler_apple/ios"
shared_preferences_foundation:
......@@ -120,7 +114,7 @@ EXTERNAL SOURCES:
SPEC CHECKSUMS:
audio_session: 9bb7f6c970f21241b19f5a3658097ae459681ba0
connectivity_plus: 481668c94744c30c53b8895afb39159d1e619bdf
Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7
Flutter: cabc95a1d2626b1b06e7179b784ebcf0c0cde467
flutter_app_update: 816fdb2e30e4832a7c45e3f108d391c42ef040a9
flutter_inapp_purchase: 722da12971a50f306f37e62fc1aaf576b1cbecf6
flutter_inappwebview_ios: b89ba3482b96fb25e00c967aae065701b66e9b99
......@@ -128,14 +122,13 @@ SPEC CHECKSUMS:
flutter_sound_core: 7f2626d249d3a57bfa6da892ef7e22d234482c1a
flutter_tts: b88dbc8655d3dc961bc4a796e4e16a4cc1795833
fluwx: 49b4472b54762abde51daa0bc348ba05520016ac
image_picker_ios: 7fe1ff8e34c1790d6fff70a32484959f563a928a
image_picker_ios: e0ece4aa2a75771a7de3fa735d26d90817041326
just_audio: 4e391f57b79cad2b0674030a00453ca5ce817eed
OrderedSet: e539b66b644ff081c73a262d24ad552a69be3a94
package_info_plus: 566e1b7a2f3900e4b0020914ad3fc051dcc95596
path_provider_foundation: 080d55be775b7414fd5a5ef3ac137b97b097e564
permission_handler_apple: 4ed2196e43d0651e8ff7ca3483a069d469701f2d
ReachabilitySwift: 32793e867593cfc1177f5d16491e3a197d2fccda
shared_preferences_foundation: 9e1978ff2562383bd5676f64ec4e9aa8fa06a6f7
shared_preferences_foundation: 7036424c3d8ec98dfe75ff1667cb0cd531ec82bb
sqflite_darwin: 20b2a3a3b70e43edae938624ce550a3cbf66a3d0
tobias: f9c405df3ded93ad34539200fe3e7779cfb19081
WechatOpenSDK-XCFramework: ff342ae616bb86df3d236aca38059dfd4bc4a949
......
......@@ -468,37 +468,37 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SUPPORTED_PLATFORMS = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2";
TARGETED_DEVICE_FAMILY = 1;
VALIDATE_PRODUCT = YES;
};
name = Profile;
};
249021D4217E4FDB00AE95B9 /* Profile */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
249021D4217E4FDB00AE95B9 /* Profile */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CODE_SIGN_IDENTITY = "iPhone Distribution";
CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
DEVELOPMENT_TEAM = 65TSK9H32H;
DEVELOPMENT_TEAM = MYN43C5WGE;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = "清控紫荆数智学堂";
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.books";
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = com.zijing.book.flutterBook.max;
PRODUCT_BUNDLE_IDENTIFIER = com.zijing.book.flutterBook;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
PROVISIONING_PROFILE_SPECIFIER = "book-app-app-store-20260514";
VERSIONING_SYSTEM = "apple-generic";
};
name = Profile;
......@@ -592,11 +592,11 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2";
TARGETED_DEVICE_FAMILY = 1;
};
name = Debug;
};
......@@ -641,37 +641,37 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SUPPORTED_PLATFORMS = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2";
TARGETED_DEVICE_FAMILY = 1;
VALIDATE_PRODUCT = YES;
};
name = Release;
};
97C147061CF9000F007C117D /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
97C147061CF9000F007C117D /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
DEVELOPMENT_TEAM = 65TSK9H32H;
DEVELOPMENT_TEAM = MYN43C5WGE;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = "清控紫荆数智学堂";
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.books";
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = com.zijing.book.flutterBook.max;
PRODUCT_BUNDLE_IDENTIFIER = com.zijing.book.flutterBook;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
PROVISIONING_PROFILE_SPECIFIER = "";
VERSIONING_SYSTEM = "apple-generic";
};
name = Debug;
......@@ -682,22 +682,22 @@
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CODE_SIGN_IDENTITY = "iPhone Distribution";
CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
DEVELOPMENT_TEAM = 65TSK9H32H;
DEVELOPMENT_TEAM = MYN43C5WGE;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = "清控紫荆数智学堂";
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.books";
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = com.zijing.book.flutterBook.max;
PRODUCT_BUNDLE_IDENTIFIER = com.zijing.book.flutterBook;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
PROVISIONING_PROFILE_SPECIFIER = "book-app-app-store-20260514";
VERSIONING_SYSTEM = "apple-generic";
};
name = Release;
......
......@@ -26,6 +26,7 @@
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
customLLDBInitFile = "$(SRCROOT)/Flutter/ephemeral/flutter_lldbinit"
shouldUseLaunchSchemeArgsEnv = "YES">
<MacroExpansion>
<BuildableReference
......@@ -54,6 +55,7 @@
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
customLLDBInitFile = "$(SRCROOT)/Flutter/ephemeral/flutter_lldbinit"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
......
#import <Flutter/Flutter.h>
#import <UIKit/UIKit.h>
@interface AppDelegate : FlutterAppDelegate
@interface AppDelegate : FlutterAppDelegate <FlutterImplicitEngineDelegate>
@end
......@@ -5,9 +5,12 @@
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[GeneratedPluginRegistrant registerWithRegistry:self];
// Override point for customization after application launch.
return [super application:application didFinishLaunchingWithOptions:launchOptions];
}
- (void)didInitializeImplicitFlutterEngine:(NSObject<FlutterImplicitEngineBridge>*)engineBridge {
[GeneratedPluginRegistrant registerWithRegistry:engineBridge.pluginRegistry];
}
@end
......@@ -41,7 +41,7 @@
<string>weixin</string>
<key>CFBundleURLSchemes</key>
<array>
<string>1111</string>
<string>wx1111</string>
</array>
</dict>
</array>
......@@ -69,12 +69,35 @@
<string>清控紫荆数智学堂需要访问麦克风</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>清控紫荆数智学堂需要访问照片</string>
<key>UIApplicationSceneManifest</key>
<dict>
<key>UIApplicationSupportsMultipleScenes</key>
<false/>
<key>UISceneConfigurations</key>
<dict>
<key>UIWindowSceneSessionRoleApplication</key>
<array>
<dict>
<key>UISceneClassName</key>
<string>UIWindowScene</string>
<key>UISceneConfigurationName</key>
<string>flutter</string>
<key>UISceneDelegateClassName</key>
<string>FlutterSceneDelegate</string>
<key>UISceneStoryboardFile</key>
<string>Main</string>
</dict>
</array>
</dict>
</dict>
<key>UIApplicationSupportsIndirectInputEvents</key>
<true/>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIMainStoryboardFile</key>
<string>Main</string>
<key>UIRequiresFullScreen</key>
<true/>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationLandscapeLeft</string>
......
......@@ -34,15 +34,17 @@ class _ReadPageState extends State<ReadPage> {
chapterName: widget.chapterName,
bookDetailModel: widget.bookDetailModel,
noteId: widget.noteId),
builder: (readController) => WillPopScope(
onWillPop: () async {
PopBackModel backModel = PopBackModel(
chapterId: readController.chapterId,
back: true,
chapterName: readController.chapterId);
context.pop(backModel);
CustomToast.dismiss();
return false;
builder: (readController) => PopScope(
canPop: false,
onPopInvokedWithResult: (didPop, result) {
if (!didPop) {
PopBackModel backModel = PopBackModel(
chapterId: readController.chapterId,
back: true,
chapterName: readController.chapterId);
context.pop(backModel);
CustomToast.dismiss();
}
},
child: Scaffold(
appBar: CustomAppBar(
......
......@@ -271,8 +271,8 @@ class _UserSetPageState extends State<UserSetPage> {
context: context,
barrierDismissible: !forcedUpgrade,
builder: (BuildContext context) {
return WillPopScope(
onWillPop: () => Future.value(!forcedUpgrade),
return PopScope(
canPop: forcedUpgrade,
child: AlertDialog(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8.0.w),
......@@ -365,8 +365,8 @@ class _UserSetPageState extends State<UserSetPage> {
context: context,
barrierDismissible: !forcedUpgrade,
builder: (BuildContext context) {
return WillPopScope(
onWillPop: () => Future.value(!forcedUpgrade),
return PopScope(
canPop: forcedUpgrade,
child: AlertDialog(
insetPadding: EdgeInsets.zero, // 设置水平边距
shape: RoundedRectangleBorder(
......
......@@ -72,7 +72,6 @@ abstract class AppTheme {
static ThemeData get light {
var scheme = ColorScheme.light(
onBackground: const Color(0xFF333333),
surface: Colors.white,
onSurface: const Color(0xFF333333),
primary: primary,
......@@ -90,7 +89,6 @@ abstract class AppTheme {
static ThemeData get dark {
var scheme = ColorScheme.dark(
onBackground: Colors.white,
surface: const Color(0xFF252525),
onSurface: Colors.white,
primary: primary,
......@@ -113,7 +111,7 @@ abstract class AppTheme {
scaffoldBackgroundColor: scheme.surface,
splashColor: Colors.transparent,
highlightColor: Colors.transparent,
dialogTheme: DialogTheme(
dialogTheme: DialogThemeData(
elevation: 0,
titleTextStyle: TextStyle(
fontSize: 22.w,
......@@ -249,7 +247,7 @@ abstract class AppTheme {
borderRadius: BorderRadius.all(Radius.circular(6.w)),
),
),
tabBarTheme: TabBarTheme(
tabBarTheme: TabBarThemeData(
labelColor: scheme.primary,
unselectedLabelColor: scheme.surface,
labelStyle: TextStyle(
......
......@@ -105,8 +105,8 @@ abstract class Access {
context: context,
barrierDismissible: false, // 不允许点击外部关闭
builder: (BuildContext dialogContext) {
return WillPopScope(
onWillPop: () async => false, // 不允许返回键关闭
return PopScope(
canPop: false,
child: AlertDialog(
insetPadding: EdgeInsets.symmetric(horizontal: 40.w),
shape: RoundedRectangleBorder(
......@@ -212,8 +212,8 @@ abstract class Access {
showDialog(
context: context,
builder: (BuildContext dialogContext) {
return WillPopScope(
onWillPop: () => Future.value(true),
return PopScope(
canPop: true,
child: AlertDialog(
insetPadding: EdgeInsets.zero,
shape: RoundedRectangleBorder(
......
......@@ -311,7 +311,7 @@ class CustomInput extends StatelessWidget {
);
}
Widget? _suffixIcon(InputDecorationTheme decorationTheme) {
Widget? _suffixIcon(InputDecorationThemeData decorationTheme) {
if (iconData == null) return null;
return Padding(
padding: EdgeInsetsDirectional.only(
......@@ -570,7 +570,7 @@ class CustomInputCommands extends StatelessWidget {
);
}
Widget? _suffixIcon(InputDecorationTheme decorationTheme) {
Widget? _suffixIcon(InputDecorationThemeData decorationTheme) {
if (iconData == null) return null;
return Padding(
padding: EdgeInsetsDirectional.only(
......
......@@ -29,10 +29,10 @@ packages:
dependency: transitive
description:
name: async
sha256: d2872f9c19731c2e5f10444b14686eb7cc85c76274bd6c16e1816bff9a3bab63
sha256: e2eb0491ba5ddb6177742d2da23904574082139b07c1e33b8503b9f46f3e1a37
url: "https://pub.dev"
source: hosted
version: "2.12.0"
version: "2.13.1"
audio_session:
dependency: "direct main"
description:
......@@ -69,10 +69,10 @@ packages:
dependency: transitive
description:
name: characters
sha256: f71061c654a3380576a52b451dd5532377954cf9dbd272a78fc8479606670803
sha256: faf38497bda5ead2a8c7615f4f7939df04333478bf32e4173fcb06d428b5716b
url: "https://pub.dev"
source: hosted
version: "1.4.0"
version: "1.4.1"
clock:
dependency: transitive
description:
......@@ -81,6 +81,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.1.2"
code_assets:
dependency: transitive
description:
name: code_assets
sha256: "83ccdaa064c980b5596c35dd64a8d3ecc68620174ab9b90b6343b753aa721687"
url: "https://pub.dev"
source: hosted
version: "1.0.0"
collection:
dependency: transitive
description:
......@@ -117,10 +125,10 @@ packages:
dependency: transitive
description:
name: cross_file
sha256: "942a4791cd385a68ccb3b32c71c427aba508a1bb949b86dff2adbe4049f16239"
sha256: "28bb3ae56f117b5aec029d702a90f57d285cd975c3c5c281eaca38dbc47c5937"
url: "https://pub.dev"
source: hosted
version: "0.3.5"
version: "0.3.5+2"
crypto:
dependency: "direct main"
description:
......@@ -133,10 +141,10 @@ packages:
dependency: "direct main"
description:
name: cupertino_icons
sha256: ba631d1c7f7bef6b729a622b7b752645a2d076dba9976925b8f25725a30e1ee6
sha256: "41e005c33bd814be4d3096aff55b1908d419fde52ca656c8c47719ec745873cd"
url: "https://pub.dev"
source: hosted
version: "1.0.8"
version: "1.0.9"
dbus:
dependency: transitive
description:
......@@ -205,10 +213,10 @@ packages:
dependency: transitive
description:
name: fake_async
sha256: "6a95e56b2449df2273fd8c45a662d6947ce1ebb7aafe80e550a3f68297f3cacc"
sha256: "5368f224a74523e8d2e7399ea1638b37aecfca824a3cc4dfdf77bf1fa905ac44"
url: "https://pub.dev"
source: hosted
version: "1.3.2"
version: "1.3.3"
ffi:
dependency: transitive
description:
......@@ -229,18 +237,18 @@ packages:
dependency: transitive
description:
name: file_selector_linux
sha256: "54cbbd957e1156d29548c7d9b9ec0c0ebb6de0a90452198683a7d23aed617a33"
sha256: "2567f398e06ac72dcf2e98a0c95df2a9edd03c2c2e0cacd4780f20cdf56263a0"
url: "https://pub.dev"
source: hosted
version: "0.9.3+2"
version: "0.9.4"
file_selector_macos:
dependency: transitive
description:
name: file_selector_macos
sha256: "19124ff4a3d8864fdc62072b6a2ef6c222d55a3404fe14893a3c02744907b60c"
sha256: "5e0bbe9c312416f1787a68259ea1505b52f258c587f12920422671807c4d618a"
url: "https://pub.dev"
source: hosted
version: "0.9.4+4"
version: "0.9.5"
file_selector_platform_interface:
dependency: transitive
description:
......@@ -253,10 +261,10 @@ packages:
dependency: transitive
description:
name: file_selector_windows
sha256: "320fcfb6f33caa90f0b58380489fc5ac05d99ee94b61aa96ec2bff0ba81d3c2b"
sha256: "62197474ae75893a62df75939c777763d39c2bc5f73ce5b88497208bc269abfd"
url: "https://pub.dev"
source: hosted
version: "0.9.3+4"
version: "0.9.3+5"
fixnum:
dependency: transitive
description:
......@@ -391,10 +399,10 @@ packages:
dependency: transitive
description:
name: flutter_plugin_android_lifecycle
sha256: c2fe1001710127dfa7da89977a08d591398370d099aacdaa6d44da7eb14b8476
sha256: "38d1c268de9097ff59cf0e844ac38759fc78f76836d37edad06fa21e182055a0"
url: "https://pub.dev"
source: hosted
version: "2.0.31"
version: "2.0.34"
flutter_screenutil:
dependency: "direct main"
description:
......@@ -485,6 +493,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "4.7.3"
glob:
dependency: transitive
description:
name: glob
sha256: c3f1ee72c96f8f78935e18aa8cecced9ab132419e8625dc187e1c2408efc20de
url: "https://pub.dev"
source: hosted
version: "2.1.3"
go_router:
dependency: "direct main"
description:
......@@ -493,6 +509,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "10.2.0"
hooks:
dependency: transitive
description:
name: hooks
sha256: "025f060e86d2d4c3c47b56e33caf7f93bf9283340f26d23424ebcfccf34f621e"
url: "https://pub.dev"
source: hosted
version: "1.0.3"
http:
dependency: transitive
description:
......@@ -521,34 +545,34 @@ packages:
dependency: "direct main"
description:
name: image_picker
sha256: "784210112be18ea55f69d7076e2c656a4e24949fa9e76429fe53af0c0f4fa320"
sha256: "91c025426c2881c551100bce834e201c835a170151545f58d17da5180ca7d9ac"
url: "https://pub.dev"
source: hosted
version: "1.2.1"
version: "1.2.2"
image_picker_android:
dependency: transitive
description:
name: image_picker_android
sha256: "28f3987ca0ec702d346eae1d90eda59603a2101b52f1e234ded62cff1d5cfa6e"
sha256: d5b3e1774af29c9ab00103afb0d4614070f924d2e0057ac867ec98800114793f
url: "https://pub.dev"
source: hosted
version: "0.8.13+1"
version: "0.8.13+17"
image_picker_for_web:
dependency: transitive
description:
name: image_picker_for_web
sha256: "40c2a6a0da15556dc0f8e38a3246064a971a9f512386c3339b89f76db87269b6"
sha256: "66257a3191ab360d23a55c8241c91a6e329d31e94efa7be9cf7a212e65850214"
url: "https://pub.dev"
source: hosted
version: "3.1.0"
version: "3.1.1"
image_picker_ios:
dependency: transitive
description:
name: image_picker_ios
sha256: eb06fe30bab4c4497bad449b66448f50edcc695f1c59408e78aa3a8059eb8f0e
sha256: b9c4a438a9ff4f60808c9cf0039b93a42bb6c2211ef6ebb647394b2b3fa84588
url: "https://pub.dev"
source: hosted
version: "0.8.13"
version: "0.8.13+6"
image_picker_linux:
dependency: transitive
description:
......@@ -561,10 +585,10 @@ packages:
dependency: transitive
description:
name: image_picker_macos
sha256: d58cd9d67793d52beefd6585b12050af0a7663c0c2a6ece0fb110a35d6955e04
sha256: "86f0f15a309de7e1a552c12df9ce5b59fe927e71385329355aec4776c6a8ec91"
url: "https://pub.dev"
source: hosted
version: "0.2.2"
version: "0.2.2+1"
image_picker_platform_interface:
dependency: transitive
description:
......@@ -585,10 +609,26 @@ packages:
dependency: "direct main"
description:
name: intl
sha256: d6f56758b7d3014a48af9701c085700aac781a92a87a62b1333b46d8879661cf
sha256: "3df61194eb431efc39c4ceba583b95633a403f46c9fd341e550ce0bfa50e9aa5"
url: "https://pub.dev"
source: hosted
version: "0.19.0"
version: "0.20.2"
jni:
dependency: transitive
description:
name: jni
sha256: c2230682d5bc2362c1c9e8d3c7f406d9cbba23ab3f2e203a025dd47e0fb2e68f
url: "https://pub.dev"
source: hosted
version: "1.0.0"
jni_flutter:
dependency: transitive
description:
name: jni_flutter
sha256: "8b59e590786050b1cd866677dddaf76b1ade5e7bc751abe04b86e84d379d3ba6"
url: "https://pub.dev"
source: hosted
version: "1.0.1"
js:
dependency: transitive
description:
......@@ -625,26 +665,26 @@ packages:
dependency: transitive
description:
name: leak_tracker
sha256: c35baad643ba394b40aac41080300150a4f08fd0fd6a10378f8f7c6bc161acec
sha256: "33e2e26bdd85a0112ec15400c8cbffea70d0f9c3407491f672a2fad47915e2de"
url: "https://pub.dev"
source: hosted
version: "10.0.8"
version: "11.0.2"
leak_tracker_flutter_testing:
dependency: transitive
description:
name: leak_tracker_flutter_testing
sha256: f8b613e7e6a13ec79cfdc0e97638fddb3ab848452eff057653abd3edba760573
sha256: "1dbc140bb5a23c75ea9c4811222756104fbcd1a27173f0c34ca01e16bea473c1"
url: "https://pub.dev"
source: hosted
version: "3.0.9"
version: "3.0.10"
leak_tracker_testing:
dependency: transitive
description:
name: leak_tracker_testing
sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3"
sha256: "8d5a2d49f4a66b49744b23b018848400d23e54caf9463f4eb20df3eb8acb2eb1"
url: "https://pub.dev"
source: hosted
version: "3.0.1"
version: "3.0.2"
lints:
dependency: transitive
description:
......@@ -673,26 +713,26 @@ packages:
dependency: transitive
description:
name: matcher
sha256: dc58c723c3c24bf8d3e2d3ad3f2f9d7bd9cf43ec6feaa64181775e60190153f2
sha256: dc0b7dc7651697ea4ff3e69ef44b0407ea32c487a39fff6a4004fa585e901861
url: "https://pub.dev"
source: hosted
version: "0.12.17"
version: "0.12.19"
material_color_utilities:
dependency: transitive
description:
name: material_color_utilities
sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec
sha256: "9c337007e82b1889149c82ed242ed1cb24a66044e30979c44912381e9be4c48b"
url: "https://pub.dev"
source: hosted
version: "0.11.1"
version: "0.13.0"
meta:
dependency: transitive
description:
name: meta
sha256: e3641ec5d63ebf0d9b41bd43201a66e3fc79a65db5f61fc181f04cd27aab950c
sha256: "23f08335362185a5ea2ad3a4e597f1375e78bce8a040df5c600c8d3552ef2394"
url: "https://pub.dev"
source: hosted
version: "1.16.0"
version: "1.17.0"
mime:
dependency: transitive
description:
......@@ -701,6 +741,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.0.6"
native_toolchain_c:
dependency: transitive
description:
name: native_toolchain_c
sha256: "6ba77bb18063eebe9de401f5e6437e95e1438af0a87a3a39084fbd37c90df572"
url: "https://pub.dev"
source: hosted
version: "0.17.6"
nm:
dependency: transitive
description:
......@@ -709,6 +757,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "0.5.0"
objective_c:
dependency: transitive
description:
name: objective_c
sha256: "100a1c87616ab6ed41ec263b083c0ef3261ee6cd1dc3b0f35f8ddfa4f996fe52"
url: "https://pub.dev"
source: hosted
version: "9.3.0"
oktoast:
dependency: "direct main"
description:
......@@ -717,6 +773,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "3.4.0"
package_config:
dependency: transitive
description:
name: package_config
sha256: f096c55ebb7deb7e384101542bfba8c52696c1b56fca2eb62827989ef2353bbc
url: "https://pub.dev"
source: hosted
version: "2.2.0"
package_info_plus:
dependency: "direct main"
description:
......@@ -734,7 +798,7 @@ packages:
source: hosted
version: "2.0.1"
path:
dependency: transitive
dependency: "direct main"
description:
name: path
sha256: "75cca69d1490965be98c73ceaea117e8a04dd21217b37b292c9ddbec0d955bc5"
......@@ -769,18 +833,18 @@ packages:
dependency: transitive
description:
name: path_provider_android
sha256: "3b4c1fc3aa55ddc9cd4aa6759984330d5c8e66aa7702a6223c61540dc6380c37"
sha256: "69cbd515a62b94d32a7944f086b2f82b4ac40a1d45bebfc00813a430ab2dabcd"
url: "https://pub.dev"
source: hosted
version: "2.2.19"
version: "2.3.1"
path_provider_foundation:
dependency: transitive
description:
name: path_provider_foundation
sha256: "16eef174aacb07e09c351502740fa6254c165757638eba1e9116b0a781201bbd"
sha256: "2a376b7d6392d80cd3705782d2caa734ca4727776db0b6ec36ef3f1855197699"
url: "https://pub.dev"
source: hosted
version: "2.4.2"
version: "2.6.0"
path_provider_linux:
dependency: transitive
description:
......@@ -857,10 +921,10 @@ packages:
dependency: transitive
description:
name: petitparser
sha256: "07c8f0b1913bcde1ff0d26e57ace2f3012ccbf2b204e070290dad3bb22797646"
sha256: "91bd59303e9f769f108f8df05e371341b15d59e995e6806aefab827b58336675"
url: "https://pub.dev"
source: hosted
version: "6.1.0"
version: "7.0.2"
platform:
dependency: transitive
description:
......@@ -885,6 +949,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "3.9.1"
pub_semver:
dependency: transitive
description:
name: pub_semver
sha256: "5bfcf68ca79ef689f8990d1160781b4bad40a3bd5e5218ad4076ddb7f4081585"
url: "https://pub.dev"
source: hosted
version: "2.2.0"
rational:
dependency: transitive
description:
......@@ -893,6 +965,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.2.3"
record_use:
dependency: transitive
description:
name: record_use
sha256: "2551bd8eecfe95d14ae75f6021ad0248be5c27f138c2ec12fcb52b500b3ba1ed"
url: "https://pub.dev"
source: hosted
version: "0.6.0"
rxdart:
dependency: transitive
description:
......@@ -905,26 +985,26 @@ packages:
dependency: "direct main"
description:
name: shared_preferences
sha256: "6e8bf70b7fef813df4e9a36f658ac46d107db4b4cfe1048b477d4e453a8159f5"
sha256: c3025c5534b01739267eb7d76959bbc25a6d10f6988e1c2a3036940133dd10bf
url: "https://pub.dev"
source: hosted
version: "2.5.3"
version: "2.5.5"
shared_preferences_android:
dependency: transitive
description:
name: shared_preferences_android
sha256: bd14436108211b0d4ee5038689a56d4ae3620fd72fd6036e113bf1345bc74d9e
sha256: e8d4762b1e2e8578fc4d0fd548cebf24afd24f49719c08974df92834565e2c53
url: "https://pub.dev"
source: hosted
version: "2.4.13"
version: "2.4.23"
shared_preferences_foundation:
dependency: transitive
description:
name: shared_preferences_foundation
sha256: "6a52cfcdaeac77cad8c97b539ff688ccfc458c007b4db12be584fbe5c0e49e03"
sha256: "4e7eaffc2b17ba398759f1151415869a34771ba11ebbccd1b0145472a619a64f"
url: "https://pub.dev"
source: hosted
version: "2.5.4"
version: "2.5.6"
shared_preferences_linux:
dependency: transitive
description:
......@@ -937,10 +1017,10 @@ packages:
dependency: transitive
description:
name: shared_preferences_platform_interface
sha256: "57cbf196c486bc2cf1f02b85784932c6094376284b3ad5779d1b1c6c6a816b80"
sha256: "649dc798a33931919ea356c4305c2d1f81619ea6e92244070b520187b5140ef9"
url: "https://pub.dev"
source: hosted
version: "2.4.1"
version: "2.4.2"
shared_preferences_web:
dependency: transitive
description:
......@@ -966,34 +1046,34 @@ packages:
dependency: transitive
description:
name: source_span
sha256: "254ee5351d6cb365c859e20ee823c3bb479bf4a293c22d17a9f1bf144ce86f7c"
sha256: "56a02f1f4cd1a2d96303c0144c93bd6d909eea6bee6bf5a0e0b685edbd4c47ab"
url: "https://pub.dev"
source: hosted
version: "1.10.1"
version: "1.10.2"
sqflite:
dependency: "direct main"
description:
name: sqflite
sha256: e2297b1da52f127bc7a3da11439985d9b536f75070f3325e62ada69a5c585d03
sha256: "564cfed0746fe53140c23b70b308e045c3b31f17778f2f326ccb7d804ea0250a"
url: "https://pub.dev"
source: hosted
version: "2.4.2"
version: "2.4.2+1"
sqflite_android:
dependency: transitive
description:
name: sqflite_android
sha256: "2b3070c5fa881839f8b402ee4a39c1b4d561704d4ebbbcfb808a119bc2a1701b"
sha256: "881e28efdcc9950fd8e9bb42713dcf1103e62a2e7168f23c9338d82db13dec40"
url: "https://pub.dev"
source: hosted
version: "2.4.1"
version: "2.4.2+3"
sqflite_common:
dependency: transitive
description:
name: sqflite_common
sha256: "84731e8bfd8303a3389903e01fb2141b6e59b5973cacbb0929021df08dddbe8b"
sha256: f8a08a13fb8f0f8c590df89d745000bed44a673ed94bac846739e1a016875c21
url: "https://pub.dev"
source: hosted
version: "2.5.5"
version: "2.5.7"
sqflite_darwin:
dependency: transitive
description:
......@@ -1038,10 +1118,10 @@ packages:
dependency: transitive
description:
name: synchronized
sha256: "0669c70faae6270521ee4f05bffd2919892d42d1276e6c495be80174b6bc0ef6"
sha256: "63896c27e81b28f8cb4e69ead0d3e8f03f1d1e5fc531a3e579cabed6a2c7c9e5"
url: "https://pub.dev"
source: hosted
version: "3.3.1"
version: "3.4.0+1"
term_glyph:
dependency: transitive
description:
......@@ -1054,10 +1134,10 @@ packages:
dependency: transitive
description:
name: test_api
sha256: fb31f383e2ee25fbbfe06b40fe21e1e458d14080e3c67e7ba0acfde4df4e0bbd
sha256: "8161c84903fd860b26bfdefb7963b3f0b68fee7adea0f59ef805ecca346f0c7a"
url: "https://pub.dev"
source: hosted
version: "0.7.4"
version: "0.7.10"
tobias:
dependency: "direct main"
description:
......@@ -1086,18 +1166,18 @@ packages:
dependency: transitive
description:
name: vector_math
sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803"
sha256: d530bd74fea330e6e364cda7a85019c434070188383e1cd8d9777ee586914c5b
url: "https://pub.dev"
source: hosted
version: "2.1.4"
version: "2.2.0"
vm_service:
dependency: transitive
description:
name: vm_service
sha256: "0968250880a6c5fe7edc067ed0a13d4bae1577fe2771dcf3010d52c4a9d3ca14"
sha256: "0016aef94fc66495ac78af5859181e3f3bf2026bd8eecc72b9565601e19ab360"
url: "https://pub.dev"
source: hosted
version: "14.3.1"
version: "15.2.0"
web:
dependency: transitive
description:
......@@ -1110,10 +1190,10 @@ packages:
dependency: transitive
description:
name: win32
sha256: "329edf97fdd893e0f1e3b9e88d6a0e627128cc17cc316a8d67fda8f1451178ba"
sha256: d7cb55e04cd34096cd3a79b3330245f54cb96a370a1c27adb3c84b917de8b08e
url: "https://pub.dev"
source: hosted
version: "5.13.0"
version: "5.15.0"
xdg_directories:
dependency: transitive
description:
......@@ -1126,10 +1206,18 @@ packages:
dependency: transitive
description:
name: xml
sha256: b015a8ad1c488f66851d762d3090a21c600e479dc75e68328c52774040cf9226
sha256: "971043b3a0d3da28727e40ed3e0b5d18b742fa5a68665cca88e74b7876d5e025"
url: "https://pub.dev"
source: hosted
version: "6.6.1"
yaml:
dependency: transitive
description:
name: yaml
sha256: b9da305ac7c39faa3f030eccd175340f968459dae4af175130b3fc47e40d76ce
url: "https://pub.dev"
source: hosted
version: "6.5.0"
version: "3.1.3"
sdks:
dart: ">=3.7.2 <4.0.0"
flutter: ">=3.29.0"
dart: ">=3.11.0 <4.0.0"
flutter: ">=3.38.4"
......@@ -16,13 +16,13 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
# In Windows, build-name is used as the major, minor, and patch parts
# of the product and file versions while build-number is used as the build suffix.
version: 1.0.1+2
version: 1.0.1+4
environment:
sdk: '>=3.0.0 <4.0.0'
fluwx:
app_id: '1111'
app_id: 'wx1111'
debug_logging: true
# Dependencies specify other packages that your package needs in order to work.
......@@ -59,14 +59,15 @@ dependencies:
# 录音
flutter_tts: ^3.8.5
# webview
flutter_inappwebview: ^6.0.0
intl: ^0.19.0
flutter_inappwebview: ^6.1.0
intl: ^0.20.2
# 录音
flutter_sound: 9.30.0
permission_handler: ^12.0.0
audio_session: ^0.1.6
flutter_sound_platform_interface: 9.30.0
path: ^1.9.0
# 获取目录结构
path_provider: ^2.0.2
# 下拉刷新 上拉加载更多
......
#!/bin/bash
set -e
# =============================================
# 清控紫荆数智学堂 — iOS 发布脚本
# 用法: ./scripts/ios_publish.sh [--submit]
# =============================================
APP_ID="6476735372"
PROJECT_DIR="$(cd "$(dirname "$0")/.." && pwd)"
# 从 pubspec.yaml 读取版本号
VERSION=$(grep '^version:' "$PROJECT_DIR/pubspec.yaml" | sed 's/version: //' | cut -d'+' -f1)
BUILD=$(grep '^version:' "$PROJECT_DIR/pubspec.yaml" | sed 's/version: //' | cut -d'+' -f2)
# 解析参数
SUBMIT=false
for arg in "$@"; do
case $arg in
--submit) SUBMIT=true ;;
esac
done
echo "========================================="
echo " App: 清控紫荆数智学堂 ($APP_ID)"
echo " 版本: $VERSION (build $BUILD)"
echo "========================================="
# 1. 安装依赖
echo "[1/4] 安装 Flutter 依赖..."
cd "$PROJECT_DIR"
flutter pub get
# 2. Pod install
echo "[2/4] 安装 CocoaPods 依赖..."
cd "$PROJECT_DIR/ios"
pod install
# 3. 构建 IPA(Flutter 内置流程:build → archive → export)
echo "[3/4] 构建 IPA..."
cd "$PROJECT_DIR"
# 生成 ExportOptions.plist(如果不存在)
EXPORT_OPTIONS="$PROJECT_DIR/ios/ExportOptions.plist"
if [ ! -f "$EXPORT_OPTIONS" ]; then
cat > "$EXPORT_OPTIONS" << 'XMLEOF'
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>method</key>
<string>app-store</string>
<key>destination</key>
<string>export</string>
<key>teamID</key>
<string>MYN43C5WGE</string>
<key>uploadBitcode</key>
<false/>
<key>uploadSymbols</key>
<true/>
<key>signingStyle</key>
<string>automatic</string>
<key>generateAppStoreInformation</key>
<true/>
</dict>
</plist>
XMLEOF
echo "已生成 ExportOptions.plist"
fi
flutter build ipa --release \
--export-options-plist="$EXPORT_OPTIONS"
IPA_PATH="$PROJECT_DIR/build/ios/ipa/flutter_book.ipa"
if [ ! -f "$IPA_PATH" ]; then
echo "错误: IPA 文件未生成: $IPA_PATH"
exit 1
fi
echo "IPA 生成成功: $IPA_PATH"
# 4. 上传到 App Store
echo "[4/4] 上传到 App Store..."
if [ "$SUBMIT" = true ]; then
asc publish appstore \
--app "$APP_ID" \
--ipa "$IPA_PATH" \
--version "$VERSION" \
--submit --confirm
else
asc builds upload \
--app "$APP_ID" \
--ipa "$IPA_PATH"
fi
echo ""
echo "========================================="
echo " 上传完成!"
echo " 版本: $VERSION (build $BUILD)"
if [ "$SUBMIT" = true ]; then
echo " 已自动提交审核"
else
echo " 未提交审核,可用以下命令提交:"
echo " asc review status --app $APP_ID"
echo " 或运行: $0 --submit"
fi
echo "========================================="
Markdown 格式
0% 或
您添加了 0 人 到此讨论。请谨慎行事。
请先完成此评论的编辑!
请 注册 或者 后发表评论