提交 67ef61b0 authored 作者: 王鹏飞's avatar 王鹏飞

Refactor HttpService and Access utility for improved permission handling and code clarity

- Updated HttpService to enhance header management and error handling. - Improved Access utility to include permission explanation dialogs before requesting permissions. - Modified AssetsPicker to check for permissions before accessing the camera or gallery. - Adjusted constants for server URLs and agreements for better maintainability. - Cleaned up pubspec.yaml and pubspec.lock by removing unused dependencies.
上级 883b112b
...@@ -51,30 +51,18 @@ android { ...@@ -51,30 +51,18 @@ android {
versionName flutterVersionName versionName flutterVersionName
} }
signingConfigs { signingConfigs {
// release {
// keyAlias keystoreProperties['keyAlias']
// keyPassword keystoreProperties['keyPassword']
// storeFile file(keystoreProperties['storeFile'])
// storePassword keystoreProperties['storePassword']
// }
release{ release{
keyAlias keystoreProperties['keyAlias'] keyAlias keystoreProperties['keyAlias']
keyPassword keystoreProperties['keyPassword'] keyPassword keystoreProperties['keyPassword']
storeFile file(keystoreProperties['storeFile']) storeFile file(keystoreProperties['storeFile'])
storePassword keystoreProperties['storePassword'] storePassword keystoreProperties['storePassword']
} }
debug{ // debug 使用默认签名
keyAlias keystoreProperties['keyAlias']
keyPassword keystoreProperties['keyPassword']
storeFile file(keystoreProperties['storeFile'])
storePassword keystoreProperties['storePassword']
}
} }
buildTypes { buildTypes {
debug { debug {
signingConfig signingConfigs.release // 使用默认 debug 签名
} }
release { release {
// TODO: Add your own signing config for the release build. // TODO: Add your own signing config for the release build.
......
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
</queries> </queries>
<application <application
android:label="紫荆数智学堂" android:label="清控紫荆数智学堂"
android:name="${applicationName}" android:name="${applicationName}"
android:icon="@mipmap/ic_launcher"> android:icon="@mipmap/ic_launcher">
<activity <activity
......
storePassword=123456 storePassword=zijing123456
keyPassword=zijing123456
keyPassword=123456
keyAlias=zijing keyAlias=zijing
storeFile=../zijing_release.jks
storeFile=/Users/apple/zijiing_key.jks
#storeFile=zijiing_key.jks
\ No newline at end of file
PODS: PODS:
- audio_session (0.0.1): - audio_session (0.0.1):
- Flutter - Flutter
- Bugly (2.6.1)
- connectivity_plus (0.0.1): - connectivity_plus (0.0.1):
- Flutter - Flutter
- ReachabilitySwift - ReachabilitySwift
...@@ -10,9 +9,6 @@ PODS: ...@@ -10,9 +9,6 @@ PODS:
- Flutter (1.0.0) - Flutter (1.0.0)
- flutter_app_update (0.0.1): - flutter_app_update (0.0.1):
- Flutter - Flutter
- flutter_bugly (0.0.1):
- Bugly
- Flutter
- flutter_inapp_purchase (0.0.1): - flutter_inapp_purchase (0.0.1):
- Flutter - Flutter
- flutter_inappwebview_ios (0.0.1): - flutter_inappwebview_ios (0.0.1):
...@@ -47,10 +43,6 @@ PODS: ...@@ -47,10 +43,6 @@ PODS:
- permission_handler_apple (9.1.1): - permission_handler_apple (9.1.1):
- Flutter - Flutter
- ReachabilitySwift (5.0.0) - ReachabilitySwift (5.0.0)
- screen_protector (1.2.1):
- Flutter
- ScreenProtectorKit (~> 1.3.1)
- ScreenProtectorKit (1.3.1)
- shared_preferences_foundation (0.0.1): - shared_preferences_foundation (0.0.1):
- Flutter - Flutter
- FlutterMacOS - FlutterMacOS
...@@ -70,7 +62,6 @@ DEPENDENCIES: ...@@ -70,7 +62,6 @@ DEPENDENCIES:
- device_info_plus (from `.symlinks/plugins/device_info_plus/ios`) - device_info_plus (from `.symlinks/plugins/device_info_plus/ios`)
- Flutter (from `Flutter`) - Flutter (from `Flutter`)
- flutter_app_update (from `.symlinks/plugins/flutter_app_update/ios`) - flutter_app_update (from `.symlinks/plugins/flutter_app_update/ios`)
- flutter_bugly (from `.symlinks/plugins/flutter_bugly/ios`)
- flutter_inapp_purchase (from `.symlinks/plugins/flutter_inapp_purchase/ios`) - flutter_inapp_purchase (from `.symlinks/plugins/flutter_inapp_purchase/ios`)
- flutter_inappwebview_ios (from `.symlinks/plugins/flutter_inappwebview_ios/ios`) - flutter_inappwebview_ios (from `.symlinks/plugins/flutter_inappwebview_ios/ios`)
- flutter_sound (from `.symlinks/plugins/flutter_sound/ios`) - flutter_sound (from `.symlinks/plugins/flutter_sound/ios`)
...@@ -81,18 +72,15 @@ DEPENDENCIES: ...@@ -81,18 +72,15 @@ DEPENDENCIES:
- package_info_plus (from `.symlinks/plugins/package_info_plus/ios`) - package_info_plus (from `.symlinks/plugins/package_info_plus/ios`)
- path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`) - path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`)
- permission_handler_apple (from `.symlinks/plugins/permission_handler_apple/ios`) - permission_handler_apple (from `.symlinks/plugins/permission_handler_apple/ios`)
- screen_protector (from `.symlinks/plugins/screen_protector/ios`)
- shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`) - shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`)
- sqflite (from `.symlinks/plugins/sqflite/darwin`) - sqflite (from `.symlinks/plugins/sqflite/darwin`)
- tobias (from `.symlinks/plugins/tobias/ios`) - tobias (from `.symlinks/plugins/tobias/ios`)
SPEC REPOS: SPEC REPOS:
trunk: trunk:
- Bugly
- flutter_sound_core - flutter_sound_core
- OrderedSet - OrderedSet
- ReachabilitySwift - ReachabilitySwift
- ScreenProtectorKit
- WechatOpenSDK-XCFramework - WechatOpenSDK-XCFramework
EXTERNAL SOURCES: EXTERNAL SOURCES:
...@@ -106,8 +94,6 @@ EXTERNAL SOURCES: ...@@ -106,8 +94,6 @@ EXTERNAL SOURCES:
:path: Flutter :path: Flutter
flutter_app_update: flutter_app_update:
:path: ".symlinks/plugins/flutter_app_update/ios" :path: ".symlinks/plugins/flutter_app_update/ios"
flutter_bugly:
:path: ".symlinks/plugins/flutter_bugly/ios"
flutter_inapp_purchase: flutter_inapp_purchase:
:path: ".symlinks/plugins/flutter_inapp_purchase/ios" :path: ".symlinks/plugins/flutter_inapp_purchase/ios"
flutter_inappwebview_ios: flutter_inappwebview_ios:
...@@ -128,8 +114,6 @@ EXTERNAL SOURCES: ...@@ -128,8 +114,6 @@ EXTERNAL SOURCES:
:path: ".symlinks/plugins/path_provider_foundation/darwin" :path: ".symlinks/plugins/path_provider_foundation/darwin"
permission_handler_apple: permission_handler_apple:
:path: ".symlinks/plugins/permission_handler_apple/ios" :path: ".symlinks/plugins/permission_handler_apple/ios"
screen_protector:
:path: ".symlinks/plugins/screen_protector/ios"
shared_preferences_foundation: shared_preferences_foundation:
:path: ".symlinks/plugins/shared_preferences_foundation/darwin" :path: ".symlinks/plugins/shared_preferences_foundation/darwin"
sqflite: sqflite:
...@@ -139,12 +123,10 @@ EXTERNAL SOURCES: ...@@ -139,12 +123,10 @@ EXTERNAL SOURCES:
SPEC CHECKSUMS: SPEC CHECKSUMS:
audio_session: 9bdd3bf46960d4322cb8c3cb6138295dcfe84eee audio_session: 9bdd3bf46960d4322cb8c3cb6138295dcfe84eee
Bugly: 217ac2ce5f0f2626d43dbaa4f70764c953a26a31
connectivity_plus: 481668c94744c30c53b8895afb39159d1e619bdf connectivity_plus: 481668c94744c30c53b8895afb39159d1e619bdf
device_info_plus: 335f3ce08d2e174b9fdc3db3db0f4e3b1f66bd89 device_info_plus: 335f3ce08d2e174b9fdc3db3db0f4e3b1f66bd89
Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854 Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854
flutter_app_update: 816fdb2e30e4832a7c45e3f108d391c42ef040a9 flutter_app_update: 816fdb2e30e4832a7c45e3f108d391c42ef040a9
flutter_bugly: 12197049262a692eab0bd2834d465a5647d920c2
flutter_inapp_purchase: 722da12971a50f306f37e62fc1aaf576b1cbecf6 flutter_inapp_purchase: 722da12971a50f306f37e62fc1aaf576b1cbecf6
flutter_inappwebview_ios: 25b61a1b550d1068e4ddaf490fc1d03c2ce6828d flutter_inappwebview_ios: 25b61a1b550d1068e4ddaf490fc1d03c2ce6828d
flutter_sound: 49be32081884d275fe91d48262f4b1fcd86e10d3 flutter_sound: 49be32081884d275fe91d48262f4b1fcd86e10d3
...@@ -158,8 +140,6 @@ SPEC CHECKSUMS: ...@@ -158,8 +140,6 @@ SPEC CHECKSUMS:
path_provider_foundation: 608fcb11be570ce83519b076ab6a1fffe2474f05 path_provider_foundation: 608fcb11be570ce83519b076ab6a1fffe2474f05
permission_handler_apple: 3787117e48f80715ff04a3830ca039283d6a4f29 permission_handler_apple: 3787117e48f80715ff04a3830ca039283d6a4f29
ReachabilitySwift: 985039c6f7b23a1da463388634119492ff86c825 ReachabilitySwift: 985039c6f7b23a1da463388634119492ff86c825
screen_protector: 3d90d44ac886b25335aebd93230b454aef45794a
ScreenProtectorKit: 83a6281b02c7a5902ee6eac4f5045f674e902ae4
shared_preferences_foundation: 0b09b969fb36da5551c0bc4a2dbd9d0ff9387478 shared_preferences_foundation: 0b09b969fb36da5551c0bc4a2dbd9d0ff9387478
sqflite: c35dad70033b8862124f8337cc994a809fcd9fa3 sqflite: c35dad70033b8862124f8337cc994a809fcd9fa3
tobias: 50b529c2501d277c83fef9976803a001eb58a057 tobias: 50b529c2501d277c83fef9976803a001eb58a057
......
...@@ -489,7 +489,7 @@ ...@@ -489,7 +489,7 @@
DEVELOPMENT_TEAM = MYN43C5WGE; DEVELOPMENT_TEAM = MYN43C5WGE;
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist; INFOPLIST_FILE = Runner/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = "紫荆数智学堂"; INFOPLIST_KEY_CFBundleDisplayName = "清控紫荆数智学堂";
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.books"; INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.books";
IPHONEOS_DEPLOYMENT_TARGET = 12.0; IPHONEOS_DEPLOYMENT_TARGET = 12.0;
LD_RUNPATH_SEARCH_PATHS = ( LD_RUNPATH_SEARCH_PATHS = (
...@@ -662,7 +662,7 @@ ...@@ -662,7 +662,7 @@
DEVELOPMENT_TEAM = MYN43C5WGE; DEVELOPMENT_TEAM = MYN43C5WGE;
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist; INFOPLIST_FILE = Runner/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = "紫荆数智学堂"; INFOPLIST_KEY_CFBundleDisplayName = "清控紫荆数智学堂";
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.books"; INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.books";
IPHONEOS_DEPLOYMENT_TARGET = 12.0; IPHONEOS_DEPLOYMENT_TARGET = 12.0;
LD_RUNPATH_SEARCH_PATHS = ( LD_RUNPATH_SEARCH_PATHS = (
...@@ -688,7 +688,7 @@ ...@@ -688,7 +688,7 @@
DEVELOPMENT_TEAM = MYN43C5WGE; DEVELOPMENT_TEAM = MYN43C5WGE;
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist; INFOPLIST_FILE = Runner/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = "紫荆数智学堂"; INFOPLIST_KEY_CFBundleDisplayName = "清控紫荆数智学堂";
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.books"; INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.books";
IPHONEOS_DEPLOYMENT_TARGET = 12.0; IPHONEOS_DEPLOYMENT_TARGET = 12.0;
LD_RUNPATH_SEARCH_PATHS = ( LD_RUNPATH_SEARCH_PATHS = (
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
<key>CFBundleDevelopmentRegion</key> <key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string> <string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleDisplayName</key> <key>CFBundleDisplayName</key>
<string>紫荆数智学堂</string> <string>清控紫荆数智学堂</string>
<key>CFBundleExecutable</key> <key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string> <string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key> <key>CFBundleIdentifier</key>
...@@ -47,15 +47,15 @@ ...@@ -47,15 +47,15 @@
<true/> <true/>
</dict> </dict>
<key>NSAppleMusicUsageDescription</key> <key>NSAppleMusicUsageDescription</key>
<string>紫荆数智学堂需要访问媒体</string> <string>清控紫荆数智学堂需要访问媒体</string>
<key>NSCameraUsageDescription</key> <key>NSCameraUsageDescription</key>
<string>紫荆数智学堂需要访问相机</string> <string>清控紫荆数智学堂需要访问相机</string>
<key>NSMicrophoneUsageDescription</key> <key>NSMicrophoneUsageDescription</key>
<string>紫荆数智学堂需要访问麦克风</string> <string>清控紫荆数智学堂需要访问麦克风</string>
<key>NSPhotoLibraryUsageDescription</key> <key>NSPhotoLibraryUsageDescription</key>
<string>紫荆数智学堂需要访问照片</string> <string>清控紫荆数智学堂需要访问照片</string>
<key>NSSpeechRecognitionUsageDescription</key> <key>NSSpeechRecognitionUsageDescription</key>
<string>紫荆数智学堂需要语言识别</string> <string>清控紫荆数智学堂需要语言识别</string>
<key>UIApplicationSupportsIndirectInputEvents</key> <key>UIApplicationSupportsIndirectInputEvents</key>
<true/> <true/>
<key>UILaunchStoryboardName</key> <key>UILaunchStoryboardName</key>
......
...@@ -18,13 +18,6 @@ class Global { ...@@ -18,13 +18,6 @@ class Global {
await SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]); await SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
// 初始化数据库 // 初始化数据库
SqlManager.init(); SqlManager.init();
// 检测网络变化
Connectivity().onConnectivityChanged.listen((ConnectivityResult result) {
Console.log('网络变化--------------------------------$result');
if (result != ConnectivityResult.none && UserStore.to.isLogin) {
upload();
}
});
// 监测app生命周期 // 监测app生命周期
// WidgetsBinding.instance?.addObserver(AppLifecycleObserver()); // WidgetsBinding.instance?.addObserver(AppLifecycleObserver());
...@@ -32,12 +25,20 @@ class Global { ...@@ -32,12 +25,20 @@ class Global {
// 配置存储 // 配置存储
Get.putAsync<StorageService>(() => StorageService().init()), Get.putAsync<StorageService>(() => StorageService().init()),
]).whenComplete(() { ]).whenComplete(() {
// 先注册依赖最广的用户状态,避免启动早期被其他模块提前读取。
Get.put<UserStore>(UserStore());
// 网络 // 网络
Get.put<HttpService>(HttpService()); Get.put<HttpService>(HttpService());
//配置基本设置 //配置基本设置
Get.put<ConfigStore>(ConfigStore()); Get.put<ConfigStore>(ConfigStore());
// });
Get.put<UserStore>(UserStore());
// UserStore 注册后再监听网络变化,避免回调触发时找不到实例。
Connectivity().onConnectivityChanged.listen((ConnectivityResult result) {
Console.log('网络变化--------------------------------$result');
if (result != ConnectivityResult.none && UserStore.to.isLogin) {
upload();
}
}); });
} }
......
...@@ -6,7 +6,6 @@ import 'package:flutter_book/routes/index.dart'; ...@@ -6,7 +6,6 @@ import 'package:flutter_book/routes/index.dart';
import 'package:flutter_book/store/index.dart'; import 'package:flutter_book/store/index.dart';
import 'package:flutter_book/theme.dart'; import 'package:flutter_book/theme.dart';
import 'package:flutter_book/widgets/index.dart'; import 'package:flutter_book/widgets/index.dart';
import 'package:flutter_bugly/flutter_bugly.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:oktoast/oktoast.dart'; import 'package:oktoast/oktoast.dart';
...@@ -19,17 +18,9 @@ void main() { ...@@ -19,17 +18,9 @@ void main() {
Future.wait([ Future.wait([
UserStore.to.profile(), UserStore.to.profile(),
]).whenComplete(() { ]).whenComplete(() {
FlutterBugly.postCatchedException(() {
// 如果需要 ensureInitialized,请在这里运行。 // 如果需要 ensureInitialized,请在这里运行。
WidgetsFlutterBinding.ensureInitialized(); WidgetsFlutterBinding.ensureInitialized();
runApp(const MyApp()); runApp(const MyApp());
FlutterBugly.init(
androidAppId: "8b4da96535",
iOSAppId: "290703a371",
);
});
// runApp(const MyApp());
//FlutterNativeSplash.remove();
}); });
}); });
SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle.light); SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle.light);
...@@ -46,7 +37,7 @@ class MyApp extends StatelessWidget { ...@@ -46,7 +37,7 @@ class MyApp extends StatelessWidget {
builder: (context, child) => GetBuilder<ConfigStore>( builder: (context, child) => GetBuilder<ConfigStore>(
builder: (config) => MaterialApp.router( builder: (config) => MaterialApp.router(
debugShowCheckedModeBanner: false, debugShowCheckedModeBanner: false,
title: '紫荆数智学堂', title: '清控紫荆数智学堂',
theme: AppTheme.light, theme: AppTheme.light,
darkTheme: AppTheme.dark, darkTheme: AppTheme.dark,
themeMode: ThemeMode.light, themeMode: ThemeMode.light,
......
...@@ -116,12 +116,114 @@ class LoginController extends GetxController { ...@@ -116,12 +116,114 @@ class LoginController extends GetxController {
update(); update();
} }
/// 显示用户协议弹框
Future<bool> _showAgreementDialog(BuildContext context) async {
await showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8.0.w),
),
contentPadding: EdgeInsets.zero,
title: Center(
child: Padding(
padding: EdgeInsets.only(top: 24.w),
child: Text(
'用户协议及隐私协议',
style: TextStyle(
fontSize: 16.w,
fontWeight: Fonts.medium,
color: Colours.c3,
),
),
),
),
content: Wrap(
children: [
Container(
margin: EdgeInsets.only(top: 20.w, bottom: 29.w),
padding: EdgeInsets.symmetric(horizontal: 20.w),
child: Center(
child: Text(
'已阅读并同意《用户协议》、《隐私政策》',
style: TextStyle(
fontSize: 14.w,
color: Colours.c6,
),
textAlign: TextAlign.center,
),
),
),
Container(
height: 1.w,
width: double.infinity,
color: Colours.cLine,
),
],
),
actionsPadding: EdgeInsets.zero,
actions: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
GestureDetector(
onTap: () => Navigator.of(context).pop(),
child: Container(
width: 105.w,
height: 39.5.w,
color: Colours.cFF,
alignment: Alignment.center,
child: Text(
'不同意',
style: TextStyle(
fontSize: 15.w,
fontWeight: Fonts.medium,
color: Colours.c6,
),
),
),
),
Container(
height: 39.5.w,
width: 1,
color: Colours.cLine,
),
GestureDetector(
onTap: () {
Navigator.of(context).pop();
setAgree();
},
child: Container(
width: 105.w,
height: 39.5.w,
color: Colours.cFF,
alignment: Alignment.center,
child: Text(
'同意',
style: TextStyle(
fontSize: 15.w,
fontWeight: Fonts.boldSemi,
color: Colours.cAB1941,
),
),
),
),
],
),
],
);
},
);
return agree;
}
/// 登录 /// 登录
void onLogin(BuildContext context) async { void onLogin(BuildContext context) async {
Tools.unfocus(); Tools.unfocus();
if (!agree) { if (!agree) {
Toast.show('请先阅读并同意《用户协议》和《隐私政策》'); await _showAgreementDialog(context);
return; if (!agree) return;
} }
String type = '1'; String type = '1';
...@@ -163,8 +265,8 @@ class LoginController extends GetxController { ...@@ -163,8 +265,8 @@ class LoginController extends GetxController {
/// 发送验证码 /// 发送验证码
void sendCode() async { void sendCode() async {
if (!agree) { if (!agree) {
Toast.show('请先阅读并同意《用户协议》和《隐私政策》'); await _showAgreementDialog(Get.context!);
return; if (!agree) return;
} }
final result = final result =
await AccountAPI.sendCode(phone: phoneInput.text, type: 'login'); await AccountAPI.sendCode(phone: phoneInput.text, type: 'login');
......
...@@ -215,13 +215,13 @@ class _LoginPageState extends State<LoginPage> { ...@@ -215,13 +215,13 @@ class _LoginPageState extends State<LoginPage> {
GestureDetector( GestureDetector(
child: Text('《用户协议》',style: TextStyle(color: Colours.cBlue,fontSize:14.w,height: 1.4)), child: Text('《用户协议》',style: TextStyle(color: Colours.cBlue,fontSize:14.w,height: 1.4)),
onTap: (){ onTap: (){
context.pushNamed(Routes.terms,queryParameters: {'url':'$kServerUrl$kUserAgreement','title':'用户协议'}); context.pushNamed(Routes.terms,queryParameters: {'url':kUserAgreement,'title':'用户协议'});
}, },
), ),
GestureDetector( GestureDetector(
child: Text('《隐私政策》',style: TextStyle(color: Colours.cBlue,fontSize:14.w,height: 1.4)), child: Text('《隐私政策》',style: TextStyle(color: Colours.cBlue,fontSize:14.w,height: 1.4)),
onTap: (){ onTap: (){
context.pushNamed(Routes.terms,queryParameters: {'url':'$kServerUrl$kUserPriAgreement','title':'隐私政策'}); context.pushNamed(Routes.terms,queryParameters: {'url':kUserPriAgreement,'title':'隐私政策'});
}, },
), ),
], ],
......
part of mine; part of mine;
class MinePage extends StatefulWidget { class MinePage extends StatefulWidget {
const MinePage({Key? key}) : super(key: key); const MinePage({Key? key}) : super(key: key);
...@@ -13,7 +12,7 @@ class _MinePageState extends State<MinePage> { ...@@ -13,7 +12,7 @@ class _MinePageState extends State<MinePage> {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return GetBuilder<MineController>( return GetBuilder<MineController>(
init: MineController(), init: MineController(),
builder:(controller) => Stack( builder: (controller) => Stack(
children: [ children: [
Image.asset( Image.asset(
'assets/images/mine_bg.png', 'assets/images/mine_bg.png',
...@@ -21,7 +20,7 @@ class _MinePageState extends State<MinePage> { ...@@ -21,7 +20,7 @@ class _MinePageState extends State<MinePage> {
width: double.infinity, width: double.infinity,
), ),
Scaffold( Scaffold(
backgroundColor:Colors.transparent, backgroundColor: Colors.transparent,
appBar: CustomAppBar( appBar: CustomAppBar(
backgroundColor: Colors.transparent, backgroundColor: Colors.transparent,
actions: [ actions: [
...@@ -42,15 +41,21 @@ class _MinePageState extends State<MinePage> { ...@@ -42,15 +41,21 @@ class _MinePageState extends State<MinePage> {
onPressed: () => context.pushNamed(Routes.set), onPressed: () => context.pushNamed(Routes.set),
), ),
GestureDetector( GestureDetector(
onTap: () async{ onTap: () async {
context.pushNamed(Routes.msgs).then((value) { context.pushNamed(Routes.msgs).then((value) {
controller.getNums(); controller.getNums();
}); });
}, },
child: badges.Badge( child: badges.Badge(
position: badges.BadgePosition.topEnd(top: -5.w, end: 0), position: badges.BadgePosition.topEnd(top: -5.w, end: 0),
showBadge: controller.num == 0?false:true, showBadge: controller.num == 0 ? false : true,
badgeContent: Text(controller.num.toString(),style: TextStyle(fontSize: 9.w,color: Colors.white,fontWeight: Fonts.bold),), badgeContent: Text(
controller.num.toString(),
style: TextStyle(
fontSize: 9.w,
color: Colors.white,
fontWeight: Fonts.bold),
),
badgeStyle: const badges.BadgeStyle( badgeStyle: const badges.BadgeStyle(
badgeColor: AppTheme.primary, badgeColor: AppTheme.primary,
shape: badges.BadgeShape.circle, shape: badges.BadgeShape.circle,
...@@ -75,39 +80,52 @@ class _MinePageState extends State<MinePage> { ...@@ -75,39 +80,52 @@ class _MinePageState extends State<MinePage> {
children: [ children: [
Container( Container(
margin: EdgeInsets.symmetric(horizontal: 10.w), margin: EdgeInsets.symmetric(horizontal: 10.w),
child: BuildUser(userInfo:controller.userInfo,onTap: () async{ child: BuildUser(
context.pushNamed(Routes.userInfo,extra: controller.userInfo).then((value){ userInfo: controller.userInfo,
onTap: () async {
context
.pushNamed(Routes.userInfo,
extra: controller.userInfo)
.then((value) {
controller.getInfo(); controller.getInfo();
}); });
},), },
),
), ),
Gaps.vGaps10, Gaps.vGaps10,
Container( Container(
margin: EdgeInsets.symmetric(horizontal: 2.2.w), margin: EdgeInsets.symmetric(horizontal: 2.2.w),
child: BuildRead(items: controller.reads,onTap: (ReadModel model) async{ child: BuildRead(
context.pushNamed(model.link??'').then((value){ items: controller.reads,
onTap: (ReadModel model) async {
context.pushNamed(model.link ?? '').then((value) {
controller.getInfo(); controller.getInfo();
}); });
}), }),
), ),
controller.ads.isNotEmpty?Gaps.vGaps5:const SizedBox(), controller.ads.isNotEmpty ? Gaps.vGaps5 : const SizedBox(),
controller.ads.isNotEmpty? controller.ads.isNotEmpty
Container( ? Container(
color: Colors.transparent, color: Colors.transparent,
padding: EdgeInsets.symmetric(horizontal: 10.w), padding: EdgeInsets.symmetric(horizontal: 10.w),
child: BuildBanner( child: BuildBanner(
items:controller.ads, items: controller.ads,
onTap:(adModel){ onTap: (adModel) {
context.pushNamed(Routes.adDetail,extra: adModel); context.pushNamed(Routes.adDetail,
} , extra: adModel);
), },
):const SizedBox(), ),
controller.ads.isNotEmpty?Gaps.vGaps15:Gaps.vGaps5, )
BuildAccount(items:controller.accounts,onTap: (ReadModel model) async{ : const SizedBox(),
context.pushNamed(model.link??'').then((value){ controller.ads.isNotEmpty ? Gaps.vGaps15 : Gaps.vGaps5,
BuildAccount(
items: controller.accounts,
onTap: (ReadModel model) async {
context.pushNamed(model.link ?? '').then((value) {
controller.getInfo(); controller.getInfo();
}); });
},), },
),
Gaps.vGaps10, Gaps.vGaps10,
Container( Container(
margin: EdgeInsets.symmetric(horizontal: AppTheme.margin), margin: EdgeInsets.symmetric(horizontal: AppTheme.margin),
...@@ -128,31 +146,56 @@ class _MinePageState extends State<MinePage> { ...@@ -128,31 +146,56 @@ class _MinePageState extends State<MinePage> {
child: Column( child: Column(
children: [ children: [
GestureDetector( GestureDetector(
onTap:() async { onTap: () async {
context.pushNamed(Routes.security,extra: controller.userInfo).then((value){ context
.pushNamed(Routes.security,
extra: controller.userInfo)
.then((value) {
controller.getInfo(); controller.getInfo();
}); });
}, child: _buildItem('账户安全') },
child: _buildItem('账户安全')),
Container(
color: Colours.cLine,
margin: EdgeInsets.symmetric(horizontal: 15.w),
height: 1.w,
), ),
Container(color: Colours.cLine,margin: EdgeInsets.symmetric(horizontal: 15.w),height: 1.w,),
// _buildItem('意见反馈'), // _buildItem('意见反馈'),
GestureDetector( GestureDetector(
onTap:(){ onTap: () {
context.pushNamed(Routes.feedback); context.pushNamed(Routes.feedback);
}, child: _buildItem('意见反馈') },
child: _buildItem('意见反馈')),
Container(
color: Colours.cLine,
margin: EdgeInsets.symmetric(horizontal: 15.w),
height: 1.w,
), ),
Container(color: Colours.cLine,margin: EdgeInsets.symmetric(horizontal: 15.w),height: 1.w,),
GestureDetector( GestureDetector(
onTap: (){ onTap: () {
context.pushNamed(Routes.helpCenter); context.pushNamed(Routes.helpCenter);
}, child: _buildItem('帮助中心',) },
child: _buildItem(
'帮助中心',
)),
Container(
color: Colours.cLine,
margin: EdgeInsets.symmetric(horizontal: 15.w),
height: 1.w,
), ),
Container(color: Colours.cLine,margin: EdgeInsets.symmetric(horizontal: 15.w),height: 1.w,),
GestureDetector( GestureDetector(
onTap: (){ onTap: () {
context.pushNamed(Routes.about); context.pushNamed(Routes.about);
}, child: _buildItem('关于我们',) },
child: _buildItem(
'关于我们',
)),
Container(
color: Colours.cLine,
margin: EdgeInsets.symmetric(horizontal: 15.w),
height: 1.w,
), ),
_buildContactItem(),
], ],
), ),
), ),
...@@ -169,14 +212,20 @@ class _MinePageState extends State<MinePage> { ...@@ -169,14 +212,20 @@ class _MinePageState extends State<MinePage> {
Widget _buildItem(String title) { Widget _buildItem(String title) {
return Container( return Container(
padding: EdgeInsets.only(left: 18.w,right: 15.w), padding: EdgeInsets.only(left: 18.w, right: 15.w),
color: Colors.white, color: Colors.white,
height: 42.w, height: 42.w,
child: Row( child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center,
children: [ children: [
Text(title,style: TextStyle(fontSize: 14.w,color: Colours.c3,),), Text(
title,
style: TextStyle(
fontSize: 14.w,
color: Colours.c3,
),
),
SizedBox( SizedBox(
width: 5.w, width: 5.w,
height: 8.w, height: 8.w,
...@@ -187,4 +236,20 @@ class _MinePageState extends State<MinePage> { ...@@ -187,4 +236,20 @@ class _MinePageState extends State<MinePage> {
); );
} }
Widget _buildContactItem() {
return Container(
padding: EdgeInsets.only(left: 18.w, right: 15.w),
color: Colors.white,
height: 42.w,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text('联系电话', style: TextStyle(fontSize: 14.w, color: Colours.c3)),
Text('010-62793909',
style: TextStyle(fontSize: 14.w, color: Colours.c3)),
],
),
);
}
} }
...@@ -6,37 +6,45 @@ class ReadPage extends StatefulWidget { ...@@ -6,37 +6,45 @@ class ReadPage extends StatefulWidget {
final String chapterName; final String chapterName;
final String noteId; final String noteId;
final BookDetailModel bookDetailModel; final BookDetailModel bookDetailModel;
const ReadPage({ const ReadPage(
Key? key, {Key? key,
required this.bookId, required this.bookId,
required this.chapterId, required this.chapterId,
required this.chapterName, required this.chapterName,
required this.bookDetailModel, required this.bookDetailModel,
required this.noteId required this.noteId})
}) : super(key: key); : super(key: key);
@override @override
State<ReadPage> createState() => _ReadPageState(); State<ReadPage> createState() => _ReadPageState();
} }
class _ReadPageState extends State<ReadPage> { class _ReadPageState extends State<ReadPage> {
@override @override
void initState() { void initState() {
super.initState(); super.initState();
} }
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return GetBuilder( return GetBuilder(
init: ReadController(bookId: widget.bookId, chapterId: widget.chapterId,chapterName: widget.chapterName,bookDetailModel: widget.bookDetailModel,noteId: widget.noteId), init: ReadController(
bookId: widget.bookId,
chapterId: widget.chapterId,
chapterName: widget.chapterName,
bookDetailModel: widget.bookDetailModel,
noteId: widget.noteId),
builder: (readController) => WillPopScope( builder: (readController) => WillPopScope(
onWillPop: () async { onWillPop: () async {
PopBackModel backModel = PopBackModel(chapterId: readController.chapterId,back: true,chapterName: readController.chapterId); PopBackModel backModel = PopBackModel(
chapterId: readController.chapterId,
back: true,
chapterName: readController.chapterId);
context.pop(backModel); context.pop(backModel);
CustomToast.dismiss(); CustomToast.dismiss();
return false; return false;
}, },
child:Scaffold( child: Scaffold(
appBar: CustomAppBar( appBar: CustomAppBar(
titleSpacing: 0, titleSpacing: 0,
title: Align( title: Align(
...@@ -44,65 +52,72 @@ class _ReadPageState extends State<ReadPage> { ...@@ -44,65 +52,72 @@ class _ReadPageState extends State<ReadPage> {
child: Text(readController.chapterName), child: Text(readController.chapterName),
), ),
centerTitle: false, centerTitle: false,
actions: [ // actions: [
GestureDetector( // GestureDetector(
onTap: () { // onTap: () {
readController.getBookDown(); // readController.getBookDown();
}, // },
child: Text( // child: Text(
readController.existDownFile == true?'':'离线阅读', // readController.existDownFile == true ? '' : '离线阅读',
style: TextStyle( // style: TextStyle(fontSize: 14.w, color: Colours.c3),
fontSize: 14.w, color: Colours.c3), // ))
)) // ],
],
), ),
resizeToAvoidBottomInset: false, resizeToAvoidBottomInset: false,
floatingActionButton: readController.show&& !readController.toolModel.selected?GestureDetector( floatingActionButton:
onTap: (){ readController.show && !readController.toolModel.selected
? GestureDetector(
onTap: () {
readController.setShowChat(true); readController.setShowChat(true);
readController.setChatType(0); readController.setChatType(0);
}, },
child: Image.asset('assets/images/chat.png'), child: Image.asset('assets/images/chat.png'),
):null, )
: null,
// floatingActionButtonAnimator: const NoAnimationFabAnimator(), // floatingActionButtonAnimator: const NoAnimationFabAnimator(),
floatingActionButtonLocation:MyFloatingActionButtonLocation(), floatingActionButtonLocation: MyFloatingActionButtonLocation(),
body: Container( body: Container(
color: Colors.white, color: Colors.white,
child: Stack( child: Stack(
children: [ children: [
InAppWebView( InAppWebView(
initialFile: readController.existDownFile && !readController.netStatus?'assets/html/read_unline.html':'assets/html/read.html', initialFile:
readController.existDownFile && !readController.netStatus
? 'assets/html/read_unline.html'
: 'assets/html/read.html',
// initialUrlRequest:URLRequest( // initialUrlRequest:URLRequest(
// url:WebUri.uri(Uri.parse(kReadTestUnderLineBook)) // url:WebUri.uri(Uri.parse(kReadTestUnderLineBook))
// // url: readController.existDownFile && !readController.netStatus? WebUri.uri(Uri.parse(kReadTestUnderLineBook)): WebUri.uri(Uri.parse(kReadBook)) // // url: readController.existDownFile && !readController.netStatus? WebUri.uri(Uri.parse(kReadTestUnderLineBook)): WebUri.uri(Uri.parse(kReadBook))
// ), // ),
initialSettings:InAppWebViewSettings( initialSettings: InAppWebViewSettings(
clearCache:true, clearCache: true,
// http的请求也不做限制 // http的请求也不做限制
mixedContentMode:MixedContentMode.MIXED_CONTENT_ALWAYS_ALLOW mixedContentMode:
), MixedContentMode.MIXED_CONTENT_ALWAYS_ALLOW),
contextMenu: ContextMenu( contextMenu: ContextMenu(
settings: ContextMenuSettings( settings: ContextMenuSettings(
hideDefaultSystemContextMenuItems: true, hideDefaultSystemContextMenuItems: true,
) )),
), onWebViewCreated: (InAppWebViewController controller) {
onWebViewCreated: (InAppWebViewController controller){
// CustomToast.loading(); // CustomToast.loading();
readController.webViewController = controller; readController.webViewController = controller;
}, },
onConsoleMessage: (controller, consoleMessage) { onConsoleMessage: (controller, consoleMessage) {
// 接收从 WebView 发送的消息 // 接收从 WebView 发送的消息
Console.log("Received message from WebView-----------------------------: ${consoleMessage.message}"); Console.log(
"Received message from WebView-----------------------------: ${consoleMessage.message}");
}, },
onLoadStop: (controller, url) { onLoadStop: (controller, url) {
if(readController.existDownFile && !readController.netStatus){ if (readController.existDownFile &&
!readController.netStatus) {
Console.log('-----------------加载离线数据---------------'); Console.log('-----------------加载离线数据---------------');
readController.getOffLineInfo(); readController.getOffLineInfo();
} } else {
else { String str =
String str = '$kServerUrl,${readController.bookId},${readController.chapterId},${UserStore.to.token},${readController.noteId},${readController.sModel.bookId =='0'?'':readController.sModel.combinedContent}'; '$kServerUrl,${readController.bookId},${readController.chapterId},${UserStore.to.token},${readController.noteId},${readController.sModel.bookId == '0' ? '' : readController.sModel.combinedContent}';
Console.log('-----------------加载在线数据---------------$str'); Console.log('-----------------加载在线数据---------------$str');
controller.evaluateJavascript(source: 'callbackInFlutterComponent("$str");'); controller.evaluateJavascript(
source: 'callbackInFlutterComponent("$str");');
} }
// 添加单击事件 // 添加单击事件
...@@ -112,14 +127,18 @@ class _ReadPageState extends State<ReadPage> { ...@@ -112,14 +127,18 @@ class _ReadPageState extends State<ReadPage> {
}); });
'''); ''');
// 监听js单击回调 // 监听js单击回调
controller.addJavaScriptHandler(handlerName: 'onTap', callback: (args){ controller.addJavaScriptHandler(
handlerName: 'onTap',
callback: (args) {
readController.setShow(readController.show); readController.setShow(readController.show);
}); });
// 监听笔记回调 // 监听笔记回调
controller.addJavaScriptHandler(handlerName: 'noteCallBack', callback: (args){ controller.addJavaScriptHandler(
Console.log('监听笔记回调------------------------------------------------$args'); handlerName: 'noteCallBack',
callback: (args) {
Console.log(
'监听笔记回调------------------------------------------------$args');
readController.noteTitle = args.first; readController.noteTitle = args.first;
readController.setShowChat(true); readController.setShowChat(true);
readController.setChatType(1); readController.setChatType(1);
...@@ -127,34 +146,51 @@ class _ReadPageState extends State<ReadPage> { ...@@ -127,34 +146,51 @@ class _ReadPageState extends State<ReadPage> {
}); });
// 监听百科回调 // 监听百科回调
controller.addJavaScriptHandler(handlerName: 'baikeCallBack', callback: (args){ controller.addJavaScriptHandler(
Console.log('监听百科回调------------------------------------------------$args'); handlerName: 'baikeCallBack',
context.pushNamed(Routes.baiKe,queryParameters: {'keyword':args.first}); callback: (args) {
Console.log(
'监听百科回调------------------------------------------------$args');
context.pushNamed(Routes.baiKe,
queryParameters: {'keyword': args.first});
}); });
// 监听字典回调 // 监听字典回调
controller.addJavaScriptHandler(handlerName: 'dictCallBack', callback: (args){ controller.addJavaScriptHandler(
Console.log('监听字典回调------------------------------------------------$args'); handlerName: 'dictCallBack',
context.pushNamed(Routes.baiDict,queryParameters: {'keyword':args.first}); callback: (args) {
Console.log(
'监听字典回调------------------------------------------------$args');
context.pushNamed(Routes.baiDict,
queryParameters: {'keyword': args.first});
}); });
// 监听朗读回调 // 监听朗读回调
controller.addJavaScriptHandler(handlerName: 'readCallBack', callback: (args){ controller.addJavaScriptHandler(
Console.log('监听朗读回调------------------------------------------------$args'); handlerName: 'readCallBack',
callback: (args) {
Console.log(
'监听朗读回调------------------------------------------------$args');
readController.speak(args.first.toString()); readController.speak(args.first.toString());
}); });
// 监听讨论回调 // 监听讨论回调
controller.addJavaScriptHandler(handlerName: 'discussCallBack', callback: (args){ controller.addJavaScriptHandler(
Console.log('监听讨论回调------------------------------------------------$args'); handlerName: 'discussCallBack',
callback: (args) {
Console.log(
'监听讨论回调------------------------------------------------$args');
readController.setShowChat(true); readController.setShowChat(true);
readController.setChatType(0); readController.setChatType(0);
readController.noteTitle = args.first.toString(); readController.noteTitle = args.first.toString();
}); });
// 答题和答题结果页回调 // 答题和答题结果页回调
controller.addJavaScriptHandler(handlerName: 'answerResultCallBack', callback: (args){ controller.addJavaScriptHandler(
Console.log('监听答题回调------------------------------------------------$args'); handlerName: 'answerResultCallBack',
callback: (args) {
Console.log(
'监听答题回调------------------------------------------------$args');
String chapterId = args.first[0].toString(); String chapterId = args.first[0].toString();
String position = args.first[1].toString(); String position = args.first[1].toString();
...@@ -164,37 +200,42 @@ class _ReadPageState extends State<ReadPage> { ...@@ -164,37 +200,42 @@ class _ReadPageState extends State<ReadPage> {
String title = args.first[3].toString(); String title = args.first[3].toString();
String url = ''; String url = '';
// 未答题 // 未答题
if(type == '0'){ if (type == '0') {
url = kAnswer; url = kAnswer;
} } else {
else {
url = kAnswerResult; url = kAnswerResult;
} }
Map<String,String> params = { Map<String, String> params = {
'chapter_id':chapterId, 'chapter_id': chapterId,
'position':position, 'position': position,
'url':url, 'url': url,
'book_id':readController.bookId, 'book_id': readController.bookId,
'token':UserStore.to.token, 'token': UserStore.to.token,
'title':title 'title': title
}; };
Console.log('监听答题回调---------------给页面传参---------------------------------$params'); Console.log(
'监听答题回调---------------给页面传参---------------------------------$params');
// 跳转知识测评界面 // 跳转知识测评界面
context.pushNamed(Routes.answer,queryParameters: params); context.pushNamed(Routes.answer,
queryParameters: params);
}); });
// 监听 上一节 下一节 // 监听 上一节 下一节
controller.addJavaScriptHandler(handlerName: 'loadChapterCallBack', callback: (args){ controller.addJavaScriptHandler(
Console.log('监听 上一节 下一节------------------------------------------------$args'); handlerName: 'loadChapterCallBack',
callback: (args) {
Console.log(
'监听 上一节 下一节------------------------------------------------$args');
String chapterId = args.first[0].toString(); String chapterId = args.first[0].toString();
String chapterName = args.first[1].toString(); String chapterName = args.first[1].toString();
ChapterModel chapterModel = ChapterModel(id: int.parse(chapterId), name: chapterName); ChapterModel chapterModel = ChapterModel(
id: int.parse(chapterId), name: chapterName);
// readController.setChapterInfo(id: chapterId, name: chapterName ?? ''); // readController.setChapterInfo(id: chapterId, name: chapterName ?? '');
readController.selectChapter(chapterModel); readController.selectChapter(chapterModel);
if(readController.existDownFile && !readController.netStatus){ if (readController.existDownFile &&
!readController.netStatus) {
String direction = ''; String direction = '';
if(args.first.length == 3){ if (args.first.length == 3) {
direction = args.first[2].toString(); direction = args.first[2].toString();
} }
readController.getOffLineInfo(direction: direction); readController.getOffLineInfo(direction: direction);
...@@ -207,33 +248,43 @@ class _ReadPageState extends State<ReadPage> { ...@@ -207,33 +248,43 @@ class _ReadPageState extends State<ReadPage> {
// }); // });
// 阅读页内容中的 外部链接 // 阅读页内容中的 外部链接
controller.addJavaScriptHandler(handlerName: 'openLinkCallback', callback: (args){ controller.addJavaScriptHandler(
Console.log('监听外部链接------------------------------------------------$args'); handlerName: 'openLinkCallback',
context.pushNamed(Routes.link,queryParameters: {'url': args.first.toString()}); callback: (args) {
Console.log(
'监听外部链接------------------------------------------------$args');
context.pushNamed(Routes.link,
queryParameters: {'url': args.first.toString()});
}); });
// 画廊 扩展于都 // 画廊 扩展于都
controller.addJavaScriptHandler(handlerName: 'readInfoCallback', callback: (args){ controller.addJavaScriptHandler(
handlerName: 'readInfoCallback',
callback: (args) {
String position = args.first[0].toString(); String position = args.first[0].toString();
String type = args.first[1].toString(); String type = args.first[1].toString();
String title = args.first[2].toString(); String title = args.first[2].toString();
Map<String,String> params = { Map<String, String> params = {
'chapter_id':readController.chapterId, 'chapter_id': readController.chapterId,
'position':position, 'position': position,
'book_id':readController.bookId, 'book_id': readController.bookId,
'token':UserStore.to.token, 'token': UserStore.to.token,
'title':title, 'title': title,
'base_url':kServerUrl, 'base_url': kServerUrl,
'type':type 'type': type
}; };
Console.log('监听画廊 扩展于都---------------给页面传参---------------------------------$params'); Console.log(
context.pushNamed(Routes.readInfo,queryParameters: params); '监听画廊 扩展于都---------------给页面传参---------------------------------$params');
context.pushNamed(Routes.readInfo,
queryParameters: params);
}); });
// 购买回调 // 购买回调
controller.addJavaScriptHandler(handlerName: 'payCallback', callback: (args){ controller.addJavaScriptHandler(
handlerName: 'payCallback',
callback: (args) {
List<CourseModel> buy = []; List<CourseModel> buy = [];
CourseModel model= CourseModel( CourseModel model = CourseModel(
bookId: readController.bookDetailModel.bookId, bookId: readController.bookDetailModel.bookId,
price: readController.bookDetailModel.price, price: readController.bookDetailModel.price,
vipPrice: readController.bookDetailModel.vipPrice, vipPrice: readController.bookDetailModel.vipPrice,
...@@ -241,100 +292,119 @@ class _ReadPageState extends State<ReadPage> { ...@@ -241,100 +292,119 @@ class _ReadPageState extends State<ReadPage> {
bookName: readController.bookDetailModel.bookName, bookName: readController.bookDetailModel.bookName,
cartId: 0, cartId: 0,
status: 1, status: 1,
selected: true selected: true);
);
buy.add(model); buy.add(model);
context.pushNamed(Routes.bookPay,extra: buy).then((value){ context
.pushNamed(Routes.bookPay, extra: buy)
.then((value) {
controller.reload(); controller.reload();
}); });
}); });
// 图片预览 // 图片预览
controller.addJavaScriptHandler(handlerName: 'scaleImageCallback', callback: (args){ controller.addJavaScriptHandler(
handlerName: 'scaleImageCallback',
callback: (args) {
String url = args.first[0].toString(); String url = args.first[0].toString();
String title = args.first[1].toString(); String title = args.first[1].toString();
Map<String,String> params = { Map<String, String> params = {
'url':url, 'url': url,
'title':title, 'title': title,
}; };
Console.log('监听图片预览---------------给页面传参---------------------------------$params'); Console.log(
context.pushNamed(Routes.scaleImage,queryParameters: params); '监听图片预览---------------给页面传参---------------------------------$params');
context.pushNamed(Routes.scaleImage,
queryParameters: params);
}); });
// 前端 token过期回调 // 前端 token过期回调
controller.addJavaScriptHandler(handlerName: 'refreshTokenCallback', callback: (args) async { controller.addJavaScriptHandler(
handlerName: 'refreshTokenCallback',
callback: (args) async {
Console.log('刷新token------------------------'); Console.log('刷新token------------------------');
final result = await readController.refreshToken(); final result = await readController.refreshToken();
Map<String, dynamic> param = { Map<String, dynamic> param = {
'token': result, 'token': result,
}; };
String jsonStr = jsonEncode(param); String jsonStr = jsonEncode(param);
Console.log('刷新token------------------------$jsonStr'); Console.log(
controller.evaluateJavascript(source: 'refreshTokenSuccess($jsonStr)'); '刷新token------------------------$jsonStr');
controller.evaluateJavascript(
source: 'refreshTokenSuccess($jsonStr)');
}); });
controller.addJavaScriptHandler(handlerName: 'showLoadingCallback', callback: (args) async { controller.addJavaScriptHandler(
handlerName: 'showLoadingCallback',
callback: (args) async {
CustomToast.loading(); CustomToast.loading();
}); });
controller.addJavaScriptHandler(handlerName: 'dismissLoadingCallback', callback: (args) async { controller.addJavaScriptHandler(
handlerName: 'dismissLoadingCallback',
callback: (args) async {
CustomToast.dismiss(); CustomToast.dismiss();
}); });
/// 离线需要参数 /// 离线需要参数
// 添加高亮划线笔记 // 添加高亮划线笔记
controller.addJavaScriptHandler(handlerName: 'offlineAddNoteCallBack', callback: (args){ controller.addJavaScriptHandler(
Console.log('添加笔记回调------------------------------------------${args[0]}'); handlerName: 'offlineAddNoteCallBack',
Map<String,dynamic> data = args[0]; callback: (args) {
Console.log(
'添加笔记回调------------------------------------------${args[0]}');
Map<String, dynamic> data = args[0];
readController.addLocalNote(data); readController.addLocalNote(data);
}); });
// 删除高亮划线笔记 // 删除高亮划线笔记
controller.addJavaScriptHandler(handlerName: 'offlineDelNoteCallBack', callback: (args){ controller.addJavaScriptHandler(
Console.log('删除笔记回调------------------------------------------${args[0]}'); handlerName: 'offlineDelNoteCallBack',
Map<String,dynamic> data = args[0]; callback: (args) {
Console.log(
'删除笔记回调------------------------------------------${args[0]}');
Map<String, dynamic> data = args[0];
int notesId = 0; int notesId = 0;
if (data['notes_id'].runtimeType == int) { if (data['notes_id'].runtimeType == int) {
notesId = data['notes_id']; notesId = data['notes_id'];
} } else if (data['notes_id'].runtimeType == String) {
else if (data['notes_id'].runtimeType == String){
notesId = int.parse(data['notes_id']); notesId = int.parse(data['notes_id']);
} }
int id = 0; int id = 0;
if(data.keys.contains('id')){ if (data.keys.contains('id')) {
// id = data['id']; // id = data['id'];
if (data['id'].runtimeType == int) { if (data['id'].runtimeType == int) {
id = data['id']; id = data['id'];
} } else if (data['id'].runtimeType == String) {
else if (data['id'].runtimeType == String){
id = int.parse(data['id']); id = int.parse(data['id']);
} }
} }
readController.delLocalNote(noteId: notesId,id: id); readController.delLocalNote(noteId: notesId, id: id);
}); });
// 更新高亮划线笔记 // 更新高亮划线笔记
controller.addJavaScriptHandler(handlerName: 'offlineUpdateNoteCallBack', callback: (args){ controller.addJavaScriptHandler(
Console.log('更新笔记回调------------------------------------------${args[0]}'); handlerName: 'offlineUpdateNoteCallBack',
callback: (args) {
Console.log(
'更新笔记回调------------------------------------------${args[0]}');
// int id = 0; // int id = 0;
// Map<String, dynamic> data = {}; // Map<String, dynamic> data = {};
Map<String,dynamic> data = args[0]; Map<String, dynamic> data = args[0];
int notesId = 0; int notesId = 0;
if (data['notes_id'].runtimeType == int) { if (data['notes_id'].runtimeType == int) {
notesId = data['notes_id']; notesId = data['notes_id'];
} } else if (data['notes_id'].runtimeType == String) {
else if (data['notes_id'].runtimeType == String){
notesId = int.parse(data['notes_id']); notesId = int.parse(data['notes_id']);
} }
int id = 0; int id = 0;
if(data.keys.contains('id')){ if (data.keys.contains('id')) {
if (data['id'].runtimeType == int) { if (data['id'].runtimeType == int) {
id = data['id']; id = data['id'];
} } else if (data['id'].runtimeType == String) {
else if (data['id'].runtimeType == String){
id = int.parse(data['id']); id = int.parse(data['id']);
} }
} }
readController.updateLocalNote(notesId: notesId,id:id, data: data); readController.updateLocalNote(
notesId: notesId, id: id, data: data);
}); });
}, },
), ),
...@@ -343,12 +413,13 @@ class _ReadPageState extends State<ReadPage> { ...@@ -343,12 +413,13 @@ class _ReadPageState extends State<ReadPage> {
right: 0, right: 0,
top: 0, top: 0,
bottom: 69, bottom: 69,
child: _showContent(readController,readController.toolModel) child:
), _showContent(readController, readController.toolModel)),
/// 底部工具栏布局 /// 底部工具栏布局
Visibility( Visibility(
visible: readController.show, visible: readController.show,
child:Positioned( child: Positioned(
left: 0, left: 0,
right: 0, right: 0,
bottom: 0, bottom: 0,
...@@ -358,11 +429,10 @@ class _ReadPageState extends State<ReadPage> { ...@@ -358,11 +429,10 @@ class _ReadPageState extends State<ReadPage> {
height: 69, height: 69,
color: Colors.limeAccent, color: Colors.limeAccent,
alignment: Alignment.center, alignment: Alignment.center,
child: _createToolBar(readController) child: _createToolBar(readController)),
),
),
)
), ),
)),
/// 悬浮按钮点击发起话题布局 /// 悬浮按钮点击发起话题布局
Visibility( Visibility(
visible: readController.showChat, visible: readController.showChat,
...@@ -370,12 +440,11 @@ class _ReadPageState extends State<ReadPage> { ...@@ -370,12 +440,11 @@ class _ReadPageState extends State<ReadPage> {
left: 0, left: 0,
right: 0, right: 0,
top: 0, top: 0,
bottom:0, bottom: 0,
child: GestureDetector( child: GestureDetector(
onTap: (){ onTap: () {
readController.setShowChat(false); readController.setShowChat(false);
readController.clearAllDiscussInput(); readController.clearAllDiscussInput();
}, },
child: Container( child: Container(
color: const Color(0xFF000000).withOpacity(0.5), color: const Color(0xFF000000).withOpacity(0.5),
...@@ -383,18 +452,20 @@ class _ReadPageState extends State<ReadPage> { ...@@ -383,18 +452,20 @@ class _ReadPageState extends State<ReadPage> {
reverse: true, reverse: true,
child: Container( child: Container(
color: Colors.white, color: Colors.white,
padding: EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom), padding: EdgeInsets.only(
bottom: MediaQuery.of(context)
.viewInsets
.bottom),
// alignment:Alignment.bottomCenter, // alignment:Alignment.bottomCenter,
child: GestureDetector( child: GestureDetector(
behavior: HitTestBehavior.opaque, behavior: HitTestBehavior.opaque,
onTap: (){}, onTap: () {},
child: ReadInputDiscuss(controller: readController,) child: ReadInputDiscuss(
) controller: readController,
))),
), ),
), ),
), )),
)
),
), ),
], ],
), ),
...@@ -402,17 +473,16 @@ class _ReadPageState extends State<ReadPage> { ...@@ -402,17 +473,16 @@ class _ReadPageState extends State<ReadPage> {
), ),
), ),
); );
} }
// 目录 笔记 讨论 工具栏 // 目录 笔记 讨论 工具栏
Widget _createToolBar(ReadController controller){ Widget _createToolBar(ReadController controller) {
return Row( return Row(
mainAxisAlignment: MainAxisAlignment.spaceAround, mainAxisAlignment: MainAxisAlignment.spaceAround,
children: controller.tools.map((model){ children: controller.tools.map((model) {
return Expanded( return Expanded(
child: GestureDetector( child: GestureDetector(
onTap: (){ onTap: () {
controller.chooseTool(model); controller.chooseTool(model);
}, },
child: Container( child: Container(
...@@ -425,36 +495,54 @@ class _ReadPageState extends State<ReadPage> { ...@@ -425,36 +495,54 @@ class _ReadPageState extends State<ReadPage> {
SizedBox( SizedBox(
width: 25, width: 25,
height: 25, height: 25,
child: Image.asset(model.selected?model.activeIcon:model.icon,fit: BoxFit.cover,) child: Image.asset(
model.selected ? model.activeIcon : model.icon,
fit: BoxFit.cover,
)),
SizedBox(
height: 2.5.w,
), ),
SizedBox(height: 2.5.w,), model.selected
model.selected?Text(model.name,style: TextStyle(fontSize: 12.w,height: 1.4,fontWeight: Fonts.boldSemi,color: AppTheme.primary),) ? Text(
:Text(model.name,style: TextStyle(fontSize: 12.w,height: 1.4,fontWeight: Fonts.medium,color: Colours.c6)) model.name,
style: TextStyle(
fontSize: 12.w,
height: 1.4,
fontWeight: Fonts.boldSemi,
color: AppTheme.primary),
)
: Text(model.name,
style: TextStyle(
fontSize: 12.w,
height: 1.4,
fontWeight: Fonts.medium,
color: Colours.c6))
], ],
), ),
), ),
), ),
); );
}).toList() }).toList());
);
} }
Widget detail(ReadController controller,ToolModel model){ Widget detail(ReadController controller, ToolModel model) {
if(model.tag == 0){ if (model.tag == 0) {
return ReadCategoryPage(controller: controller, return ReadCategoryPage(
controller: controller,
// 点 x 事件 // 点 x 事件
onTap: (){ onTap: () {
controller.chooseTool(model); controller.chooseTool(model);
}, },
// 点 搜索全部 列表 某一项 事件 // 点 搜索全部 列表 某一项 事件
onTapSearchItem: (SearchAllModel sModel){ onTapSearchItem: (SearchAllModel sModel) {
controller.chooseTool(model); controller.chooseTool(model);
// 加载阅读界面 参数:chapter_id text // 加载阅读界面 参数:chapter_id text
controller.sModel = sModel; controller.sModel = sModel;
controller.selectChapter(ChapterModel(id: sModel.chapterId,name: sModel.chapterName)); controller.selectChapter(
ChapterModel(id: sModel.chapterId, name: sModel.chapterName));
controller.webViewController.reload(); controller.webViewController.reload();
}, },
onTapChapter: (ChapterModel chapterModel){ onTapChapter: (ChapterModel chapterModel) {
// 配置选择的章节 // 配置选择的章节
controller.selectChapter(chapterModel); controller.selectChapter(chapterModel);
// 取消选中 tool // 取消选中 tool
...@@ -464,76 +552,78 @@ class _ReadPageState extends State<ReadPage> { ...@@ -464,76 +552,78 @@ class _ReadPageState extends State<ReadPage> {
// controller.setCurrentReadChapterId(); // controller.setCurrentReadChapterId();
}, },
); );
} } else if (model.tag == 1) {
else if(model.tag == 1){
return ReadNotePage( return ReadNotePage(
// 点 x 事件 // 点 x 事件
onTap: (){ onTap: () {
controller.chooseTool(model); controller.chooseTool(model);
}, },
// 点 搜索全部 列表 某一项 事件 // 点 搜索全部 列表 某一项 事件
onTapSearchItem: (SearchAllModel sModel){ onTapSearchItem: (SearchAllModel sModel) {
controller.chooseTool(model); controller.chooseTool(model);
// 重新加载阅读界面 参数:chapter_id text // 重新加载阅读界面 参数:chapter_id text
controller.sModel = sModel; controller.sModel = sModel;
controller.selectChapter(ChapterModel(id: sModel.chapterId,name: sModel.chapterName)); controller.selectChapter(
ChapterModel(id: sModel.chapterId, name: sModel.chapterName));
controller.webViewController.reload(); controller.webViewController.reload();
}, },
// 删除笔记后 重新刷新web页 // 删除笔记后 重新刷新web页
delTapCallBack: (){ delTapCallBack: () {
controller.webViewController.reload(); controller.webViewController.reload();
}, },
bookDetailModel: controller.bookDetailModel, bookDetailModel: controller.bookDetailModel,
chapterId: controller.chapterId, chapterId: controller.chapterId,
); );
} } else if (model.tag == 2) {
else if(model.tag == 2){
return ReadDiscussPage( return ReadDiscussPage(
// 点 x 事件 // 点 x 事件
onTap: (){ onTap: () {
controller.chooseTool(model); controller.chooseTool(model);
}, },
// 点 搜索全部 列表 某一项 事件 // 点 搜索全部 列表 某一项 事件
onTapSearchItem: (SearchAllModel sModel){ onTapSearchItem: (SearchAllModel sModel) {
controller.chooseTool(model); controller.chooseTool(model);
controller.sModel = sModel; controller.sModel = sModel;
// 重新加载阅读界面 参数:chapter_id text // 重新加载阅读界面 参数:chapter_id text
controller.selectChapter(ChapterModel(id: sModel.chapterId,name: sModel.chapterName)); controller.selectChapter(
ChapterModel(id: sModel.chapterId, name: sModel.chapterName));
controller.webViewController.reload(); controller.webViewController.reload();
}, },
bookDetailModel: controller.bookDetailModel, bookDetailModel: controller.bookDetailModel,
chapterId:controller.chapterId, chapterId: controller.chapterId,
); );
} }
return const SizedBox(); return const SizedBox();
} }
// 目录、评论、笔记 背景 // 目录、评论、笔记 背景
Widget _showContent(ReadController controller,ToolModel model) { Widget _showContent(ReadController controller, ToolModel model) {
if (controller.show){ if (controller.show) {
if(model.selected){ if (model.selected) {
return GestureDetector( return GestureDetector(
onTap: (){ onTap: () {
controller.chooseTool(model); controller.chooseTool(model);
}, },
child: Container( child: Container(
color: const Color(0xFF000000).withOpacity(0.5), color: const Color(0xFF000000).withOpacity(0.5),
padding: EdgeInsets.only(top: MediaQuery.of(context).size.height * 0.2), padding:
EdgeInsets.only(top: MediaQuery.of(context).size.height * 0.2),
child: ClipRRect( child: ClipRRect(
borderRadius: BorderRadius.only(topRight: Radius.circular(8.w),topLeft: Radius.circular(8.w)), borderRadius: BorderRadius.only(
topRight: Radius.circular(8.w),
topLeft: Radius.circular(8.w)),
child: Container( child: Container(
color: Colors.white, color: Colors.white,
child: GestureDetector( child: GestureDetector(
behavior: HitTestBehavior.opaque, behavior: HitTestBehavior.opaque,
onTap: (){}, onTap: () {},
child: detail(controller, model), child: detail(controller, model),
) )),
),
), ),
// child: ReadCategoryPage(), // child: ReadCategoryPage(),
), ),
); );
} } else {
else{
return const SizedBox(); return const SizedBox();
} }
} }
...@@ -541,18 +631,15 @@ class _ReadPageState extends State<ReadPage> { ...@@ -541,18 +631,15 @@ class _ReadPageState extends State<ReadPage> {
} }
} }
// 定制 悬浮按钮位置 // 定制 悬浮按钮位置
class MyFloatingActionButtonLocation extends FloatingActionButtonLocation { class MyFloatingActionButtonLocation extends FloatingActionButtonLocation {
@override @override
Offset getOffset(ScaffoldPrelayoutGeometry scaffoldGeometry) { Offset getOffset(ScaffoldPrelayoutGeometry scaffoldGeometry) {
// You can customize the position of the FloatingActionButton here // You can customize the position of the FloatingActionButton here
return Offset(scaffoldGeometry.scaffoldSize.width - 15.0.w - 45.w, scaffoldGeometry.scaffoldSize.height - 118.w-49.w); return Offset(scaffoldGeometry.scaffoldSize.width - 15.0.w - 45.w,
scaffoldGeometry.scaffoldSize.height - 118.w - 49.w);
} }
@override @override
String toString() => 'MyFloatingActionButtonLocation'; String toString() => 'MyFloatingActionButtonLocation';
} }
...@@ -192,8 +192,11 @@ class _ReadInputDiscussState extends State<ReadInputDiscuss> { ...@@ -192,8 +192,11 @@ class _ReadInputDiscussState extends State<ReadInputDiscuss> {
onTap: () async{ onTap: () async{
final assets = await AssetsPicker.image( final assets = await AssetsPicker.image(
context: context, context: context,
purpose: '用于从相册中选择图片添加到讨论中,仅用于上传和显示图片内容。',
); );
widget.controller.addDiscussInputImages(assets!.path); if (assets != null) {
widget.controller.addDiscussInputImages(assets.path);
}
}, },
child: SizedBox( child: SizedBox(
// color: Colors.red, // color: Colors.red,
......
library splash_page; library splash_page;
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_book/apis/index.dart'; import 'package:flutter_book/apis/index.dart';
import 'package:go_router/go_router.dart'; import 'package:go_router/go_router.dart';
import '../../routes/index.dart'; import '../../routes/index.dart';
import '../../services/index.dart';
import '../../utils/index.dart'; import '../../utils/index.dart';
part 'view.dart'; part 'view.dart';
...@@ -8,31 +8,135 @@ class SplashPage extends StatefulWidget { ...@@ -8,31 +8,135 @@ class SplashPage extends StatefulWidget {
} }
class _SplashPageState extends State<SplashPage> { class _SplashPageState extends State<SplashPage> {
bool _navigated = false;
@override @override
void initState() { void initState() {
super.initState(); super.initState();
Future.wait([ WidgetsBinding.instance.addPostFrameCallback((_) {
Future.delayed(const Duration(seconds: 2)) _startLaunchFlow();
]).whenComplete(() async { });
}
Future<void> _startLaunchFlow() async {
await _showPrivacyNoticeIfNeeded();
if (!mounted || _navigated) return;
await Future.delayed(const Duration(seconds: 2));
if (!mounted || _navigated) return;
final netStatus = await Tools.checkCurrentNetStatus(); final netStatus = await Tools.checkCurrentNetStatus();
if (netStatus){ if (!mounted || _navigated) return;
if (netStatus) {
final ads = await CommonAPI.list(type: '1'); final ads = await CommonAPI.list(type: '1');
if (!mounted || _navigated) return;
if (ads.isNotEmpty) { if (ads.isNotEmpty) {
context.pushReplacementNamed(Routes.ad,extra: ads); _navigated = true;
} context.pushReplacementNamed(Routes.ad, extra: ads);
else { return;
context.pushReplacementNamed(Routes.main);
} }
} }
else {
_navigated = true;
context.pushReplacementNamed(Routes.main); context.pushReplacementNamed(Routes.main);
} }
}); Future<void> _showPrivacyNoticeIfNeeded() async {
if (StorageService.to.getBool(kLocalPrivacyNoticeShown)) {
return;
}
await showDialog<void>(
context: context,
barrierDismissible: false,
builder: (dialogContext) {
return AlertDialog(
scrollable: true,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12),
),
title: const Text(
'隐私声明',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.w600,
color: Colours.c3,
),
),
content: SingleChildScrollView(
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
RichText(
text: TextSpan(
style: const TextStyle(
fontSize: 14,
height: 1.6,
color: Colours.c6,
),
children: [
const TextSpan(
text: '欢迎使用清控紫荆数智学堂。为保障你的个人信息安全,我们会按照',
),
TextSpan(
text: '《用户协议》',
style: const TextStyle(color: Color(0xFF2A82D9)),
recognizer: TapGestureRecognizer()
..onTap = () {
context.pushNamed(
Routes.terms,
queryParameters: {
'url': kUserAgreement,
'title': '用户协议',
},
);
},
),
const TextSpan(text: '和'),
TextSpan(
text: '《隐私政策》',
style: const TextStyle(color: Color(0xFF2A82D9)),
recognizer: TapGestureRecognizer()
..onTap = () {
context.pushNamed(
Routes.terms,
queryParameters: {
'url': kUserPriAgreement,
'title': '隐私政策',
},
);
},
),
const TextSpan(
text: '处理账号信息、设备信息、学习记录等内容。',
),
],
),
),
],
),
),
actions: [
SizedBox(
width: double.infinity,
child: TextButton(
onPressed: () async {
await StorageService.to
.setBool(kLocalPrivacyNoticeShown, true);
if (dialogContext.mounted) {
Navigator.of(dialogContext).pop();
}
},
child: const Text('我知道了'),
),
),
],
);
},
);
} }
@override @override
...@@ -43,7 +147,10 @@ class _SplashPageState extends State<SplashPage> { ...@@ -43,7 +147,10 @@ class _SplashPageState extends State<SplashPage> {
body: SizedBox( body: SizedBox(
height: double.infinity, height: double.infinity,
width: double.infinity, width: double.infinity,
child: Image.asset('assets/images/splash.png',fit: BoxFit.cover,), child: Image.asset(
'assets/images/splash.png',
fit: BoxFit.cover,
),
) )
// const Column( // const Column(
// crossAxisAlignment: CrossAxisAlignment.stretch, // crossAxisAlignment: CrossAxisAlignment.stretch,
...@@ -57,7 +164,7 @@ class _SplashPageState extends State<SplashPage> { ...@@ -57,7 +164,7 @@ class _SplashPageState extends State<SplashPage> {
// url: 'assets/images/logo.png', // url: 'assets/images/logo.png',
// fit: BoxFit.contain, // fit: BoxFit.contain,
// ), // ),
// title: Text('紫荆数智学堂'), // title: Text('清控紫荆数智学堂'),
// ), // ),
// ) // )
// ), // ),
......
...@@ -44,9 +44,16 @@ class _AboutPageState extends State<AboutPage> { ...@@ -44,9 +44,16 @@ class _AboutPageState extends State<AboutPage> {
child: const CustomImage.asset(url: 'assets/images/icon.png'), child: const CustomImage.asset(url: 'assets/images/icon.png'),
), ),
Gaps.vGaps15, Gaps.vGaps15,
Text('紫荆数智学堂',style: TextStyle(fontSize: 17.w,fontWeight: Fonts.medium,color: Colours.c3),), Text(
'清控紫荆数智学堂',
style: TextStyle(
fontSize: 17.w,
fontWeight: Fonts.medium,
color: Colours.c3),
),
Gaps.vGaps5, Gaps.vGaps5,
Text('V${packageInfo.version??''}',style: TextStyle(fontSize: 13.w,color: Colours.c9)), Text('V${packageInfo.version}',
style: TextStyle(fontSize: 13.w, color: Colours.c9)),
], ],
), ),
SafeArea( SafeArea(
...@@ -56,29 +63,50 @@ class _AboutPageState extends State<AboutPage> { ...@@ -56,29 +63,50 @@ class _AboutPageState extends State<AboutPage> {
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: [ children: [
GestureDetector( GestureDetector(
child: Text('《用户协议》',textAlign: TextAlign.right,style: TextStyle(fontSize: 10.w,color: const Color(0xFF2A82D9)),), child: Text(
onTap: (){ '《用户协议》',
context.pushNamed(Routes.terms,queryParameters: {'url':'$kServerUrl$kUserAgreement','title':'用户协议'}); textAlign: TextAlign.right,
style: TextStyle(
fontSize: 10.w, color: const Color(0xFF2A82D9)),
),
onTap: () {
context.pushNamed(Routes.terms, queryParameters: {
'url': kUserAgreement,
'title': '用户协议'
});
}, },
), ),
Gaps.vGaps15, Gaps.vGaps15,
Container(width: 1.w,height: 10.w,color: const Color(0xFFC8C8C8),), Container(
width: 1.w,
height: 10.w,
color: const Color(0xFFC8C8C8),
),
Gaps.vGaps15, Gaps.vGaps15,
GestureDetector( GestureDetector(
child: Text('《隐私协议》',textAlign: TextAlign.left,style: TextStyle(fontSize: 10.w,color: const Color(0xFF2A82D9))), child: Text('《隐私协议》',
onTap:(){ textAlign: TextAlign.left,
context.pushNamed(Routes.terms,queryParameters: {'url':'$kServerUrl$kUserPriAgreement','title':'隐私政策'}); style: TextStyle(
} , fontSize: 10.w, color: const Color(0xFF2A82D9))),
onTap: () {
context.pushNamed(Routes.terms, queryParameters: {
'url': kUserPriAgreement,
'title': '隐私政策'
});
},
) )
], ],
), ),
Gaps.hGaps10, Gaps.hGaps10,
Text('Copyright © 2024 Zijing Education. All rights reserved.\n清控紫荆(北京)教育科技股份有限公司\n京ICP证150431号',style: TextStyle(color: Colours.c9,fontSize:9.w),textAlign: TextAlign.center,), Text(
'Copyright © 2024 Zijing Education. All rights reserved.\n清控紫荆(北京)教育科技股份有限公司\n京ICP证150431号',
style: TextStyle(color: Colours.c9, fontSize: 9.w),
textAlign: TextAlign.center,
),
Gaps.vGaps25, Gaps.vGaps25,
], ],
), ),
) )
], ],
), ),
); );
......
part of recharge; part of recharge;
class CoinRechargePage extends StatefulWidget { class CoinRechargePage extends StatefulWidget {
const CoinRechargePage({Key? key}) : super(key: key); const CoinRechargePage({Key? key}) : super(key: key);
...@@ -9,12 +7,13 @@ class CoinRechargePage extends StatefulWidget { ...@@ -9,12 +7,13 @@ class CoinRechargePage extends StatefulWidget {
State<CoinRechargePage> createState() => _CoinRechargePageState(); State<CoinRechargePage> createState() => _CoinRechargePageState();
} }
class _CoinRechargePageState extends State<CoinRechargePage> with AutomaticKeepAliveClientMixin { class _CoinRechargePageState extends State<CoinRechargePage>
with AutomaticKeepAliveClientMixin {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return GetBuilder<CoinRechargeController>( return GetBuilder<CoinRechargeController>(
init: CoinRechargeController(context: context), init: CoinRechargeController(context: context),
builder:(controller) => Column( builder: (controller) => Column(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
Container( Container(
...@@ -27,14 +26,14 @@ class _CoinRechargePageState extends State<CoinRechargePage> with AutomaticKeepA ...@@ -27,14 +26,14 @@ class _CoinRechargePageState extends State<CoinRechargePage> with AutomaticKeepA
const Row( const Row(
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: [ children: [
Text('紫荆币充值',textAlign:TextAlign.center), Text('紫荆币充值', textAlign: TextAlign.center),
], ],
), ),
Positioned( Positioned(
right: 0.w, right: 0.w,
top: 0.w, top: 0.w,
child: GestureDetector( child: GestureDetector(
onTap: (){ onTap: () {
context.pop(); context.pop();
}, },
child: SizedBox( child: SizedBox(
...@@ -49,15 +48,14 @@ class _CoinRechargePageState extends State<CoinRechargePage> with AutomaticKeepA ...@@ -49,15 +48,14 @@ class _CoinRechargePageState extends State<CoinRechargePage> with AutomaticKeepA
), ),
Container( Container(
margin: EdgeInsets.symmetric(horizontal: 20.w), margin: EdgeInsets.symmetric(horizontal: 20.w),
child: _buildAudioGridView(controller) child: _buildAudioGridView(controller)),
),
Gaps.vGaps15, Gaps.vGaps15,
_buildListView(controller), _buildListView(controller),
Gaps.vGaps15, Gaps.vGaps15,
Container( Container(
margin: EdgeInsets.symmetric(horizontal:15.w), margin: EdgeInsets.symmetric(horizontal: 15.w),
child: CustomGradientButton( child: CustomGradientButton(
text: '立即充值${controller.rechargeModel.priceName??''}', text: '立即充值${controller.rechargeModel.priceName ?? ''}',
isEnabled: true, isEnabled: true,
onPressed: () { onPressed: () {
controller.createRechargeOrder(); controller.createRechargeOrder();
...@@ -66,15 +64,25 @@ class _CoinRechargePageState extends State<CoinRechargePage> with AutomaticKeepA ...@@ -66,15 +64,25 @@ class _CoinRechargePageState extends State<CoinRechargePage> with AutomaticKeepA
), ),
Gaps.vGaps15, Gaps.vGaps15,
GestureDetector( GestureDetector(
onTap: (){ onTap: () {
context.pushNamed(Routes.terms,queryParameters: {'url':'$kServerUrl$kUserRechargeAgreement','title':'用户充值协议'}); context.pushNamed(Routes.terms, queryParameters: {
'url': kUserRechargeAgreement,
'title': '用户充值协议'
});
}, },
child: RichText(text: TextSpan( child: RichText(
children: [ text: TextSpan(children: [
TextSpan(text: '充值即代表同意',style: TextStyle(fontSize: 13.w,height: 1.5,color: Colours.c9)), TextSpan(
TextSpan(text: '《用户充值协议》',style: TextStyle(fontSize: 13.w,height: 1.5,color: const Color(0xFF2A82D9))), text: '充值即代表同意',
] style: TextStyle(
)), fontSize: 13.w, height: 1.5, color: Colours.c9)),
TextSpan(
text: '《用户充值协议》',
style: TextStyle(
fontSize: 13.w,
height: 1.5,
color: const Color(0xFF2A82D9))),
])),
), ),
Gaps.vGaps15 Gaps.vGaps15
], ],
...@@ -82,7 +90,7 @@ class _CoinRechargePageState extends State<CoinRechargePage> with AutomaticKeepA ...@@ -82,7 +90,7 @@ class _CoinRechargePageState extends State<CoinRechargePage> with AutomaticKeepA
); );
} }
Widget _buildAudioGridView(CoinRechargeController controller){ Widget _buildAudioGridView(CoinRechargeController controller) {
return GridView.builder( return GridView.builder(
// padding: const EdgeInsets.only(left: 13,top: 10), // padding: const EdgeInsets.only(left: 13,top: 10),
physics: const NeverScrollableScrollPhysics(), physics: const NeverScrollableScrollPhysics(),
...@@ -91,26 +99,41 @@ class _CoinRechargePageState extends State<CoinRechargePage> with AutomaticKeepA ...@@ -91,26 +99,41 @@ class _CoinRechargePageState extends State<CoinRechargePage> with AutomaticKeepA
crossAxisCount: 3, crossAxisCount: 3,
crossAxisSpacing: 10.w, crossAxisSpacing: 10.w,
mainAxisSpacing: 10.w, mainAxisSpacing: 10.w,
childAspectRatio: 2 childAspectRatio: 2),
),
itemBuilder: (BuildContext context, int index) { itemBuilder: (BuildContext context, int index) {
CoinModel model = controller.data[index]; CoinModel model = controller.data[index];
return GestureDetector( return GestureDetector(
onTap: (){ onTap: () {
controller.choose(model); controller.choose(model);
}, },
child: Container( child: Container(
decoration: BoxDecoration( decoration: BoxDecoration(
color: model.selected?AppTheme.primary.withOpacity(0.1):Colors.white, color: model.selected
? AppTheme.primary.withOpacity(0.1)
: Colors.white,
borderRadius: BorderRadius.circular(8.w), borderRadius: BorderRadius.circular(8.w),
border: Border.all(width: 0.5.w,color: model.selected?AppTheme.primary:const Color(0xFFDADADA)) border: Border.all(
), width: 0.5.w,
color: model.selected
? AppTheme.primary
: const Color(0xFFDADADA))),
child: Column( child: Column(
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: [ children: [
Text(model.beanName??'',style: TextStyle(color: model.selected?AppTheme.primary:Colours.c3,fontSize: 14.w,height: 1.5),), Text(
Text(model.priceName??'',style: TextStyle(color: model.selected?AppTheme.primary:Colours.c9,fontSize: 11.w,height: 1.5),), model.beanName ?? '',
style: TextStyle(
color: model.selected ? AppTheme.primary : Colours.c3,
fontSize: 14.w,
height: 1.5),
),
Text(
model.priceName ?? '',
style: TextStyle(
color: model.selected ? AppTheme.primary : Colours.c9,
fontSize: 11.w,
height: 1.5),
),
], ],
), ),
), ),
...@@ -119,18 +142,21 @@ class _CoinRechargePageState extends State<CoinRechargePage> with AutomaticKeepA ...@@ -119,18 +142,21 @@ class _CoinRechargePageState extends State<CoinRechargePage> with AutomaticKeepA
itemCount: controller.data.length, itemCount: controller.data.length,
); );
} }
Widget _buildListView(CoinRechargeController controller){
Widget _buildListView(CoinRechargeController controller) {
return ListView.builder( return ListView.builder(
physics: const NeverScrollableScrollPhysics(), physics: const NeverScrollableScrollPhysics(),
padding: EdgeInsets.symmetric(horizontal: 20.w), padding: EdgeInsets.symmetric(horizontal: 20.w),
shrinkWrap:true, shrinkWrap: true,
itemBuilder: (BuildContext context, int index){ itemBuilder: (BuildContext context, int index) {
PayModel model = controller.pays[index]; PayModel model = controller.pays[index];
return GestureDetector( return GestureDetector(
onTap: (){ onTap: () {
controller.setPayModel(model); controller.setPayModel(model);
}, },
child: BuildPayWay(model:model,)); child: BuildPayWay(
model: model,
));
}, },
itemCount: controller.pays.length, itemCount: controller.pays.length,
); );
......
...@@ -167,8 +167,11 @@ class _UserEditNotePageState extends State<UserEditNotePage> { ...@@ -167,8 +167,11 @@ class _UserEditNotePageState extends State<UserEditNotePage> {
onTap: () async{ onTap: () async{
final assets = await AssetsPicker.image( final assets = await AssetsPicker.image(
context: context, context: context,
purpose: '用于从相册中选择图片添加到笔记中,仅用于上传和显示图片内容。',
); );
controller.addImage(assets!.path); if (assets != null) {
controller.addImage(assets.path);
}
}, },
child: SizedBox( child: SizedBox(
// color: Colors.red, // color: Colors.red,
......
...@@ -168,9 +168,12 @@ class _UserInfoPageState extends State<UserInfoPage> { ...@@ -168,9 +168,12 @@ class _UserInfoPageState extends State<UserInfoPage> {
Console.log("点击拍照"); Console.log("点击拍照");
final assets = await AssetsPicker.camera( final assets = await AssetsPicker.camera(
context: context, context: context,
purpose: '用于使用相机拍照设置用户头像,仅用于上传和显示您的头像图片。',
); );
controller.upload(path: assets!.path); if (assets != null) {
controller.upload(path: assets.path);
controller.show(); controller.show();
}
}, },
child: Container( child: Container(
height: 45.w, height: 45.w,
...@@ -202,9 +205,12 @@ class _UserInfoPageState extends State<UserInfoPage> { ...@@ -202,9 +205,12 @@ class _UserInfoPageState extends State<UserInfoPage> {
Console.log("点击选择现有图片"); Console.log("点击选择现有图片");
final assets = await AssetsPicker.image( final assets = await AssetsPicker.image(
context: context, context: context,
purpose: '用于从相册中选择图片设置用户头像,仅用于上传和显示您的头像图片。',
); );
controller.upload(path: assets!.path); if (assets != null) {
controller.upload(path: assets.path);
controller.show(); controller.show();
}
}, },
child: Container( child: Container(
height: 45.w, height: 45.w,
......
...@@ -48,6 +48,7 @@ import 'package:flutter_book/pages/user_set/index.dart'; ...@@ -48,6 +48,7 @@ import 'package:flutter_book/pages/user_set/index.dart';
import 'package:flutter_book/pages/user_wrong/index.dart'; import 'package:flutter_book/pages/user_wrong/index.dart';
import 'package:flutter_book/pages/user_wrong_des/index.dart'; import 'package:flutter_book/pages/user_wrong_des/index.dart';
import 'package:flutter_book/pages/version_des/index.dart'; import 'package:flutter_book/pages/version_des/index.dart';
import 'package:get/get.dart';
import 'package:go_router/go_router.dart'; import 'package:go_router/go_router.dart';
import '../models/index.dart'; import '../models/index.dart';
...@@ -67,7 +68,6 @@ import '../pages/user_terms/index.dart'; ...@@ -67,7 +68,6 @@ import '../pages/user_terms/index.dart';
import '../pages/version/index.dart'; import '../pages/version/index.dart';
import '../store/index.dart'; import '../store/index.dart';
part 'observers.dart'; part 'observers.dart';
part 'routes.dart'; part 'routes.dart';
part 'transitions.dart'; part 'transitions.dart';
...@@ -3,13 +3,14 @@ part of routes; ...@@ -3,13 +3,14 @@ part of routes;
abstract class Routes { abstract class Routes {
static final RouteObserver<Route> observer = RouteObservers(); static final RouteObserver<Route> observer = RouteObservers();
static List<String> history = []; static List<String> history = [];
static final ValueNotifier<bool> _routeRefreshFallback =
ValueNotifier<bool>(false);
static const splash = 'splash'; static const splash = 'splash';
static const main = 'main'; static const main = 'main';
static const ad = 'ad'; static const ad = 'ad';
static const adDetail = 'ad_detail'; static const adDetail = 'ad_detail';
static const web = 'read_web'; static const web = 'read_web';
static const answer = 'answer'; static const answer = 'answer';
static const readInfo = 'read_info'; static const readInfo = 'read_info';
...@@ -22,7 +23,6 @@ abstract class Routes { ...@@ -22,7 +23,6 @@ abstract class Routes {
// 搜索 // 搜索
static const search = 'search'; static const search = 'search';
/// 登录模块 /// 登录模块
// 登录 // 登录
static const login = 'login'; static const login = 'login';
...@@ -31,7 +31,6 @@ abstract class Routes { ...@@ -31,7 +31,6 @@ abstract class Routes {
// 重置密码 // 重置密码
static const resetPwd = 'reset_pwd'; static const resetPwd = 'reset_pwd';
/// 课程模块 /// 课程模块
// 详情 // 详情
static const bookDetail = 'book_detail'; static const bookDetail = 'book_detail';
...@@ -40,7 +39,6 @@ abstract class Routes { ...@@ -40,7 +39,6 @@ abstract class Routes {
// 学习报告 // 学习报告
static const studyReport = 'study_report'; static const studyReport = 'study_report';
/// 图书馆模块 /// 图书馆模块
// 百科 // 百科
static const baiKe = 'bai_ke'; static const baiKe = 'bai_ke';
...@@ -54,8 +52,6 @@ abstract class Routes { ...@@ -54,8 +52,6 @@ abstract class Routes {
static const shop = 'shop'; static const shop = 'shop';
static const payCoupon = 'pay_coupon'; static const payCoupon = 'pay_coupon';
/// 我的模块 /// 我的模块
// 个人信息 // 个人信息
static const userInfo = 'user_info'; static const userInfo = 'user_info';
...@@ -108,55 +104,58 @@ abstract class Routes { ...@@ -108,55 +104,58 @@ abstract class Routes {
// 意见反馈 // 意见反馈
static const feedback = 'feedback'; static const feedback = 'feedback';
// 订单评价 // 订单评价
static const orderEvaluate= 'order_evaluate'; static const orderEvaluate = 'order_evaluate';
// 帮助中心 // 帮助中心
static const helpCenter= 'help_center'; static const helpCenter = 'help_center';
// 帮助中心内容 // 帮助中心内容
static const helpCenterContent = 'help_center_content'; static const helpCenterContent = 'help_center_content';
// 订单列表 // 订单列表
static const order= 'order'; static const order = 'order';
// 已完成订单 // 已完成订单
static const orderCompleted= 'order_completed'; static const orderCompleted = 'order_completed';
// 图书待付款订单 // 图书待付款订单
static const orderAwaiting= 'order_awaiting'; static const orderAwaiting = 'order_awaiting';
// 图书取消订单 // 图书取消订单
static const orderCancel= 'order_cancel'; static const orderCancel = 'order_cancel';
// 紫荆币待付款订单 // 紫荆币待付款订单
static const orderCoinAwaiting= 'order_coin_awaiting'; static const orderCoinAwaiting = 'order_coin_awaiting';
// 紫荆币已取消订单 // 紫荆币已取消订单
static const orderCoinCancel= 'order_coin_cancel'; static const orderCoinCancel = 'order_coin_cancel';
// 紫荆币已完成订单 // 紫荆币已完成订单
static const orderCoinCompleted= 'order_coin_completed'; static const orderCoinCompleted = 'order_coin_completed';
// 已退款订单 // 已退款订单
static const orderRefunded= 'order_refunded'; static const orderRefunded = 'order_refunded';
// 搜索订单 // 搜索订单
static const orderSearch= 'order_search'; static const orderSearch = 'order_search';
// 图片预览 // 图片预览
static const imageView = 'image_view'; static const imageView = 'image_view';
static final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>(); static final GlobalKey<NavigatorState> navigatorKey =
GlobalKey<NavigatorState>();
static UserStore? get _userStoreOrNull =>
Get.isRegistered<UserStore>() ? Get.find<UserStore>() : null;
static final GoRouter config = GoRouter( static final GoRouter config = GoRouter(
navigatorKey: navigatorKey, navigatorKey: navigatorKey,
initialLocation: '/$splash', initialLocation: '/$splash',
// initialLocation: '/', // initialLocation: '/',
observers: [observer], observers: [observer],
refreshListenable:UserStore.to.needLogin, refreshListenable: _userStoreOrNull?.needLogin ?? _routeRefreshFallback,
redirect: (context, state) { redirect: (context, state) {
final userStore = _userStoreOrNull;
final currentRoute = state.matchedLocation; final currentRoute = state.matchedLocation;
final loginRoute = state.namedLocation(login); final loginRoute = state.namedLocation(login);
final mainRoute = state.namedLocation(main); final mainRoute = state.namedLocation(main);
if (currentRoute.contains(mainRoute)) return null; if (currentRoute.contains(mainRoute)) return null;
if(currentRoute.contains(loginRoute)) return null; if (currentRoute.contains(loginRoute)) return null;
if(!UserStore.to.isLogin) return loginRoute; if (!(userStore?.isLogin ?? false)) return loginRoute;
return null; return null;
}, },
routes: [ routes: [
GoRoute( GoRoute(
path: '/$splash', path: '/$splash',
name: splash, name: splash,
pageBuilder: (context, state) =>CupertinoPage( pageBuilder: (context, state) => CupertinoPage(
name: state.uri.toString(), name: state.uri.toString(),
key: state.pageKey, key: state.pageKey,
child: const SplashPage(), child: const SplashPage(),
...@@ -165,589 +164,533 @@ abstract class Routes { ...@@ -165,589 +164,533 @@ abstract class Routes {
GoRoute( GoRoute(
path: '/', path: '/',
name: main, name: main,
pageBuilder: (context, state) =>CupertinoPage( pageBuilder: (context, state) => CupertinoPage(
name: state.uri.toString(), name: state.uri.toString(),
key: state.pageKey, key: state.pageKey,
child: const MainPage() child: const MainPage())),
)
),
GoRoute( GoRoute(
path: '/$ad', path: '/$ad',
name: ad, name: ad,
pageBuilder: (context, state) =>CupertinoPage( pageBuilder: (context, state) => CupertinoPage(
name: state.uri.toString(), name: state.uri.toString(),
key: state.pageKey, key: state.pageKey,
child: AdPage(ads: state.extra as List<AdModel>,) child: AdPage(
) ads: state.extra as List<AdModel>,
), ))),
/// 登录模块 /// 登录模块
GoRoute( GoRoute(
path: '/$login', path: '/$login',
name: login, name: login,
pageBuilder: (context, state) =>CupertinoPage( pageBuilder: (context, state) => CupertinoPage(
name: state.uri.toString(), name: state.uri.toString(),
key: state.pageKey, key: state.pageKey,
child: const LoginPage() child: const LoginPage())),
)
),
GoRoute( GoRoute(
path: '/$forgetPwd', path: '/$forgetPwd',
name: forgetPwd, name: forgetPwd,
pageBuilder: (context, state) =>CupertinoPage( pageBuilder: (context, state) => CupertinoPage(
name: state.uri.toString(), name: state.uri.toString(),
key: state.pageKey, key: state.pageKey,
child: const ForgetPwdPage() child: const ForgetPwdPage())),
)
),
GoRoute( GoRoute(
path: '/$resetPwd', path: '/$resetPwd',
name: resetPwd, name: resetPwd,
pageBuilder: (context, state) =>CupertinoPage( pageBuilder: (context, state) => CupertinoPage(
name: state.uri.toString(), name: state.uri.toString(),
key: state.pageKey, key: state.pageKey,
child: ResetPwdPage( child: ResetPwdPage(
phone: state.uri.queryParameters['phone'].toString(), phone: state.uri.queryParameters['phone'].toString(),
code: state.uri.queryParameters['code'].toString(), code: state.uri.queryParameters['code'].toString(),
) ))),
)
),
GoRoute( GoRoute(
path: '/$web', path: '/$web',
name: web, name: web,
pageBuilder: (context, state) =>CupertinoPage( pageBuilder: (context, state) => CupertinoPage(
name: state.uri.toString(), name: state.uri.toString(),
key: state.pageKey, key: state.pageKey,
child: ReadPage( child: ReadPage(
bookId: state.uri.queryParameters['book_id'].toString(), bookId: state.uri.queryParameters['book_id'].toString(),
chapterId: state.uri.queryParameters['chapter_id'].toString(), chapterId: state.uri.queryParameters['chapter_id'].toString(),
chapterName: state.uri.queryParameters['chapter_name'].toString(), chapterName:
state.uri.queryParameters['chapter_name'].toString(),
bookDetailModel: state.extra as BookDetailModel, bookDetailModel: state.extra as BookDetailModel,
noteId: state.uri.queryParameters['note_id'].toString(), noteId: state.uri.queryParameters['note_id'].toString(),
) ))),
)
),
GoRoute( GoRoute(
path: '/$about', path: '/$about',
name: about, name: about,
pageBuilder: (context, state) =>CupertinoPage( pageBuilder: (context, state) => CupertinoPage(
name: state.uri.toString(), name: state.uri.toString(),
key: state.pageKey, key: state.pageKey,
child: const AboutPage() child: const AboutPage())),
)
),
GoRoute( GoRoute(
path: '/$bookPay', path: '/$bookPay',
name: bookPay, name: bookPay,
pageBuilder: (context, state) =>CupertinoPage( pageBuilder: (context, state) => CupertinoPage(
name: state.uri.toString(), name: state.uri.toString(),
key: state.pageKey, key: state.pageKey,
child: BookPayPage(buy: state.extra as List<CourseModel>,) child: BookPayPage(
) buy: state.extra as List<CourseModel>,
), ))),
GoRoute( GoRoute(
path: '/$terms', path: '/$terms',
name: terms, name: terms,
pageBuilder: (context, state) =>CupertinoPage( pageBuilder: (context, state) => CupertinoPage(
name: state.uri.toString(), name: state.uri.toString(),
key: state.pageKey, key: state.pageKey,
child: TermsPage( child: TermsPage(
url: state.uri.queryParameters['url'].toString(), url: state.uri.queryParameters['url'].toString(),
title: state.uri.queryParameters['title'].toString(), title: state.uri.queryParameters['title'].toString(),
) ))),
)
),
GoRoute( GoRoute(
path: '/$msgs', path: '/$msgs',
name: msgs, name: msgs,
pageBuilder: (context, state) =>CupertinoPage( pageBuilder: (context, state) => CupertinoPage(
name: state.uri.toString(), name: state.uri.toString(),
key: state.pageKey, key: state.pageKey,
child: const MsgPage() child: const MsgPage())),
)
),
GoRoute( GoRoute(
path: '/$userInfo', path: '/$userInfo',
name: userInfo, name: userInfo,
pageBuilder: (context, state) =>CupertinoPage( pageBuilder: (context, state) => CupertinoPage(
name: state.uri.toString(), name: state.uri.toString(),
key: state.pageKey, key: state.pageKey,
child: UserInfoPage(userInfo: state.extra as UserInfoModel,) child: UserInfoPage(
) userInfo: state.extra as UserInfoModel,
), ))),
GoRoute( GoRoute(
path: '/$nike', path: '/$nike',
name: nike, name: nike,
pageBuilder: (context, state) =>CupertinoPage( pageBuilder: (context, state) => CupertinoPage(
name: state.uri.toString(), name: state.uri.toString(),
key: state.pageKey, key: state.pageKey,
child: UserNickPage(userInfo: state.extra as UserInfoModel,) child: UserNickPage(
) userInfo: state.extra as UserInfoModel,
), ))),
GoRoute( GoRoute(
path: '/$coin', path: '/$coin',
name: coin, name: coin,
pageBuilder: (context, state) =>CupertinoPage( pageBuilder: (context, state) => CupertinoPage(
name: state.uri.toString(), name: state.uri.toString(),
key: state.pageKey, key: state.pageKey,
child: const UserCoinPage() child: const UserCoinPage())),
)
),
GoRoute( GoRoute(
path: '/$bookDetail', path: '/$bookDetail',
name: bookDetail, name: bookDetail,
pageBuilder: (context, state) =>CupertinoPage( pageBuilder: (context, state) => CupertinoPage(
name: state.uri.toString(), name: state.uri.toString(),
key: state.pageKey, key: state.pageKey,
child: BookDetailPage( child: BookDetailPage(
bookId: state.uri.queryParameters['book_id'].toString(), bookId: state.uri.queryParameters['book_id'].toString(),
) )),
),
redirect: (context, state) => _RouteRedirect.auth(), redirect: (context, state) => _RouteRedirect.auth(),
), ),
GoRoute( GoRoute(
path: '/$bookScore', path: '/$bookScore',
name: bookScore, name: bookScore,
pageBuilder: (context, state) =>CupertinoPage( pageBuilder: (context, state) => CupertinoPage(
name: state.uri.toString(), name: state.uri.toString(),
key: state.pageKey, key: state.pageKey,
child: BookScorePage( child: BookScorePage(
bookId: state.uri.queryParameters['book_id'].toString(), bookId: state.uri.queryParameters['book_id'].toString(),
) ))),
)
),
GoRoute( GoRoute(
path: '/$studyReport', path: '/$studyReport',
name: studyReport, name: studyReport,
pageBuilder: (context, state) =>CupertinoPage( pageBuilder: (context, state) => CupertinoPage(
name: state.uri.toString(), name: state.uri.toString(),
key: state.pageKey, key: state.pageKey,
child: StudyReportPage( child: StudyReportPage(
bookId: state.uri.queryParameters['book_id'].toString(), bookId: state.uri.queryParameters['book_id'].toString(),
) ))),
)
),
GoRoute( GoRoute(
path: '/$creditPoints', path: '/$creditPoints',
name: creditPoints, name: creditPoints,
pageBuilder: (context, state) =>CupertinoPage( pageBuilder: (context, state) => CupertinoPage(
name: state.uri.toString(), name: state.uri.toString(),
key: state.pageKey, key: state.pageKey,
child: const CreditPointsPage() child: const CreditPointsPage())),
)
),
GoRoute( GoRoute(
path: '/$payCoupon', path: '/$payCoupon',
name: payCoupon, name: payCoupon,
pageBuilder: (context, state) =>CupertinoPage( pageBuilder: (context, state) => CupertinoPage(
name: state.uri.toString(), name: state.uri.toString(),
key: state.pageKey, key: state.pageKey,
child: PayCouponPage( child: PayCouponPage(
payController: state.extra as BookPayController, payController: state.extra as BookPayController,
) ))),
)
),
GoRoute( GoRoute(
path: '/$search', path: '/$search',
name: search, name: search,
pageBuilder: (context, state) =>CupertinoPage( pageBuilder: (context, state) => CupertinoPage(
name: state.uri.toString(), name: state.uri.toString(),
key: state.pageKey, key: state.pageKey,
child: const SearchPage() child: const SearchPage())),
)
),
GoRoute( GoRoute(
path: '/$studyHistory', path: '/$studyHistory',
name: studyHistory, name: studyHistory,
pageBuilder: (context, state) =>CupertinoPage( pageBuilder: (context, state) => CupertinoPage(
name: state.uri.toString(), name: state.uri.toString(),
key: state.pageKey, key: state.pageKey,
child: const StudyHistoryPage() child: const StudyHistoryPage())),
)
),
GoRoute( GoRoute(
path: '/$love', path: '/$love',
name: love, name: love,
pageBuilder: (context, state) =>CupertinoPage( pageBuilder: (context, state) => CupertinoPage(
name: state.uri.toString(), name: state.uri.toString(),
key: state.pageKey, key: state.pageKey,
child: const UserLovePage() child: const UserLovePage())),
)
),
GoRoute( GoRoute(
path: '/$shop', path: '/$shop',
name: shop, name: shop,
pageBuilder: (context, state) =>CupertinoPage( pageBuilder: (context, state) => CupertinoPage(
name: state.uri.toString(), name: state.uri.toString(),
key: state.pageKey, key: state.pageKey,
child: const BookShopPage() child: const BookShopPage())),
)
),
GoRoute( GoRoute(
path: '/$note', path: '/$note',
name: note, name: note,
pageBuilder: (context, state) =>CupertinoPage( pageBuilder: (context, state) => CupertinoPage(
name: state.uri.toString(), name: state.uri.toString(),
key: state.pageKey, key: state.pageKey,
child: const UserNotePage() child: const UserNotePage())),
)
),
GoRoute( GoRoute(
path: '/$wrong', path: '/$wrong',
name: wrong, name: wrong,
pageBuilder: (context, state) =>CupertinoPage( pageBuilder: (context, state) => CupertinoPage(
name: state.uri.toString(), name: state.uri.toString(),
key: state.pageKey, key: state.pageKey,
child: const UserWrongPage() child: const UserWrongPage())),
)
),
GoRoute( GoRoute(
path: '/$wrongDes', path: '/$wrongDes',
name: wrongDes, name: wrongDes,
pageBuilder: (context, state) =>CupertinoPage( pageBuilder: (context, state) => CupertinoPage(
name: state.uri.toString(), name: state.uri.toString(),
key: state.pageKey, key: state.pageKey,
child: UserWrongDesPage( child: UserWrongDesPage(model: state.extra as CourseModel))),
model: state.extra as CourseModel
)
)
),
GoRoute( GoRoute(
path: '/$point', path: '/$point',
name: point, name: point,
pageBuilder: (context, state) =>CupertinoPage( pageBuilder: (context, state) => CupertinoPage(
name: state.uri.toString(), name: state.uri.toString(),
key: state.pageKey, key: state.pageKey,
child: const UserPointPage() child: const UserPointPage())),
)
),
GoRoute( GoRoute(
path: '/$discuss', path: '/$discuss',
name: discuss, name: discuss,
pageBuilder: (context, state) =>CupertinoPage( pageBuilder: (context, state) => CupertinoPage(
name: state.uri.toString(), name: state.uri.toString(),
key: state.pageKey, key: state.pageKey,
child: const UserDiscussPage() child: const UserDiscussPage())),
)
),
GoRoute( GoRoute(
path: '/$coupon', path: '/$coupon',
name: coupon, name: coupon,
pageBuilder: (context, state) =>CupertinoPage( pageBuilder: (context, state) => CupertinoPage(
name: state.uri.toString(), name: state.uri.toString(),
key: state.pageKey, key: state.pageKey,
child: const UserCouponPage() child: const UserCouponPage())),
)
),
GoRoute( GoRoute(
path: '/$set', path: '/$set',
name: set, name: set,
pageBuilder: (context, state) =>CupertinoPage( pageBuilder: (context, state) => CupertinoPage(
name: state.uri.toString(), name: state.uri.toString(),
key: state.pageKey, key: state.pageKey,
child: const UserSetPage() child: const UserSetPage())),
)
),
GoRoute( GoRoute(
path: '/$version', path: '/$version',
name: version, name: version,
pageBuilder: (context, state) =>CupertinoPage( pageBuilder: (context, state) => CupertinoPage(
name: state.uri.toString(), name: state.uri.toString(),
key: state.pageKey, key: state.pageKey,
child: const VersionPage() child: const VersionPage())),
)
),
GoRoute( GoRoute(
path: '/$versionDes', path: '/$versionDes',
name: versionDes, name: versionDes,
pageBuilder: (context, state) =>CupertinoPage( pageBuilder: (context, state) => CupertinoPage(
name: state.uri.toString(), name: state.uri.toString(),
key: state.pageKey, key: state.pageKey,
child: VersionDesPage(model: state.extra as VersionModel,) child: VersionDesPage(
) model: state.extra as VersionModel,
), ))),
GoRoute( GoRoute(
path: '/$security', path: '/$security',
name: security, name: security,
pageBuilder: (context, state) =>CupertinoPage( pageBuilder: (context, state) => CupertinoPage(
name: state.uri.toString(), name: state.uri.toString(),
key: state.pageKey, key: state.pageKey,
child: UserSecurityPage(model: state.extra as UserInfoModel,) child: UserSecurityPage(
) model: state.extra as UserInfoModel,
), ))),
GoRoute( GoRoute(
path: '/$changePhone', path: '/$changePhone',
name: changePhone, name: changePhone,
pageBuilder: (context, state) =>CupertinoPage( pageBuilder: (context, state) => CupertinoPage(
name: state.uri.toString(), name: state.uri.toString(),
key: state.pageKey, key: state.pageKey,
child: const ChangePhonePage() child: const ChangePhonePage())),
)
),
GoRoute( GoRoute(
path: '/$changePwd', path: '/$changePwd',
name: changePwd, name: changePwd,
pageBuilder: (context, state) =>CupertinoPage( pageBuilder: (context, state) => CupertinoPage(
name: state.uri.toString(), name: state.uri.toString(),
key: state.pageKey, key: state.pageKey,
child: ChangePwdPage( child: ChangePwdPage(
userInfo: state.extra as UserInfoModel, userInfo: state.extra as UserInfoModel,
type: state.uri.queryParameters['type'].toString(), type: state.uri.queryParameters['type'].toString(),
) ))),
)
),
GoRoute( GoRoute(
path: '/$feedback', path: '/$feedback',
name: feedback, name: feedback,
pageBuilder: (context, state) =>CupertinoPage( pageBuilder: (context, state) => CupertinoPage(
name: state.uri.toString(), name: state.uri.toString(),
key: state.pageKey, key: state.pageKey,
child: const UserFeedbackPage() child: const UserFeedbackPage())),
)
),
GoRoute( GoRoute(
path: '/$noteDes', path: '/$noteDes',
name: noteDes, name: noteDes,
pageBuilder: (context, state) =>CupertinoPage( pageBuilder: (context, state) => CupertinoPage(
name: state.uri.toString(), name: state.uri.toString(),
key: state.pageKey, key: state.pageKey,
child: UserNotesDesPage(model: state.extra as CourseModel,) child: UserNotesDesPage(
) model: state.extra as CourseModel,
), ))),
GoRoute( GoRoute(
path: '/$gender', path: '/$gender',
name: gender, name: gender,
pageBuilder: (context, state) =>CupertinoPage( pageBuilder: (context, state) => CupertinoPage(
name: state.uri.toString(), name: state.uri.toString(),
key: state.pageKey, key: state.pageKey,
child: UserGenderPage(userInfo: state.extra as UserInfoModel,) child: UserGenderPage(
) userInfo: state.extra as UserInfoModel,
), ))),
GoRoute( GoRoute(
path: '/$discussDes', path: '/$discussDes',
name: discussDes, name: discussDes,
pageBuilder: (context, state) =>CupertinoPage( pageBuilder: (context, state) => CupertinoPage(
name: state.uri.toString(), name: state.uri.toString(),
key: state.pageKey, key: state.pageKey,
child: UserDiscussDesPage(model: state.extra as CourseModel,) child: UserDiscussDesPage(
) model: state.extra as CourseModel,
), ))),
GoRoute( GoRoute(
path: '/$orderEvaluate', path: '/$orderEvaluate',
name: orderEvaluate, name: orderEvaluate,
pageBuilder: (context, state) =>CupertinoPage( pageBuilder: (context, state) => CupertinoPage(
name: state.uri.toString(), name: state.uri.toString(),
key: state.pageKey, key: state.pageKey,
child: UserOrderEvaluatePage(orderNum:state.uri.queryParameters['orderNum'].toString(),orderInfoModel: state.extra as OrderInfoModel,) child: UserOrderEvaluatePage(
) orderNum: state.uri.queryParameters['orderNum'].toString(),
), orderInfoModel: state.extra as OrderInfoModel,
GoRoute( // 帮助中心 ))),
GoRoute(
// 帮助中心
path: '/$helpCenter', path: '/$helpCenter',
name: helpCenter, name: helpCenter,
pageBuilder: (context, state) =>CupertinoPage( pageBuilder: (context, state) => CupertinoPage(
name: state.uri.toString(), name: state.uri.toString(),
key: state.pageKey, key: state.pageKey,
child: const HelpCenterPage() child: const HelpCenterPage())),
) GoRoute(
), // 帮助中心内容
GoRoute( // 帮助中心内容
path: '/$helpCenterContent', path: '/$helpCenterContent',
name: helpCenterContent, name: helpCenterContent,
pageBuilder: (context, state) =>CupertinoPage( pageBuilder: (context, state) => CupertinoPage(
name: state.uri.toString(), name: state.uri.toString(),
key: state.pageKey, key: state.pageKey,
child: HelpCenterContentPage( child: HelpCenterContentPage(
id: state.uri.queryParameters['id'].toString(), id: state.uri.queryParameters['id'].toString(),
title: state.uri.queryParameters['title'].toString(), title: state.uri.queryParameters['title'].toString(),
) ))),
) GoRoute(
), // 已完成订单
GoRoute( // 已完成订单
path: '/$order', path: '/$order',
name: order, name: order,
pageBuilder: (context, state) =>CupertinoPage( pageBuilder: (context, state) => CupertinoPage(
name: state.uri.toString(), name: state.uri.toString(),
key: state.pageKey, key: state.pageKey,
child: const UserOrderPage() child: const UserOrderPage())),
) GoRoute(
), // 已完成订单
GoRoute( // 已完成订单
path: '/$orderCompleted', path: '/$orderCompleted',
name: orderCompleted, name: orderCompleted,
pageBuilder: (context, state) =>CupertinoPage( pageBuilder: (context, state) => CupertinoPage(
name: state.uri.toString(), name: state.uri.toString(),
key: state.pageKey, key: state.pageKey,
child: UserOrderCompletedPage(orderNum: state.uri.queryParameters['orderNum'].toString()) child: UserOrderCompletedPage(
) orderNum:
), state.uri.queryParameters['orderNum'].toString()))),
GoRoute( // 图书待付款订单 GoRoute(
// 图书待付款订单
path: '/$orderAwaiting', path: '/$orderAwaiting',
name: orderAwaiting, name: orderAwaiting,
pageBuilder: (context, state) =>CupertinoPage( pageBuilder: (context, state) => CupertinoPage(
name: state.uri.toString(), name: state.uri.toString(),
key: state.pageKey, key: state.pageKey,
child: UserOrderAwaitingPage(orderNum: state.uri.queryParameters['orderNum'].toString()) child: UserOrderAwaitingPage(
) orderNum:
), state.uri.queryParameters['orderNum'].toString()))),
GoRoute( // 图书取消订单 GoRoute(
// 图书取消订单
path: '/$orderCancel', path: '/$orderCancel',
name: orderCancel, name: orderCancel,
pageBuilder: (context, state) =>CupertinoPage( pageBuilder: (context, state) => CupertinoPage(
name: state.uri.toString(), name: state.uri.toString(),
key: state.pageKey, key: state.pageKey,
child: UserOrderCancelDetailPage(orderNum: state.uri.queryParameters['orderNum'].toString()) child: UserOrderCancelDetailPage(
) orderNum:
), state.uri.queryParameters['orderNum'].toString()))),
GoRoute( // 紫荆币待付款订单 GoRoute(
// 紫荆币待付款订单
path: '/$orderCoinAwaiting', path: '/$orderCoinAwaiting',
name: orderCoinAwaiting, name: orderCoinAwaiting,
pageBuilder: (context, state) =>CupertinoPage( pageBuilder: (context, state) => CupertinoPage(
name: state.uri.toString(), name: state.uri.toString(),
key: state.pageKey, key: state.pageKey,
child: UserOrderCoinAwaitingPage(orderNum: state.uri.queryParameters['orderNum'].toString()) child: UserOrderCoinAwaitingPage(
) orderNum:
), state.uri.queryParameters['orderNum'].toString()))),
GoRoute( // 紫荆币已取消订单 GoRoute(
// 紫荆币已取消订单
path: '/$orderCoinCancel', path: '/$orderCoinCancel',
name: orderCoinCancel, name: orderCoinCancel,
pageBuilder: (context, state) =>CupertinoPage( pageBuilder: (context, state) => CupertinoPage(
name: state.uri.toString(), name: state.uri.toString(),
key: state.pageKey, key: state.pageKey,
child: UserOrderCoinCancelPage(orderNum: state.uri.queryParameters['orderNum'].toString()) child: UserOrderCoinCancelPage(
) orderNum:
), state.uri.queryParameters['orderNum'].toString()))),
GoRoute( // 紫荆币已完成订单 GoRoute(
// 紫荆币已完成订单
path: '/$orderCoinCompleted', path: '/$orderCoinCompleted',
name: orderCoinCompleted, name: orderCoinCompleted,
pageBuilder: (context, state) =>CupertinoPage( pageBuilder: (context, state) => CupertinoPage(
name: state.uri.toString(), name: state.uri.toString(),
key: state.pageKey, key: state.pageKey,
child: UserOrderCoinCompletedPage(orderNum: state.uri.queryParameters['orderNum'].toString()) child: UserOrderCoinCompletedPage(
) orderNum:
), state.uri.queryParameters['orderNum'].toString()))),
GoRoute( // 已退款订单 GoRoute(
// 已退款订单
path: '/$orderRefunded', path: '/$orderRefunded',
name: orderRefunded, name: orderRefunded,
pageBuilder: (context, state) =>CupertinoPage( pageBuilder: (context, state) => CupertinoPage(
name: state.uri.toString(), name: state.uri.toString(),
key: state.pageKey, key: state.pageKey,
child: UserOrderRefundedPage(orderNum: state.uri.queryParameters['orderNum'].toString()) child: UserOrderRefundedPage(
) orderNum:
), state.uri.queryParameters['orderNum'].toString()))),
GoRoute( // 百科 GoRoute(
// 百科
path: '/$baiKe', path: '/$baiKe',
name: baiKe, name: baiKe,
pageBuilder: (context, state) =>CupertinoPage( pageBuilder: (context, state) => CupertinoPage(
name: state.uri.toString(), name: state.uri.toString(),
key: state.pageKey, key: state.pageKey,
child: BaiKePage( child: BaiKePage(
keyword: state.uri.queryParameters['keyword'].toString(), keyword: state.uri.queryParameters['keyword'].toString(),
) ))),
)
),
GoRoute( GoRoute(
path: '/$editNote', path: '/$editNote',
name: editNote, name: editNote,
pageBuilder: (context, state) =>CupertinoPage( pageBuilder: (context, state) => CupertinoPage(
name: state.uri.toString(), name: state.uri.toString(),
key: state.pageKey, key: state.pageKey,
child: UserEditNotePage(model: state.extra as NoteModel,bookId: state.uri.queryParameters['book_id'].toString(),) child: UserEditNotePage(
) model: state.extra as NoteModel,
), bookId: state.uri.queryParameters['book_id'].toString(),
GoRoute( // 订单搜索 ))),
GoRoute(
// 订单搜索
path: '/$orderSearch', path: '/$orderSearch',
name: orderSearch, name: orderSearch,
pageBuilder: (context, state) =>CupertinoPage( pageBuilder: (context, state) => CupertinoPage(
name: state.uri.toString(), name: state.uri.toString(),
key: state.pageKey, key: state.pageKey,
child: const OrderSearchPage(), child: const OrderSearchPage(),
) )),
), GoRoute(
GoRoute( // 订单搜索 // 订单搜索
path: '/$adDetail', path: '/$adDetail',
name: adDetail, name: adDetail,
pageBuilder: (context, state) =>CupertinoPage( pageBuilder: (context, state) => CupertinoPage(
name: state.uri.toString(), name: state.uri.toString(),
key: state.pageKey, key: state.pageKey,
child: AdDetailPage(adModel: state.extra as AdModel,), child: AdDetailPage(
) adModel: state.extra as AdModel,
), ),
GoRoute( // 字典 )),
GoRoute(
// 字典
path: '/$baiDict', path: '/$baiDict',
name: baiDict, name: baiDict,
pageBuilder: (context, state) =>CupertinoPage( pageBuilder: (context, state) => CupertinoPage(
name: state.uri.toString(), name: state.uri.toString(),
key: state.pageKey, key: state.pageKey,
child: BaiDictPage( child: BaiDictPage(
keyword: state.uri.queryParameters['keyword'].toString(), keyword: state.uri.queryParameters['keyword'].toString(),
) ))),
) GoRoute(
), // 外部链接
GoRoute( // 外部链接
path: '/$link', path: '/$link',
name: link, name: link,
pageBuilder: (context, state) =>CupertinoPage( pageBuilder: (context, state) => CupertinoPage(
name: state.uri.toString(), name: state.uri.toString(),
key: state.pageKey, key: state.pageKey,
child: LinkPage( child: LinkPage(
url: state.uri.queryParameters['url'].toString(), url: state.uri.queryParameters['url'].toString(),
) ))),
) GoRoute(
), // 知识测评
GoRoute( // 知识测评
path: '/$answer', path: '/$answer',
name: answer, name: answer,
pageBuilder: (context, state) =>CupertinoPage( pageBuilder: (context, state) => CupertinoPage(
name: state.uri.toString(), name: state.uri.toString(),
key: state.pageKey, key: state.pageKey,
child: AnswerPage( child: AnswerPage(
params: state.uri.queryParameters, params: state.uri.queryParameters,
) ))),
) GoRoute(
), // 画廊 扩展阅读
GoRoute( // 画廊 扩展阅读
path: '/$readInfo', path: '/$readInfo',
name: readInfo, name: readInfo,
pageBuilder: (context, state) =>CupertinoPage( pageBuilder: (context, state) => CupertinoPage(
name: state.uri.toString(), name: state.uri.toString(),
key: state.pageKey, key: state.pageKey,
child: ReadInfoPage( child: ReadInfoPage(
params: state.uri.queryParameters, params: state.uri.queryParameters,
) ))),
) GoRoute(
), // 画廊 扩展阅读
GoRoute( // 画廊 扩展阅读
path: '/$scaleImage', path: '/$scaleImage',
name: scaleImage, name: scaleImage,
pageBuilder: (context, state) =>CupertinoPage( pageBuilder: (context, state) => CupertinoPage(
name: state.uri.toString(), name: state.uri.toString(),
key: state.pageKey, key: state.pageKey,
child: ScaleImagePage( child: ScaleImagePage(
params: state.uri.queryParameters, params: state.uri.queryParameters,
) ))),
) GoRoute(
), // 图片预览
GoRoute( // 图片预览
path: '/$imageView', path: '/$imageView',
name: imageView, name: imageView,
pageBuilder: (context, state) =>BottomToTopTransitionPage( pageBuilder: (context, state) => BottomToTopTransitionPage(
name: state.uri.toString(), name: state.uri.toString(),
key: state.pageKey, key: state.pageKey,
child: ImageViewPage( child: ImageViewPage(
images: state.extra as List<String>, images: state.extra as List<String>,
currentIndex: int.parse(state.uri.queryParameters['index'].toString()), currentIndex:
int.parse(state.uri.queryParameters['index'].toString()),
) ))),
) ]);
),
]
);
} }
abstract class _RouteRedirect { abstract class _RouteRedirect {
static String? auth() { static String? auth() {
if (UserStore.to.isLogin) return null; final userStore =
Get.isRegistered<UserStore>() ? Get.find<UserStore>() : null;
if (userStore?.isLogin ?? false) return null;
return '/${Routes.login}'; return '/${Routes.login}';
} }
} }
part of services; part of services;
class HttpService extends GetxService { class HttpService extends GetxService {
static HttpService get to => Get.find(); static HttpService get to => Get.find();
late final Dio _dio; late final Dio _dio;
...@@ -11,11 +10,10 @@ class HttpService extends GetxService { ...@@ -11,11 +10,10 @@ class HttpService extends GetxService {
final options = BaseOptions( final options = BaseOptions(
baseUrl: kServerUrl, baseUrl: kServerUrl,
connectTimeout: const Duration(seconds: 10), connectTimeout: const Duration(seconds: 10),
receiveTimeout: const Duration(seconds:10), receiveTimeout: const Duration(seconds: 10),
headers: {}, headers: {},
contentType: Headers.jsonContentType, contentType: Headers.jsonContentType,
responseType: ResponseType.json responseType: ResponseType.json);
);
_dio = Dio(options); _dio = Dio(options);
_dio.interceptors.add(_RequestInterceptor()); _dio.interceptors.add(_RequestInterceptor());
...@@ -23,28 +21,30 @@ class HttpService extends GetxService { ...@@ -23,28 +21,30 @@ class HttpService extends GetxService {
} }
/// 组织 headers 参数 /// 组织 headers 参数
Map<String,dynamic>? _getHeaders({bool excludeToken = false,Map<String,dynamic>? params,String? url}) { Map<String, dynamic>? _getHeaders(
{bool excludeToken = false, Map<String, dynamic>? params, String? url}) {
final headers = <String, dynamic>{}; final headers = <String, dynamic>{};
final userStore =
Get.isRegistered<UserStore>() ? Get.find<UserStore>() : null;
headers['appId'] = AppConfig.appID; headers['appId'] = AppConfig.appID;
headers['appSecret'] = AppConfig.appSecret; headers['appSecret'] = AppConfig.appSecret;
headers['timestamp'] = (DateTime.now().millisecondsSinceEpoch~/1000).toString(); headers['timestamp'] =
(DateTime.now().millisecondsSinceEpoch ~/ 1000).toString();
headers['url'] = kServerUrl + url.toString(); headers['url'] = kServerUrl + url.toString();
headers['token'] = UserStore.to.token; headers['token'] = userStore?.token ?? '';
if (Get.isRegistered<UserStore>() && if (userStore != null && userStore.hasToken && !excludeToken) {
UserStore.to.hasToken && !excludeToken) {
// headers['Token'] = UserStore.to.token; // headers['Token'] = UserStore.to.token;
headers['Authorization'] = UserStore.to.token; headers['Authorization'] = userStore.token;
} else{ } else {
headers['Authorization'] = ''; headers['Authorization'] = '';
} }
Map<String,dynamic>? tempParams = {}; Map<String, dynamic>? tempParams = {};
if (params != null) { if (params != null) {
tempParams.addAll(params); tempParams.addAll(params);
tempParams.addAll(headers); tempParams.addAll(headers);
headers['Sign'] = SignTool.createSign(tempParams); headers['Sign'] = SignTool.createSign(tempParams);
} } else {
else {
headers['Sign'] = SignTool.createSign(headers); headers['Sign'] = SignTool.createSign(headers);
} }
// Console.log(headers); // Console.log(headers);
...@@ -53,7 +53,7 @@ class HttpService extends GetxService { ...@@ -53,7 +53,7 @@ class HttpService extends GetxService {
/// get /// get
Future<ResponseModel> get( Future<ResponseModel> get(
String url,{ String url, {
Map<String, dynamic>? params, Map<String, dynamic>? params,
Options? options, Options? options,
CancelToken? cancelToken, CancelToken? cancelToken,
...@@ -64,10 +64,11 @@ class HttpService extends GetxService { ...@@ -64,10 +64,11 @@ class HttpService extends GetxService {
if (showLoading) CustomToast.loading(); if (showLoading) CustomToast.loading();
try { try {
final requestOptions = options ?? Options(); final requestOptions = options ?? Options();
requestOptions.headers = _getHeaders(excludeToken: excludeToken,params: params,url: url); requestOptions.headers =
_getHeaders(excludeToken: excludeToken, params: params, url: url);
// 如果启用缓存,将cacheEnabled参数添加到请求选项中 // 如果启用缓存,将cacheEnabled参数添加到请求选项中
if(cacheEnabled){ if (cacheEnabled) {
requestOptions.extra ??= {}; requestOptions.extra ??= {};
requestOptions.extra!['cacheEnabled'] = true; requestOptions.extra!['cacheEnabled'] = true;
} }
...@@ -79,7 +80,7 @@ class HttpService extends GetxService { ...@@ -79,7 +80,7 @@ class HttpService extends GetxService {
); );
if (showLoading) CustomToast.dismiss(); if (showLoading) CustomToast.dismiss();
return ResponseModel.fromJson(response.data); return ResponseModel.fromJson(response.data);
} catch (error){ } catch (error) {
if (error is! DioException) CustomToast.dismiss(); if (error is! DioException) CustomToast.dismiss();
rethrow; rethrow;
} }
...@@ -87,21 +88,23 @@ class HttpService extends GetxService { ...@@ -87,21 +88,23 @@ class HttpService extends GetxService {
/// post /// post
Future<ResponseModel> post( Future<ResponseModel> post(
String url,{ String url, {
Map<String,dynamic>? params, Map<String, dynamic>? params,
Options? options, Options? options,
CancelToken? cancelToken, CancelToken? cancelToken,
bool excludeToken = false, bool excludeToken = false,
bool showLoading = false, bool showLoading = false,
bool cacheEnabled = true, bool cacheEnabled = true,
}) async{ }) async {
if (showLoading) CustomToast.loading(); if (showLoading) CustomToast.loading();
try { try {
final requestOptions = options ?? Options(); final requestOptions = options ?? Options();
requestOptions.headers = _getHeaders(excludeToken: excludeToken,params: params,url: url); requestOptions.headers =
Console.log('----headers------${requestOptions.headers}\n----params------$params-----'); _getHeaders(excludeToken: excludeToken, params: params, url: url);
Console.log(
'----headers------${requestOptions.headers}\n----params------$params-----');
// 如果启用缓存,将cacheEnabled参数添加到请求选项中 // 如果启用缓存,将cacheEnabled参数添加到请求选项中
if(cacheEnabled){ if (cacheEnabled) {
requestOptions.extra ??= {}; requestOptions.extra ??= {};
requestOptions.extra!['cacheEnabled'] = true; requestOptions.extra!['cacheEnabled'] = true;
} }
...@@ -114,7 +117,7 @@ class HttpService extends GetxService { ...@@ -114,7 +117,7 @@ class HttpService extends GetxService {
if (showLoading) CustomToast.dismiss(); if (showLoading) CustomToast.dismiss();
Console.log(response.data); Console.log(response.data);
return ResponseModel.fromJson(response.data); return ResponseModel.fromJson(response.data);
} catch (error){ } catch (error) {
if (error is! DioException) CustomToast.dismiss(); if (error is! DioException) CustomToast.dismiss();
rethrow; rethrow;
} }
...@@ -129,58 +132,50 @@ class HttpService extends GetxService { ...@@ -129,58 +132,50 @@ class HttpService extends GetxService {
CancelToken? cancelToken, CancelToken? cancelToken,
bool excludeToken = false, bool excludeToken = false,
ProgressCallback? onSendProgress, ProgressCallback? onSendProgress,
})async { }) async {
final requestOptions = options ?? Options(); final requestOptions = options ?? Options();
requestOptions.headers = _getHeaders(excludeToken: excludeToken,url:url); requestOptions.headers = _getHeaders(excludeToken: excludeToken, url: url);
final name = path.substring(path.lastIndexOf('/') + 1,path.length); final name = path.substring(path.lastIndexOf('/') + 1, path.length);
final image = await MultipartFile.fromFile(path, filename: name); final image = await MultipartFile.fromFile(path, filename: name);
final formData = FormData.fromMap({ final formData =
'files':image, FormData.fromMap({'files': image, 'file_types': fileTypes});
'file_types':fileTypes
});
final response = await _dio.post( final response = await _dio.post(
url, url,
data:formData, data: formData,
options:requestOptions, options: requestOptions,
cancelToken: cancelToken, cancelToken: cancelToken,
onSendProgress: onSendProgress, onSendProgress: onSendProgress,
); );
return ResponseModel.fromJson(response.data); return ResponseModel.fromJson(response.data);
} }
/// download /// download
Future<void> download( Future<void> download(
String url,{ String url, {
required String savePath, required String savePath,
Options? options, Options? options,
CancelToken? cancelToken, CancelToken? cancelToken,
bool excludeToken = false, bool excludeToken = false,
ProgressCallback? onReceiveProgress, ProgressCallback? onReceiveProgress,
}) async { }) async {
try{ try {
final requestOptions = options ?? Options(); final requestOptions = options ?? Options();
requestOptions.headers = _getHeaders(excludeToken: excludeToken,url: url); requestOptions.headers =
_getHeaders(excludeToken: excludeToken, url: url);
requestOptions.responseType = ResponseType.bytes; requestOptions.responseType = ResponseType.bytes;
await _dio.download( await _dio.download(url, savePath,
url,
savePath,
options: requestOptions, options: requestOptions,
cancelToken: cancelToken, cancelToken: cancelToken,
onReceiveProgress: onReceiveProgress onReceiveProgress: onReceiveProgress);
);
Console.log('Download completed:$savePath'); Console.log('Download completed:$savePath');
}catch(e){ } catch (e) {
Console.log('Error during download: $e'); Console.log('Error during download: $e');
rethrow; rethrow;
} }
} }
} }
class _RequestInterceptor extends Interceptor { class _RequestInterceptor extends Interceptor {
@override @override
void onResponse(Response response, ResponseInterceptorHandler handler) async { void onResponse(Response response, ResponseInterceptorHandler handler) async {
...@@ -211,7 +206,7 @@ class _RequestInterceptor extends Interceptor { ...@@ -211,7 +206,7 @@ class _RequestInterceptor extends Interceptor {
), ),
true, true,
); );
}else { } else {
super.onResponse(response, handler); super.onResponse(response, handler);
} }
} }
...@@ -242,7 +237,8 @@ class _RequestInterceptor extends Interceptor { ...@@ -242,7 +237,8 @@ class _RequestInterceptor extends Interceptor {
var msg = '服务器错误'; var msg = '服务器错误';
switch (statusCode) { switch (statusCode) {
case 403: case 403:
Console.log('----------403---------access_token-------------------------${UserStore.to.accessToken}--------------------'); Console.log(
'----------403---------access_token-------------------------${UserStore.to.accessToken}--------------------');
msg = '$statusCode - Unauthorized'; msg = '$statusCode - Unauthorized';
final newToken = await refreshToken(); final newToken = await refreshToken();
Console.log('newToken----------$newToken'); Console.log('newToken----------$newToken');
...@@ -264,16 +260,15 @@ class _RequestInterceptor extends Interceptor { ...@@ -264,16 +260,15 @@ class _RequestInterceptor extends Interceptor {
try { try {
final newResponse = await Dio().fetch(requestOptions); final newResponse = await Dio().fetch(requestOptions);
handler.resolve(newResponse); handler.resolve(newResponse);
}catch (e) { } catch (e) {
handler.reject(err); handler.reject(err);
} }
} else { } else {
UserStore.to.logout(); UserStore.to.logout();
await Tools.clearData(); await Tools.clearData();
CustomToast.fail('该账号已在其他设备登录,请重新登录'); CustomToast.fail('该账号已在其他设备登录,请重新登录');
Console.log('-------------------access_token-------------------------${UserStore.to.accessToken}--------------------'); Console.log(
'-------------------access_token-------------------------${UserStore.to.accessToken}--------------------');
} }
break; break;
case 404: case 404:
...@@ -290,11 +285,10 @@ class _RequestInterceptor extends Interceptor { ...@@ -290,11 +285,10 @@ class _RequestInterceptor extends Interceptor {
break; break;
default: default:
msg = response?.data?['message']?.toString() ?? msg; msg = response?.data?['message']?.toString() ?? msg;
if(code == 3001){ if (code == 3001) {
// Toast.show(msg); // Toast.show(msg);
CustomToast.info(msg); CustomToast.info(msg);
} } else {
else{
CustomToast.fail(msg); CustomToast.fail(msg);
} }
break; break;
...@@ -314,18 +308,15 @@ class _RequestInterceptor extends Interceptor { ...@@ -314,18 +308,15 @@ class _RequestInterceptor extends Interceptor {
} }
Future<String?> refreshToken() async { Future<String?> refreshToken() async {
Console.log('--------refreshToken----------------'); Console.log('--------refreshToken----------------');
final result = await HttpService.to.post( final result = await HttpService.to.post('/v1/members/login/getToken',
'/v1/members/login/getToken',
params: { params: {
'access_token':StorageService.to.getString(kLocalAccessToken) 'access_token': StorageService.to.getString(kLocalAccessToken)
} });
);
if (result.data is Map) { if (result.data is Map) {
final String token = result.data['token']; final String token = result.data['token'];
final String accessToken = result.data['access_token']; final String accessToken = result.data['access_token'];
if(token.isEmpty && accessToken.isEmpty){ if (token.isEmpty && accessToken.isEmpty) {
UserStore.to.logout(); UserStore.to.logout();
// Routes.config.goNamed(Routes.login); // Routes.config.goNamed(Routes.login);
return null; return null;
...@@ -340,15 +331,13 @@ class _RequestInterceptor extends Interceptor { ...@@ -340,15 +331,13 @@ class _RequestInterceptor extends Interceptor {
// 如果刷新成功,返回新的token;如果刷新失败,返回null // 如果刷新成功,返回新的token;如果刷新失败,返回null
return null; return null;
} }
} }
// 缓存拦截器 // 缓存拦截器
class _CacheInterceptor extends Interceptor { class _CacheInterceptor extends Interceptor {
@override @override
void onRequest(RequestOptions options, RequestInterceptorHandler handler) async { void onRequest(
RequestOptions options, RequestInterceptorHandler handler) async {
final cacheEnabled = options.extra['cacheEnabled'] ?? false; final cacheEnabled = options.extra['cacheEnabled'] ?? false;
final status = await Tools.checkCurrentNetStatus(); final status = await Tools.checkCurrentNetStatus();
if (cacheEnabled && !status) { if (cacheEnabled && !status) {
...@@ -389,12 +378,9 @@ class _CacheInterceptor extends Interceptor { ...@@ -389,12 +378,9 @@ class _CacheInterceptor extends Interceptor {
List<int> bytes = utf8.encode(jsonEncode(response.data)); List<int> bytes = utf8.encode(jsonEncode(response.data));
Uint8List uint8List = Uint8List.fromList(bytes); Uint8List uint8List = Uint8List.fromList(bytes);
// 创建一个缓存文件并将数据写入其中 // 创建一个缓存文件并将数据写入其中
DefaultCacheManager().putFile( DefaultCacheManager().putFile(cacheKey, uint8List,
cacheKey,
uint8List,
fileExtension: '.json', // 可以根据需求修改文件扩展名 fileExtension: '.json', // 可以根据需求修改文件扩展名
maxAge: const Duration(hours: 12) maxAge: const Duration(hours: 12));
);
} catch (e) { } catch (e) {
Console.log('Error caching response: $e'); Console.log('Error caching response: $e');
} }
...@@ -402,5 +388,3 @@ class _CacheInterceptor extends Interceptor { ...@@ -402,5 +388,3 @@ class _CacheInterceptor extends Interceptor {
super.onResponse(response, handler); super.onResponse(response, handler);
} }
} }
part of utils; part of utils;
abstract class Access { abstract class Access {
/// 图片权限 /// 图片权限
static Future<bool> photos() async { /// [showExplanation] 是否在申请权限前显示说明对话框
/// [purpose] 权限使用目的说明
/// [context] 上下文,用于显示对话框
static Future<bool> photos({
bool showExplanation = false,
String purpose = '',
BuildContext? context,
}) async {
// 如果需要在申请权限前显示说明,且提供了上下文
if (showExplanation && context != null && purpose.isNotEmpty) {
final bool? shouldRequest = await _showPermissionExplanationDialog(
context: context,
permissionName: Platform.isIOS ? '相册权限' : '存储权限',
purpose: purpose,
);
// 用户取消,不申请权限
if (shouldRequest != true) {
return false;
}
}
if (Platform.isIOS) { if (Platform.isIOS) {
final result = await [Permission.photos].request(); final result = await [Permission.photos].request();
return result[Permission.photos] == PermissionStatus.granted || return result[Permission.photos] == PermissionStatus.granted ||
...@@ -17,11 +37,146 @@ abstract class Access { ...@@ -17,11 +37,146 @@ abstract class Access {
} }
/// 相机权限 /// 相机权限
static Future<bool> camera() async { /// [showExplanation] 是否在申请权限前显示说明对话框
/// [purpose] 权限使用目的说明
/// [context] 上下文,用于显示对话框
static Future<bool> camera({
bool showExplanation = false,
String purpose = '',
BuildContext? context,
}) async {
// 如果需要在申请权限前显示说明,且提供了上下文
if (showExplanation && context != null && purpose.isNotEmpty) {
final bool? shouldRequest = await _showPermissionExplanationDialog(
context: context,
permissionName: '相机权限',
purpose: purpose,
);
// 用户取消,不申请权限
if (shouldRequest != true) {
return false;
}
}
final result = await [Permission.camera].request(); final result = await [Permission.camera].request();
return result[Permission.camera] == PermissionStatus.granted; return result[Permission.camera] == PermissionStatus.granted;
} }
/// 显示权限使用目的说明对话框
/// 对话框不会自动消失,需要用户主动确认
static Future<bool?> _showPermissionExplanationDialog({
required BuildContext context,
required String permissionName,
required String purpose,
}) async {
return await showDialog<bool>(
context: context,
barrierDismissible: false, // 不允许点击外部关闭
builder: (BuildContext dialogContext) {
return WillPopScope(
onWillPop: () async => false, // 不允许返回键关闭
child: AlertDialog(
insetPadding: EdgeInsets.symmetric(horizontal: 40.w),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12.w),
),
title: Text(
'权限申请说明',
style: TextStyle(
fontSize: 18.w,
color: Colours.c3,
fontWeight: Fonts.boldSemi,
),
textAlign: TextAlign.center,
),
content: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'权限名称:',
style: TextStyle(
fontSize: 15.w,
color: Colours.c3,
fontWeight: Fonts.medium,
),
),
SizedBox(height: 5.w),
Text(
permissionName,
style: TextStyle(
fontSize: 15.w,
color: Colours.c6,
),
),
SizedBox(height: 15.w),
Text(
'使用目的:',
style: TextStyle(
fontSize: 15.w,
color: Colours.c3,
fontWeight: Fonts.medium,
),
),
SizedBox(height: 5.w),
Text(
purpose,
style: TextStyle(
fontSize: 15.w,
color: Colours.c6,
height: 1.5,
),
),
],
),
actions: <Widget>[
Row(
children: [
Expanded(
child: TextButton(
onPressed: () {
Navigator.of(dialogContext).pop(false);
},
child: Text(
'取消',
style: TextStyle(
fontSize: 16.w,
color: Colours.c6,
fontWeight: Fonts.medium,
),
),
),
),
Container(
width: 1,
height: 40.w,
color: Colours.cLine,
),
Expanded(
child: TextButton(
onPressed: () {
Navigator.of(dialogContext).pop(true);
},
child: Text(
'确定',
style: TextStyle(
fontSize: 16.w,
color: Colours.cAB1941,
fontWeight: Fonts.boldSemi,
),
),
),
),
],
),
],
),
);
},
);
}
/// 打开设置 /// 打开设置
static Future<void> setting() async => await openAppSettings(); static Future<void> setting() async => await openAppSettings();
...@@ -36,5 +191,4 @@ abstract class Access { ...@@ -36,5 +191,4 @@ abstract class Access {
final result = await [Permission.microphone].request(); final result = await [Permission.microphone].request();
return result[Permission.microphone] == PermissionStatus.granted; return result[Permission.microphone] == PermissionStatus.granted;
} }
} }
...@@ -4,22 +4,47 @@ abstract class AssetsPicker { ...@@ -4,22 +4,47 @@ abstract class AssetsPicker {
static final ImagePicker _imagePicker = ImagePicker(); static final ImagePicker _imagePicker = ImagePicker();
/// 获取图库 /// 获取图库
/// [purpose] 权限使用目的说明,用于在申请权限前告知用户
static Future<XFile?> image({ static Future<XFile?> image({
required BuildContext context, required BuildContext context,
ImageSource source = ImageSource.gallery, ImageSource source = ImageSource.gallery,
double maxWidth = 1024, double maxWidth = 1024,
double maxHeight = 1024, double maxHeight = 1024,
String purpose = '用于从相册中选择图片,用于设置头像、上传图片等功能。',
}) async { }) async {
if (!(await Access.photos())) { // 先检查权限状态
bool hasPermission = false;
if (Platform.isIOS) {
final status = await Permission.photos.status;
hasPermission = status == PermissionStatus.granted || status == PermissionStatus.limited;
} else if (Platform.isAndroid) {
final status = await Permission.storage.status;
hasPermission = status == PermissionStatus.granted;
}
// 如果没有权限,先显示说明对话框,然后申请权限
if (!hasPermission) {
final granted = await Access.photos(
showExplanation: true,
purpose: purpose,
context: context,
);
if (!granted) {
// 用户拒绝或取消,检查是否需要跳转设置
if (context.mounted) { if (context.mounted) {
// CustomDialog.showAccess( final status = Platform.isIOS
// context: context, ? await Permission.photos.status
// content: const Text('获取相册权限'), : await Permission.storage.status;
// );
_showSettingDialog(context,'获取相册权限'); if (status.isPermanentlyDenied) {
_showSettingDialog(context, '获取相册权限');
}
} }
return null; return null;
} }
}
return _imagePicker.pickImage( return _imagePicker.pickImage(
source: source, source: source,
// maxWidth: maxWidth, // maxWidth: maxWidth,
...@@ -27,23 +52,41 @@ abstract class AssetsPicker { ...@@ -27,23 +52,41 @@ abstract class AssetsPicker {
// imageQuality: 100 // imageQuality: 100
); );
} }
/// 拍照 /// 拍照
/// [purpose] 权限使用目的说明,用于在申请权限前告知用户
static Future<XFile?> camera({ static Future<XFile?> camera({
required BuildContext context, required BuildContext context,
ImageSource source = ImageSource.camera, ImageSource source = ImageSource.camera,
double maxWidth = 512, double maxWidth = 512,
double maxHeight = 512, double maxHeight = 512,
String purpose = '用于使用相机拍照,用于设置头像、上传图片等功能。',
}) async { }) async {
if (!(await Access.photos())) { // 先检查权限状态
final cameraStatus = await Permission.camera.status;
bool hasPermission = cameraStatus == PermissionStatus.granted;
// 如果没有相机权限,先显示说明对话框,然后申请权限
if (!hasPermission) {
final granted = await Access.camera(
showExplanation: true,
purpose: purpose,
context: context,
);
if (!granted) {
// 用户拒绝或取消,检查是否需要跳转设置
if (context.mounted) { if (context.mounted) {
// CustomDialog.showAccess( final status = await Permission.camera.status;
// context: context,
// content: const Text('获取拍照权限'), if (status.isPermanentlyDenied) {
// ); _showSettingDialog(context, '获取相机权限');
_showSettingDialog(context,'获取拍照权限'); }
} }
return null; return null;
} }
}
return _imagePicker.pickImage( return _imagePicker.pickImage(
source: source, source: source,
// maxWidth: maxWidth, // maxWidth: maxWidth,
......
part of utils; part of utils;
// 服务器地址 // 服务器地址
// const String kServerUrl = 'http://192.168.11.88:81'; const String kServerUrl = 'https://project-api.ezijing.com/api/book';
// const String kServerUrl = 'http://8.141.148.247:7421'; // const String kServerUrl = 'http://172.16.51.175:7421';
const String kServerUrl = 'https://ebook-app.ezijing.com'; const String kHtmlBaseServer = 'https://webapp-pub.ezijing.com/book-app';
const String kHtmlBaseServer = 'http://150.158.138.40:9200';
const String kLocalToken = 'local_token'; const String kLocalToken = 'local_token';
const String kLocalAccessToken = 'local_access_token'; const String kLocalAccessToken = 'local_access_token';
const String kLocalAccount = 'local_account'; const String kLocalAccount = 'local_account';
const String kLocalPassword = 'local_password'; const String kLocalPassword = 'local_password';
const String kLocalUserInfo = 'local_user_info'; const String kLocalUserInfo = 'local_user_info';
const String kLocalPrivacyNoticeShown = 'local_privacy_notice_shown';
const String kSearchHistory = 'search_history'; const String kSearchHistory = 'search_history';
const String kFailOrder = 'failOrder'; const String kFailOrder = 'failOrder';
const String kNoteTable = 'members_book_notes'; const String kNoteTable = 'members_book_notes';
const String kReadTable = 'read_history'; const String kReadTable = 'read_history';
const String kUserAgreement = '/html/agreement/ser_agreement.html'; const String kUserAgreement = '$kHtmlBaseServer/agreement/ser_agreement.html';
const String kUserPriAgreement = '/html/agreement/pri_agreement.html'; const String kUserPriAgreement =
const String kUserRechargeAgreement = '/html/agreement/rec_agreement.html'; '$kHtmlBaseServer/agreement/pri_agreement.html';
const String kUserRechargeAgreement =
'$kHtmlBaseServer/agreement/rec_agreement.html';
// 错题详情页 html // 错题详情页 html
const String kUserWrongDes = '$kHtmlBaseServer/evaluating_wrong.html'; const String kUserWrongDes = '$kHtmlBaseServer/evaluating_wrong.html';
// 阅读页 html // 阅读页 html
String kReadTestUnderLineBook = '$kHtmlBaseServer/read_unline.html?t=${DateTime.now().millisecondsSinceEpoch}'; String kReadTestUnderLineBook =
'$kHtmlBaseServer/read_unline.html?t=${DateTime.now().millisecondsSinceEpoch}';
const String kReadBook = '$kHtmlBaseServer/read.html'; const String kReadBook = '$kHtmlBaseServer/read.html';
// 答题页 // 答题页
const String kAnswer = '$kHtmlBaseServer/evaluating.html'; const String kAnswer = '$kHtmlBaseServer/evaluating.html';
...@@ -33,18 +36,17 @@ const String kReadInfo = '$kHtmlBaseServer/read_info.html'; ...@@ -33,18 +36,17 @@ const String kReadInfo = '$kHtmlBaseServer/read_info.html';
// 阅读页 图片预览 // 阅读页 图片预览
const String kScaleImage = '$kHtmlBaseServer/read_img.html'; const String kScaleImage = '$kHtmlBaseServer/read_img.html';
abstract class C { abstract class C {
static const String localAccount = 'storage_account'; static const String localAccount = 'storage_account';
static const String localThemeMode = 'storage_theme_mode'; static const String localThemeMode = 'storage_theme_mode';
static const String localLanguage = 'storage_lang'; static const String localLanguage = 'storage_lang';
/// 自动主题 /// 自动主题
static const String themeSystem = '0'; static const String themeSystem = '0';
/// 亮色主题 /// 亮色主题
static const String themeLight = '1'; static const String themeLight = '1';
/// 暗色主题 /// 暗色主题
static const String themeDark = '2'; static const String themeDark = '2';
} }
...@@ -49,14 +49,6 @@ packages: ...@@ -49,14 +49,6 @@ packages:
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "0.1.18" version: "0.1.18"
azlistview:
dependency: "direct main"
description:
name: azlistview
sha256: "93e865f11777a271b439f0d6b00799c0797e9daeec2e082a2e01373809c4b90d"
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.0.0"
badges: badges:
dependency: "direct main" dependency: "direct main"
description: description:
...@@ -262,14 +254,6 @@ packages: ...@@ -262,14 +254,6 @@ packages:
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "3.0.4" version: "3.0.4"
flutter_bugly:
dependency: "direct main"
description:
name: flutter_bugly
sha256: a2d13cb35bedb907cb020ea4862264dcc9044675a49a8313bb3ab2e61af79c77
url: "https://pub.flutter-io.cn"
source: hosted
version: "0.4.4"
flutter_cache_manager: flutter_cache_manager:
dependency: "direct main" dependency: "direct main"
description: description:
...@@ -549,14 +533,6 @@ packages: ...@@ -549,14 +533,6 @@ packages:
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "0.18.0" version: "0.18.0"
ionicons:
dependency: "direct main"
description:
name: ionicons
sha256: "5496bc65a16115ecf05b15b78f494ee4a8869504357668f0a11d689e970523cf"
url: "https://pub.flutter-io.cn"
source: hosted
version: "0.2.2"
js: js:
dependency: transitive dependency: transitive
description: description:
...@@ -837,14 +813,6 @@ packages: ...@@ -837,14 +813,6 @@ packages:
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "6.1.2" version: "6.1.2"
pull_to_refresh_flutter3:
dependency: "direct main"
description:
name: pull_to_refresh_flutter3
sha256: "223a6241067162dc15cf8c46c05af998ce7aa85e0703d8f696101eb1b5629d76"
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.0.1"
rational: rational:
dependency: transitive dependency: transitive
description: description:
...@@ -869,22 +837,6 @@ packages: ...@@ -869,22 +837,6 @@ packages:
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "0.26.0" version: "0.26.0"
screen_protector:
dependency: "direct main"
description:
name: screen_protector
sha256: "541bdcd341de1e38026b5b94cc2a74cd95299d2c51150735165c4b445fa0209a"
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.4.2"
scrollable_positioned_list:
dependency: transitive
description:
name: scrollable_positioned_list
sha256: "9566352ab9ba05794ee6c8864f154afba5d36c5637d0e3e32c615ba4ceb92772"
url: "https://pub.flutter-io.cn"
source: hosted
version: "0.2.3"
shared_preferences: shared_preferences:
dependency: "direct main" dependency: "direct main"
description: description:
......
name: flutter_book name: flutter_book
description: 紫荆数智学堂 description: 清控紫荆数智学堂
# The following line prevents the package from being accidentally published to # The following line prevents the package from being accidentally published to
# pub.dev using `flutter pub publish`. This is preferred for private packages. # pub.dev using `flutter pub publish`. This is preferred for private packages.
publish_to: 'none' # Remove this line if you wish to publish to pub.dev publish_to: 'none' # Remove this line if you wish to publish to pub.dev
...@@ -39,7 +39,6 @@ dependencies: ...@@ -39,7 +39,6 @@ dependencies:
flutter_localizations: flutter_localizations:
sdk: flutter sdk: flutter
# The following adds the Cupertino Icons font to your application. # The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons. # Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^1.0.2 cupertino_icons: ^1.0.2
...@@ -53,11 +52,8 @@ dependencies: ...@@ -53,11 +52,8 @@ dependencies:
shared_preferences: 2.1.1 shared_preferences: 2.1.1
# 屏幕适配 # 屏幕适配
flutter_screenutil: 5.8.2 flutter_screenutil: 5.8.2
pull_to_refresh_flutter3: 2.0.1
# 加载图片 # 加载图片
extended_image: 8.0.2 extended_image: 8.0.2
# 图标库
ionicons: 0.2.2
# 网络 # 网络
dio: 5.3.3 dio: 5.3.3
crypto: 3.0.3 crypto: 3.0.3
...@@ -97,8 +93,6 @@ dependencies: ...@@ -97,8 +93,6 @@ dependencies:
package_info_plus: ^4.2.0 package_info_plus: ^4.2.0
# 版本更新 # 版本更新
flutter_app_update: ^3.0.4 flutter_app_update: ^3.0.4
# 能指定滑动位置的listView
azlistview: ^2.0.0
# 支付宝 # 支付宝
tobias: ^3.3.0 tobias: ^3.3.0
# 内购 # 内购
...@@ -120,12 +114,8 @@ dependencies: ...@@ -120,12 +114,8 @@ dependencies:
# 安卓 # 安卓
android_id: ^0.3.6 android_id: ^0.3.6
# 防止截屏 # 防止截屏
# secure_application: ^3.8.0 # secure_application: ^3.8.0
screen_protector: ^1.4.2 # sentry_flutter: ^7.19.0
# sentry_flutter: ^7.19.0
flutter_bugly: ^0.4.4
dev_dependencies: dev_dependencies:
flutter_test: flutter_test:
...@@ -143,7 +133,6 @@ dev_dependencies: ...@@ -143,7 +133,6 @@ dev_dependencies:
# The following section is specific to Flutter packages. # The following section is specific to Flutter packages.
flutter: flutter:
# The following line ensures that the Material Icons font is # The following line ensures that the Material Icons font is
# included with your application, so that you can use the icons in # included with your application, so that you can use the icons in
# the material Icons class. # the material Icons class.
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论