init
@@ -1,6 +1,6 @@
|
|||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
<application
|
<application
|
||||||
android:label="flutter_jdt_store"
|
android:label="捷兑通-商家端"
|
||||||
android:name="${applicationName}"
|
android:name="${applicationName}"
|
||||||
android:icon="@mipmap/ic_launcher">
|
android:icon="@mipmap/ic_launcher">
|
||||||
<activity
|
<activity
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 544 B After Width: | Height: | Size: 4.4 KiB |
BIN
android/app/src/main/res/mipmap-ldpi/ic_launcher.png
Normal file
|
After Width: | Height: | Size: 1.7 KiB |
|
Before Width: | Height: | Size: 442 B After Width: | Height: | Size: 2.6 KiB |
|
Before Width: | Height: | Size: 721 B After Width: | Height: | Size: 7.0 KiB |
|
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 22 KiB |
BIN
assets/images/logo.png
Normal file
|
After Width: | Height: | Size: 20 KiB |
@@ -4,6 +4,7 @@ import 'package:flutter_easyloading/flutter_easyloading.dart';
|
|||||||
import 'package:flutter_jdt_store/router/app_pages.dart';
|
import 'package:flutter_jdt_store/router/app_pages.dart';
|
||||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||||
import 'package:statusbarz/statusbarz.dart';
|
import 'package:statusbarz/statusbarz.dart';
|
||||||
|
import 'package:bot_toast/bot_toast.dart';
|
||||||
|
|
||||||
import 'global.dart';
|
import 'global.dart';
|
||||||
import 'utils/utils.dart';
|
import 'utils/utils.dart';
|
||||||
@@ -29,6 +30,9 @@ class MainApp extends StatelessWidget {
|
|||||||
return ScreenUtilInit(
|
return ScreenUtilInit(
|
||||||
designSize: const Size(390, 844), // iPhone 13尺寸
|
designSize: const Size(390, 844), // iPhone 13尺寸
|
||||||
builder: ([BuildContext? _, __]) {
|
builder: ([BuildContext? _, __]) {
|
||||||
|
/// 初始化Toast
|
||||||
|
final botToastBuilder = BotToastInit();
|
||||||
|
|
||||||
return GetMaterialApp(
|
return GetMaterialApp(
|
||||||
debugShowCheckedModeBanner: false,
|
debugShowCheckedModeBanner: false,
|
||||||
// 日志
|
// 日志
|
||||||
@@ -39,18 +43,20 @@ class MainApp extends StatelessWidget {
|
|||||||
getPages: AppPages.routes,
|
getPages: AppPages.routes,
|
||||||
navigatorObservers: [
|
navigatorObservers: [
|
||||||
Global.routeObserver,
|
Global.routeObserver,
|
||||||
Statusbarz.instance.observer
|
Statusbarz.instance.observer,
|
||||||
|
BotToastNavigatorObserver()
|
||||||
],
|
],
|
||||||
// 启动页面
|
// 启动页面
|
||||||
initialRoute: AppPages.initial,
|
initialRoute: AppPages.initial,
|
||||||
initialBinding: InitialBinding(),
|
initialBinding: InitialBinding(),
|
||||||
builder: (context, widget) {
|
builder: (context, widget) {
|
||||||
return MediaQuery(
|
widget = MediaQuery(
|
||||||
///设置文字大小不随系统设置改变
|
|
||||||
data: MediaQuery.of(context)
|
data: MediaQuery.of(context)
|
||||||
.copyWith(textScaler: const TextScaler.linear(1.0)),
|
.copyWith(textScaler: const TextScaler.linear(1.0)),
|
||||||
child: FlutterEasyLoading(child: widget),
|
child: FlutterEasyLoading(child: widget),
|
||||||
);
|
);
|
||||||
|
widget = botToastBuilder(context, widget);
|
||||||
|
return widget;
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|||||||
10
lib/pages/login/binding.dart
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
import 'package:get/get.dart';
|
||||||
|
|
||||||
|
import 'logic.dart';
|
||||||
|
|
||||||
|
class LoginBinding extends Bindings {
|
||||||
|
@override
|
||||||
|
void dependencies() {
|
||||||
|
Get.lazyPut(() => LoginLogic());
|
||||||
|
}
|
||||||
|
}
|
||||||
6
lib/pages/login/index.dart
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
library login;
|
||||||
|
|
||||||
|
export './logic.dart';
|
||||||
|
export './state.dart';
|
||||||
|
export './view.dart';
|
||||||
|
export './binding.dart';
|
||||||
20
lib/pages/login/logic.dart
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
import 'dart:io';
|
||||||
|
import 'package:bot_toast/bot_toast.dart';
|
||||||
|
import 'package:get/get.dart';
|
||||||
|
import 'state.dart';
|
||||||
|
|
||||||
|
class LoginLogic extends GetxController {
|
||||||
|
final LoginState state = LoginState();
|
||||||
|
|
||||||
|
void isExit(context) {
|
||||||
|
if (state.lastPressedAt == null ||
|
||||||
|
DateTime.now().difference(state.lastPressedAt!) >
|
||||||
|
const Duration(seconds: 1)) {
|
||||||
|
//两次点击间隔超过1秒则重新计时
|
||||||
|
state.lastPressedAt = DateTime.now();
|
||||||
|
BotToast.showText(text:"再按一次退出程序");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
7
lib/pages/login/state.dart
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
class LoginState {
|
||||||
|
DateTime? lastPressedAt; //上次点击时间
|
||||||
|
|
||||||
|
LoginState() {
|
||||||
|
///Initialize variables
|
||||||
|
}
|
||||||
|
}
|
||||||
27
lib/pages/login/view.dart
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:get/get.dart';
|
||||||
|
|
||||||
|
import 'logic.dart';
|
||||||
|
|
||||||
|
class LoginPage extends StatelessWidget {
|
||||||
|
LoginPage({Key? key}) : super(key: key);
|
||||||
|
|
||||||
|
final logic = Get.find<LoginLogic>();
|
||||||
|
final state = Get.find<LoginLogic>().state;
|
||||||
|
|
||||||
|
DateTime? _lastPressedAt;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return PopScope(
|
||||||
|
canPop: false,
|
||||||
|
onPopInvoked: (_) {
|
||||||
|
logic.isExit(context);
|
||||||
|
},
|
||||||
|
child: const Scaffold(
|
||||||
|
body: Center(
|
||||||
|
child: Text("login"),
|
||||||
|
),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,24 +1,64 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:tdesign_flutter/tdesign_flutter.dart';
|
|
||||||
|
|
||||||
import 'splash_state.dart';
|
import 'splash_state.dart';
|
||||||
|
|
||||||
class SplashLogic extends GetxController {
|
import '../../utils/utils.dart';
|
||||||
|
|
||||||
|
class SplashLogic extends GetxController with GetTickerProviderStateMixin {
|
||||||
final SplashState state = SplashState();
|
final SplashState state = SplashState();
|
||||||
|
|
||||||
|
late AnimationController animationController;
|
||||||
|
late Animation<Offset> animation;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void onInit() {
|
||||||
|
super.onInit();
|
||||||
|
|
||||||
|
initAnimation();
|
||||||
|
|
||||||
|
animationController.forward();
|
||||||
|
|
||||||
|
isLoginFn();
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void onReady() {
|
void onReady() {
|
||||||
// TODO: implement onReady
|
debugPrint('onReady');
|
||||||
super.onReady();
|
super.onReady();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void onClose() {
|
void onClose() {
|
||||||
// TODO: implement onClose
|
animationController.dispose();
|
||||||
super.onClose();
|
super.onClose();
|
||||||
}
|
}
|
||||||
|
|
||||||
void showText(context) {
|
void initAnimation() {
|
||||||
TDToast.showText('轻提示文字内容', context: context);
|
animationController = AnimationController(
|
||||||
|
vsync: this,
|
||||||
|
duration: const Duration(seconds: 1),
|
||||||
|
);
|
||||||
|
|
||||||
|
animation = Tween<Offset>(
|
||||||
|
begin: const Offset(0.0, 1.0),
|
||||||
|
end: Offset.zero,
|
||||||
|
).animate(CurvedAnimation(
|
||||||
|
parent: animationController,
|
||||||
|
curve: Curves.easeInOut,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> isLoginFn() async {
|
||||||
|
// 倒计时3秒
|
||||||
|
await Future.delayed(const Duration(seconds: 3), () {
|
||||||
|
final token = StorageUtil().getString("token");
|
||||||
|
if (!ToolFn.isBlank(token)) {
|
||||||
|
Get.offAllNamed('/home');
|
||||||
|
} else {
|
||||||
|
Get.offAllNamed('/login');
|
||||||
|
// Get.toNamed('/login');
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:tdesign_flutter/tdesign_flutter.dart';
|
|
||||||
import 'splash_logic.dart';
|
import 'splash_logic.dart';
|
||||||
|
|
||||||
class SplashPage extends StatefulWidget {
|
class SplashPage extends StatefulWidget {
|
||||||
@@ -18,19 +17,30 @@ class _SplashPageState extends State<SplashPage> {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
body: Center(
|
body: Center(
|
||||||
child: Column(
|
child: SlideTransition(
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
position: logic.animation,
|
||||||
children: [
|
child: Column(
|
||||||
const Text("Splash"),
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
TDButton(
|
children: [
|
||||||
theme: TDButtonTheme.primary,
|
ClipRRect(
|
||||||
text: "立即登录",
|
borderRadius: BorderRadius.circular(10),
|
||||||
onTap: () {
|
child: Image.asset(
|
||||||
logic.showText(context);
|
"assets/images/logo.png",
|
||||||
},
|
width: 120,
|
||||||
),
|
),
|
||||||
],
|
),
|
||||||
),
|
const Padding(
|
||||||
|
padding: EdgeInsets.only(top: 10),
|
||||||
|
),
|
||||||
|
const Text(
|
||||||
|
"捷兑通-商家版",
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 20,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import '../pages/splash/index.dart';
|
import '../pages/splash/index.dart';
|
||||||
|
import '../pages/login/index.dart';
|
||||||
|
|
||||||
class AppPages {
|
class AppPages {
|
||||||
static const String initial = '/';
|
static const String initial = '/';
|
||||||
@@ -11,7 +12,8 @@ class AppPages {
|
|||||||
name: AppPages.initial,
|
name: AppPages.initial,
|
||||||
page: () => const SplashPage(),
|
page: () => const SplashPage(),
|
||||||
binding: SplashBinding()),
|
binding: SplashBinding()),
|
||||||
// GetPage(name: AppPages.login, page: () => LoginPage()),
|
GetPage(
|
||||||
|
name: AppPages.login, page: () => LoginPage(), binding: LoginBinding()),
|
||||||
// GetPage(name: AppPages.home, page: () => HomePage()),
|
// GetPage(name: AppPages.home, page: () => HomePage()),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|||||||
9
lib/utils/tool.dart
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
class ToolFn {
|
||||||
|
// 字符串是否为空
|
||||||
|
static bool isBlank(String? str) {
|
||||||
|
if (str == null || str.isEmpty) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,4 +2,5 @@ library utils;
|
|||||||
|
|
||||||
export 'logger.dart';
|
export 'logger.dart';
|
||||||
export 'status_bar.dart';
|
export 'status_bar.dart';
|
||||||
export 'storage.dart';
|
export 'storage.dart';
|
||||||
|
export 'tool.dart';
|
||||||
@@ -25,6 +25,14 @@ packages:
|
|||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.1"
|
version: "2.1.1"
|
||||||
|
bot_toast:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: bot_toast
|
||||||
|
sha256: "6b93030a99a98335b8827ecd83021e92e885ffc61d261d3825ffdecdd17f3bdf"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "4.1.3"
|
||||||
characters:
|
characters:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ environment:
|
|||||||
sdk: '>=3.2.3 <4.0.0'
|
sdk: '>=3.2.3 <4.0.0'
|
||||||
|
|
||||||
dependencies:
|
dependencies:
|
||||||
|
bot_toast: ^4.1.3
|
||||||
device_info_plus: ^9.1.1
|
device_info_plus: ^9.1.1
|
||||||
dio: ^5.4.0
|
dio: ^5.4.0
|
||||||
easy_refresh: ^3.3.3+1
|
easy_refresh: ^3.3.3+1
|
||||||
@@ -27,3 +28,5 @@ dev_dependencies:
|
|||||||
|
|
||||||
flutter:
|
flutter:
|
||||||
uses-material-design: true
|
uses-material-design: true
|
||||||
|
assets:
|
||||||
|
- assets/images/logo.png
|
||||||