提交 1f915716 authored 作者: yueweilu's avatar yueweilu

登录逻辑

上级 84953177
assets/images/3.0x/mine.png

1.8 KB | W: | H:

assets/images/3.0x/mine.png

1.5 KB | W: | H:

assets/images/3.0x/mine.png
assets/images/3.0x/mine.png
assets/images/3.0x/mine.png
assets/images/3.0x/mine.png
  • 2-up
  • Swipe
  • Onion skin
assets/images/mine.png

1.5 KB | W: | H:

assets/images/mine.png

422 Bytes | W: | H:

assets/images/mine.png
assets/images/mine.png
assets/images/mine.png
assets/images/mine.png
  • 2-up
  • Swipe
  • Onion skin
part of apis;
abstract class AccountAPI {
/// 登录
static Future <UserModel> login({
required String phone,
required String password,
required String type,
String? password,
String? code,
}) async {
assert((password != null && code == null) ||
(password == null && code != null),
'Provide either a password or a verification code, not both.');
Map<String,dynamic> params = {
'phone' : phone,
'type' : type,
};
// 密码登录
if(type == '1'){
params['password'] = password;
}
// 验证码登录
if(type == '2'){
params['password'] = password;
}
final result = await HttpService.to.post(
'/v1/members/login/login',
excludeToken: true,
showLoading: true,
params: {
'phone': phone,
'password': password,
'type': type
},
params: params
);
print(result.data);
if (result.data is! Map) return UserModel();
return UserModel.fromJson(result.data);
}
/// 发送验证码
static Future sendCode({
required String phone,
required String type,
}) async {
final result = await HttpService.to.post(
'/v1/members/login/sendCode',
excludeToken: true,
showLoading: true,
);
}
}
\ No newline at end of file
......@@ -14,6 +14,8 @@ class Global {
// 配置存储
Get.putAsync<StorageService>(() => StorageService().init()),
]).whenComplete(() {
print('初始化****************');
// 网络
Get.put<HttpService>(HttpService());
//配置基本设置
......
......@@ -16,7 +16,14 @@ import 'package:flutter_localizations/flutter_localizations.dart';
import 'global.dart';
void main() {
Global.init().then((_) => runApp(const MyApp()));
Global.init().then((_) {
Future.wait([
UserStore.to.profile(),
]).whenComplete(() {
runApp(const MyApp());
//FlutterNativeSplash.remove();
});
});
SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle.light);
}
......
......@@ -101,40 +101,34 @@ class LoginController extends GetxController {
update();
}
Future<bool> onLogin(GlobalKey<FormState> key) async {
/// 登录
void onLogin(BuildContext context) async {
print(EncryptUtil.encodeMd5(EncryptUtil.encodeMd5(passwordInput.text)));
final result = await AccountAPI.login(
phone: phoneInput.text,
password: EncryptUtil.encodeMd5(EncryptUtil.encodeMd5(passwordInput.text)),
type: '1'
);
print(result);
if((result.token ?? '').isEmpty) return;
/// 存储账号密码
StorageService.to.setString(kLocalAccount, 'phone');
StorageService.to.setString(kLocalPassword, 'password');
/// 存储用户信息
// 存储用户信息
await Future.wait([
UserStore.to.setToken(''),
UserStore.to.setToken(result.token!),
UserStore.to.setAccessToken(result.accessToken!),
]);
await Future.wait([
UserStore.to.setInfo(result),
UserStore.to.profile(),
]);
// if (!context.mounted) return;
// if (context.canPop()){
// context.pop();
// }else {
// context.goNamed(Routes.main);
// }
return true;
if (!context.mounted) return;
if (context.canPop()){
context.pop();
}else {
context.goNamed(Routes.main);
}
}
......
......@@ -19,190 +19,190 @@ class _LoginPageState extends State<LoginPage> {
init: LoginController(),
builder:(controller) => GestureDetector(
onTap: () => Tools.unfocus(),
child: Scaffold(
resizeToAvoidBottomInset:true,
appBar: CustomAppBar(
systemOverlayStyle: Theme.of(context).brightness == Brightness.light
? SystemUiOverlayStyle.dark
: SystemUiOverlayStyle.light,
backgroundColor: Colors.transparent,
),
// extendBodyBehindAppBar: true,
body: SafeArea(
top: false,
minimum: const EdgeInsets.all(AppTheme.margin).copyWith(
// top:Screen.statusBar,
left: 25,
right: 25,
bottom: 25
),
child: Column(
child: Container(
color: Colors.white,
child: Stack(
children: [
Expanded(
child: SingleChildScrollView(
child: Form(
autovalidateMode: AutovalidateMode.always,
onChanged: (){
setState(() {
print('++++++++++++++++');
});
},
key: _formKey,
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Column(
// crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
const SizedBox(height: 120,),
Container(
width: 180,
height: 50,
// color: Colors.cyan,
child: Image.asset(
'assets/images/zijing_icon.png',
),
),
const SizedBox(height:66),
//
CustomFormInput(
// label: 'Phone',
// required: true,
hintText: '请输入手机号',
keyboardType: TextInputType.number,
controller: controller.phoneInput,
onChanged: (text){
controller.setCanClick();
},
),
Gaps.vGaps13,
(controller.loginType == 0)?
ValueListenableBuilder<bool>(
valueListenable: controller.showPassword,
builder:(context, value, child) => CustomFormInput(
obscureText: !value,
hintText: '请输入密码',
iconData:
value ? Icons.visibility : Icons.visibility_off,
controller: controller.passwordInput,
onChanged: (text){
controller.setCanClick();
},
onIcon: controller.onShowPassword,
),
):Stack(
alignment: Alignment.centerRight,
children: [
CustomFormInput(
// label: 'Phone',
// required: true,
hintText: '请输入验证码',
keyboardType: TextInputType.number,
controller: controller.codeInput,
),
Positioned(
right: 10,
child: Row(
children: [
Container(height: 20,width: 1,color: const Color(0xFFEBEBEB),),
Gaps.hGaps10,
GestureDetector(
child: Container(
padding: const EdgeInsets.symmetric(vertical: 10),
color: Colors.yellow,
child: Text(controller.isCounting?'${controller.countDown}':'获取验证码',style: const TextStyle(fontSize: 11,color: AppTheme.primary,height: 1.4),)),
onTap: (){
controller.start();
},
),
],
)
)
],
),
Container(
margin: const EdgeInsets.only(left: 10,right: 10,top: 8.5),
alignment: Alignment.centerLeft,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
Image.asset(
'assets/images/login_bg.png',
),
SafeArea(
top: false,
minimum: const EdgeInsets.all(AppTheme.margin).copyWith(
// top:Screen.statusBar,
left: 25,
right: 25,
bottom: 25
),
child: Column(
children: [
Expanded(
child: SingleChildScrollView(
child: Form(
autovalidateMode: AutovalidateMode.always,
onChanged: (){
setState(() {
print('++++++++++++++++');
});
},
key: _formKey,
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Column(
// crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
controller.loginType == 0? GestureDetector(
child: const Text('验证码登录',style: TextStyle(fontSize: 13,height: 1.3,color: Colours.c6),),
onTap: (){
controller.updateLoginType(1);
},
):GestureDetector(
child: const Text('密码登录',style: TextStyle(fontSize: 13,height: 1.3,color: Colours.c6),),
onTap: (){
controller.updateLoginType(0);
const SizedBox(height: 120,),
Container(
width: 180,
height: 50,
// color: Colors.cyan,
child: Image.asset(
'assets/images/zijing_icon.png',
),
),
const SizedBox(height:66),
//
CustomFormInput(
// label: 'Phone',
// required: true,
hintText: '请输入手机号',
keyboardType: TextInputType.number,
controller: controller.phoneInput,
onChanged: (text){
controller.setCanClick();
},
),
controller.loginType == 0? GestureDetector(
child: const Text('忘记密码',style: TextStyle(fontSize: 13,height: 1.3,color: Colours.cBlue),),
onTap: (){
context.pushNamed(Routes.forgetPwd);
Gaps.vGaps13,
(controller.loginType == 0)?
ValueListenableBuilder<bool>(
valueListenable: controller.showPassword,
builder:(context, value, child) => CustomFormInput(
obscureText: !value,
hintText: '请输入密码',
iconData:
value ? Icons.visibility : Icons.visibility_off,
controller: controller.passwordInput,
onChanged: (text){
controller.setCanClick();
},
onIcon: controller.onShowPassword,
),
):Stack(
alignment: Alignment.centerRight,
children: [
CustomFormInput(
// label: 'Phone',
// required: true,
hintText: '请输入验证码',
keyboardType: TextInputType.number,
controller: controller.codeInput,
),
Positioned(
right: 10,
child: Row(
children: [
Container(height: 20,width: 1,color: const Color(0xFFEBEBEB),),
Gaps.hGaps10,
GestureDetector(
child: Container(
padding: const EdgeInsets.symmetric(vertical: 10),
color: Colors.yellow,
child: Text(controller.isCounting?'${controller.countDown}':'获取验证码',style: const TextStyle(fontSize: 11,color: AppTheme.primary,height: 1.4),)),
onTap: (){
controller.start();
},
),
],
)
)
],
),
Container(
margin: const EdgeInsets.only(left: 10,right: 10,top: 8.5),
alignment: Alignment.centerLeft,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
controller.loginType == 0? GestureDetector(
child: const Text('验证码登录',style: TextStyle(fontSize: 13,height: 1.3,color: Colours.c6),),
onTap: (){
controller.updateLoginType(1);
},
):GestureDetector(
child: const Text('密码登录',style: TextStyle(fontSize: 13,height: 1.3,color: Colours.c6),),
onTap: (){
controller.updateLoginType(0);
},
),
controller.loginType == 0? GestureDetector(
child: const Text('忘记密码',style: TextStyle(fontSize: 13,height: 1.3,color: Colours.cBlue),),
onTap: (){
context.pushNamed(Routes.forgetPwd);
},
):const Text('*登录后将自动完成注册',style: TextStyle(fontSize: 13,height: 1.3,color: Colours.c6),),
],
)
),
const SizedBox(height: 30,),
CustomGradientButton(
text: '立即登录',
isEnabled: controller.enable,
onPressed: () {
print('11111111111111111');
controller.onLogin(context);
},
):const Text('*登录后将自动完成注册',style: TextStyle(fontSize: 13,height: 1.3,color: Colours.c6),),
)
],
)
),
const SizedBox(height: 30,),
CustomGradientButton(
text: '立即登录',
isEnabled: controller.enable,
onPressed: () {
print('11111111111111111');
controller.onLogin(_formKey);
},
)
],
),
),
],
],
),
),
),
),
),
),
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
GestureDetector(
onTap: (){
///TODO: 同意协议
},
child: Row(
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
width: 10.w,
height: 10.w,
color: AppTheme.primary,
GestureDetector(
onTap: (){
///TODO: 同意协议
},
child: Row(
children: [
Container(
width: 10.w,
height: 10.w,
color: AppTheme.primary,
),
Gaps.hGaps10,
const Text('我已阅读并同意',style: TextStyle(color: Colours.c9,fontSize:10)),
],
),
),
GestureDetector(
child: const Text('《用户协议》',style: TextStyle(color: Colours.cBlue,fontSize:10)),
onTap: (){
context.pushNamed(Routes.terms);
},
),
GestureDetector(
child: const Text('《隐私政策》',style: TextStyle(color: Colours.cBlue,fontSize:10)),
onTap: (){
context.pushNamed(Routes.terms);
},
),
Gaps.hGaps10,
const Text('我已阅读并同意',style: TextStyle(color: Colours.c9,fontSize:10)),
],
),
),
GestureDetector(
child: const Text('《用户协议》',style: TextStyle(color: Colours.cBlue,fontSize:10)),
onTap: (){
context.pushNamed(Routes.terms);
},
),
GestureDetector(
child: const Text('《隐私政策》',style: TextStyle(color: Colours.cBlue,fontSize:10)),
onTap: (){
context.pushNamed(Routes.terms);
},
),
],
)
)
],
),
),
],
),
)
)
),
)
);
);
}
}
......@@ -6,8 +6,11 @@ import 'package:flutter_book/pages/library/index.dart';
import 'package:flutter_book/pages/mine/index.dart';
import 'package:flutter_book/theme.dart';
import 'package:get/get.dart';
import 'package:go_router/go_router.dart';
import 'package:ionicons/ionicons.dart';
import '../../routes/index.dart';
import '../../store/index.dart';
import '../../widgets/index.dart';
import '../book_shop/index.dart';
import '../course/index.dart';
......
......@@ -50,7 +50,11 @@ class _MainPageState extends State<MainPage> with WidgetsBindingObserver{
builder: (controller) => BottomNavigationBar(
currentIndex:controller.currentPage ,
onTap: (page){
controller.pageController.jumpToPage(page);
if (page != 0 && !UserStore.to.isLogin) {
context.pushNamed(Routes.login);
} else {
controller.pageController.jumpToPage(page);
}
},
items: [
BottomNavigationBarItem(
......
......@@ -22,6 +22,7 @@ import 'package:flutter_book/pages/web/index.dart';
import 'package:go_router/go_router.dart';
import '../pages/user_terms/index.dart';
import '../store/index.dart';
part 'observers.dart';
......
......@@ -62,6 +62,7 @@ abstract class Routes {
// initialLocation: '/$login',
initialLocation: '/',
observers: [observer],
// redirect: _RouteRedirect.auth,
routes: [
GoRoute(
path: '/$splash',
......@@ -230,4 +231,11 @@ abstract class Routes {
]
);
}
abstract class _RouteRedirect {
static String? auth(BuildContext context, GoRouterState state) {
if (UserStore.to.isLogin) return null;
return '/${Routes.login}';
}
}
\ No newline at end of file
library store;
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter_book/services/index.dart';
import 'package:flutter_book/theme.dart';
import 'package:get/get.dart';
import '../models/user_model.dart';
import '../utils/index.dart';
part 'config.dart';
......
......@@ -6,11 +6,21 @@ class UserStore extends GetxController {
// 是否登录
bool _isLogin = false;
String _token = '';
String get token => _token;
String _accessToken = '';
String get accessToken => _accessToken;
bool get isLogin=> _isLogin;
bool get hasToken => _token.isNotEmpty;
UserModel _info = UserModel();
UserModel get info => _info;
@override
......@@ -24,14 +34,32 @@ class UserStore extends GetxController {
_token = value;
}
Future<void> setAccessToken(String value) async {
await StorageService.to.setString(kLocalAccessToken, value);
_accessToken = value;
}
Future<void> setInfo(UserModel value) async {
await StorageService.to.setString(kLocalUserInfo, jsonEncode(value.toJson()));
_info = value;
}
// 登出
Future<void> logout() async {
await StorageService.to.remove(kLocalToken);
await StorageService.to.remove(kLocalAccessToken);
await StorageService.to.remove(kLocalUserInfo);
_token = '';
_isLogin = false;
}
Future<void> profile() async {
print('toknen----------------------: ' + _token);
if (!hasToken) return;
_isLogin = true;
update();
}
}
\ No newline at end of file
......@@ -186,8 +186,8 @@ abstract class AppTheme {
backgroundColor: Colors.white,
unselectedItemColor: scheme.onBackground.withOpacity(0.5),
selectedItemColor: scheme.primary,
unselectedLabelStyle: TextStyle(fontSize: 10.w, height: 1.6),
selectedLabelStyle: TextStyle(fontSize: 10.w, height: 1.6),
unselectedLabelStyle: TextStyle(fontSize: 11.w,fontWeight: Fonts.medium),
selectedLabelStyle: TextStyle(fontSize: 11.w,fontWeight: Fonts.medium),
unselectedIconTheme: IconThemeData(
size: 15.w,
color: scheme.onBackground.withOpacity(0.5),
......
......@@ -2,10 +2,10 @@ part of utils;
class AppConfig{
//app在服务端注册的id,由后端直接提供
static const String AppID = 'ZTxGRWl6F6erl330';
static const String AppID = 'dkFv6OwWyQhSeaZG';
//app在服务端的秘钥串,由后端直接提供
static const String AppSecret = '0a6521b67cbd5397ce641f791f284bb7';
static const String AppSecret = 'd34cea92316d1da113e95158bed9ca97';
//签名时使用的加密串,由后端直接提供
static const String AppEncodeKey = 'J2h8a9zK0z%a-k2z';
static const String AppEncodeKey = '&4F6g4Y6b5L4R9';
}
......@@ -5,8 +5,11 @@ part of utils;
const String kServerUrl = 'http://192.168.11.88:81';
const String kLocalToken = 'local_token';
const String kLocalAccessToken = 'local_access_token';
const String kLocalAccount = 'local_account';
const String kLocalPassword = 'local_password';
const String kLocalUserInfo = 'local_user_info';
abstract class C {
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论