Commit 8fcf01e0 authored by 关振斌's avatar 关振斌

pay

parent d91de89f
......@@ -73,6 +73,8 @@ PODS:
- flutter_inappwebview/Core (0.0.1):
- Flutter
- OrderedSet (~> 5.0)
- fluttercontactpicker (4.6.0):
- Flutter
- fluttertoast (0.0.2):
- Flutter
- Toast
......@@ -127,6 +129,7 @@ DEPENDENCIES:
- flutter_icmp_ping (from `.symlinks/plugins/flutter_icmp_ping/ios`)
- flutter_inapp_purchase (from `.symlinks/plugins/flutter_inapp_purchase/ios`)
- flutter_inappwebview (from `.symlinks/plugins/flutter_inappwebview/ios`)
- fluttercontactpicker (from `.symlinks/plugins/fluttercontactpicker/ios`)
- fluttertoast (from `.symlinks/plugins/fluttertoast/ios`)
- image_picker_ios (from `.symlinks/plugins/image_picker_ios/ios`)
- open_filex (from `.symlinks/plugins/open_filex/ios`)
......@@ -172,6 +175,8 @@ EXTERNAL SOURCES:
:path: ".symlinks/plugins/flutter_inapp_purchase/ios"
flutter_inappwebview:
:path: ".symlinks/plugins/flutter_inappwebview/ios"
fluttercontactpicker:
:path: ".symlinks/plugins/fluttercontactpicker/ios"
fluttertoast:
:path: ".symlinks/plugins/fluttertoast/ios"
image_picker_ios:
......@@ -205,6 +210,7 @@ SPEC CHECKSUMS:
flutter_icmp_ping: 2b159955eee0c487c766ad83fec224ae35e7c935
flutter_inapp_purchase: 5c6a1ac3f11b11d0c8c0321c0c41c1f05805e4c8
flutter_inappwebview: bfd58618f49dc62f2676de690fc6dcda1d6c3721
fluttercontactpicker: d582836dea6b5d489f3d259f35d7817ae82ee5e6
fluttertoast: eb263d302cc92e04176c053d2385237e9f43fad0
GoogleUtilities: c2bdc4cf2ce786c4d2e6b3bcfd599a25ca78f06f
GTMSessionFetcher: c9e714f7eec91a55641e2bab9f45fd83a219b882
......
......@@ -3,6 +3,7 @@ class AppUrls {
static const String baseApiUrl = '${baseUrl}/api'; // 基础接口地址
// http://101.34.153.228:8083/api/doc.html
//'http://192.168.110.1:8083';
// static const String login = '$baseApiUrl/passport/auth/login';
// static const String register = '$baseApiUrl/passport/auth/register';
// static const String getQuickLoginUrl =
......@@ -20,6 +21,7 @@ class AppUrls {
static const String getUserIntegral = '$baseApiUrl/user/getUserIntegral';
static const String getSearchRecord =
'$baseApiUrl/searchRecord/getSearchRecord';
static const String sendSms = '$baseApiUrl/sms/sendSms';
static const String applePayCallBack = '$baseApiUrl/pay/notifyApplePay';
static const String register = '$baseApiUrl/user/register';
}
......@@ -5,25 +5,26 @@
import 'dart:convert';
class LoginEntity {
LoginEntity({
required this.token,
required this.authData,
});
LoginEntity({required this.username, required this.id, required this.token});
final String username;
final int id;
final String token;
final String authData;
factory LoginEntity.fromJson(String str) => LoginEntity.fromMap(json.decode(str));
factory LoginEntity.fromJson(String str) =>
LoginEntity.fromMap(json.decode(str));
String toJson() => json.encode(toMap());
factory LoginEntity.fromMap(Map<String, dynamic> json) => LoginEntity(
token: json["token"],
authData: json["auth_data"],
);
username: json["username"],
id: json["id"],
token: json['token'],
);
Map<String, dynamic> toMap() => {
"token": token,
"auth_token": authData,
};
"username": username,
"id": id,
"token": token,
};
}
......@@ -215,3 +215,34 @@ class ApplePayEntity {
"timestamp": timestamp
};
}
class MsmEntity {
MsmEntity(
{required this.status,
required this.message,
required this.data,
required this.timestamp});
final int status;
final String message;
final dynamic data;
final int timestamp;
factory MsmEntity.fromJson(String str) => MsmEntity.fromMap(json.decode(str));
String toJson() => json.encode(toMap());
factory MsmEntity.fromMap(Map<String, dynamic> json) => MsmEntity(
status: json["status"],
message: json["message"],
timestamp: json['timestamp'],
data: json['data'],
);
Map<String, dynamic> toMap() => {
"status": status,
"message": message,
"data": data,
"timestamp": timestamp
};
}
......@@ -33,32 +33,29 @@ class UserModel extends BaseModel {
refreshData() async {
_integralEntity = IntegralEntity(id: 1, username: '');
// _isFirstOpen = await SharedPreferencesUtil.getInstance()
// ?.getBool(AppStrings.isFirstOpen) ??
// true;
// String token = await SharedPreferencesUtil.getInstance()
// ?.getString(AppStrings.token) ??
// '';
_isFirstOpen = await SharedPreferencesUtil.getInstance()
?.getBool(AppStrings.isFirstOpen) ??
true;
String token = await SharedPreferencesUtil.getInstance()
?.getString(AppStrings.token) ??
'';
// String authData = await SharedPreferencesUtil.getInstance()
// ?.getString(AppStrings.authData) ??
// '';
// if (token != null &&
// token.isNotEmpty &&
// authData != null &&
// authData.isNotEmpty) {
// _isLogin = true;
// _token = token;
// _authData = authData;
// Map<String, dynamic> userEntityMap =
// await SharedPreferencesUtil.getInstance()
// ?.getMap(AppStrings.userInfo) ??
// <String, dynamic>{};
// _userEntity = UserEntity.fromMap(userEntityMap);
// notifyListeners();
// }
if (token != null && token.isNotEmpty) {
_isLogin = true;
_token = token;
// _authData = authData;
// Map<String, dynamic> userEntityMap =
// await SharedPreferencesUtil.getInstance()
// ?.getMap(AppStrings.userInfo) ??
// <String, dynamic>{};
// _userEntity = UserEntity.fromMap(userEntityMap);
// notifyListeners();
}
}
logout() {
......@@ -88,7 +85,7 @@ class UserModel extends BaseModel {
SharedPreferencesUtil.getInstance();
await sharedPreferencesUtil?.setString(
AppStrings.authData, loginEntity.authData);
AppStrings.authData, loginEntity.username);
}
_saveUserInfo() async {
......@@ -105,11 +102,11 @@ class UserModel extends BaseModel {
_saveIsFirstOpen();
}
setToken(LoginEntity loginEntity) {
setToken(LoginEntity loginEntity) async {
_token = loginEntity.token;
_authData = loginEntity.authData;
// _authData = loginEntity.authData;
_isLogin = true;
await setIntegralInfo();
_saveUserToken(loginEntity);
_setUserAuthData(loginEntity);
}
......
......@@ -40,6 +40,7 @@ class GoodsPageState extends State<GoodsPage> {
String _platformVersion = 'Unknown';
List<IAPItem> _items = [];
List<PurchasedItem> _purchases = [];
// var guides = [AppImages.guide1, AppImages.guide2, AppImages.guide3];
// var _showButton = false;
......@@ -130,6 +131,7 @@ class GoodsPageState extends State<GoodsPage> {
});
if (res?.status == 200) {
await FlutterInappPurchase.instance.clearTransactionIOS();
EasyLoading.showSuccess('${res?.message}');
EasyLoading.dismiss();
} else {
......@@ -163,6 +165,14 @@ class GoodsPageState extends State<GoodsPage> {
});
}
@override
dispose() {
_purchaseUpdatedSubscription.cancel();
_purchaseErrorSubscription.cancel();
_conectionSubscription.cancel();
super.dispose();
}
Future _getProduct() async {
try {
List<IAPItem> items =
......
import 'package:easy_container/easy_container.dart';
import 'package:flutter/material.dart';
import 'package:intl_phone_field/intl_phone_field.dart';
import 'package:chart/utils/helpers.dart';
import 'package:chart/pages/login/verify_phone_number_screen.dart';
class AuthenticationScreen extends StatefulWidget {
static const id = 'AuthenticationScreen';
const AuthenticationScreen({
Key? key,
}) : super(key: key);
@override
// ignore: library_private_types_in_public_api
_AuthenticationScreenState createState() => _AuthenticationScreenState();
}
class _AuthenticationScreenState extends State<AuthenticationScreen> {
String? phoneNumber;
final _formKey = GlobalKey<FormState>();
@override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
body: Padding(
padding: const EdgeInsets.all(15),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Text(
"We'll send an SMS with a verification code...",
style: TextStyle(fontSize: 22),
),
const SizedBox(height: 15),
EasyContainer(
elevation: 0,
borderRadius: 10,
color: Colors.transparent,
child: Form(
key: _formKey,
child: IntlPhoneField(
autofocus: true,
invalidNumberMessage: 'Invalid Phone Number!',
textAlignVertical: TextAlignVertical.center,
style: const TextStyle(fontSize: 25),
onChanged: (phone) => phoneNumber = phone.completeNumber,
initialCountryCode: 'IN',
flagsButtonPadding: const EdgeInsets.only(right: 10),
showDropdownIcon: false,
keyboardType: TextInputType.phone,
),
),
),
const SizedBox(height: 15),
EasyContainer(
width: double.infinity,
onTap: () async {
if (isNullOrBlank(phoneNumber) ||
!_formKey.currentState!.validate()) {
showSnackBar('Please enter a valid phone number!');
} else {
Navigator.pushNamed(
context,
VerifyPhoneNumberScreen.id,
arguments: phoneNumber,
);
}
},
child: const Text(
'Verify',
style: TextStyle(fontSize: 18),
),
),
],
),
),
),
);
}
}
import 'package:easy_container/easy_container.dart';
import 'package:firebase_phone_auth_handler/firebase_phone_auth_handler.dart';
import 'dart:async';
import 'package:chart/entity/user_entity.dart';
import 'package:chart/pages/dashboard/dashboard_page.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:url_launcher/url_launcher.dart';
import 'package:flutter/material.dart';
import 'package:chart/pages/login/authentication_screen.dart';
import 'package:chart/utils/globals.dart';
import 'package:chart/utils/helpers.dart';
import 'package:flutter/services.dart';
import 'package:url_launcher/link.dart';
import 'package:url_launcher/url_launcher.dart';
import 'package:pinput/pinput.dart';
import "package:chart/service/user_service.dart";
// import 'package:intl_phone_field/intl_phone_field.dart';
class LoginPage extends StatefulWidget {
const LoginPage({super.key});
class LoginPage extends StatelessWidget {
static const id = 'LoginPage';
// This widget is the home page of your application. It is stateful, meaning
// that it has a State object (defined below) that contains fields that affect
// how it looks.
const LoginPage({
Key? key,
}) : super(key: key);
// This class is the configuration for the state. It holds the values (in this
// case the title) provided by the parent (in this case the App widget) and
// used by the build method of the State. Fields in a Widget subclass are
// always marked "final".
@override
State<LoginPage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<LoginPage> {
TextEditingController controller = TextEditingController();
// final pinController = TextEditingController();
// final focusNode = FocusNode();
final formKey = GlobalKey<FormState>();
@override
void dispose() {
// pinController.dispose();
// focusNode.dispose();
super.dispose();
}
// bool _hasCallSupport = false;
// Future<void>? _launched;
// String _phone = '';
@override
void initState() {
super.initState();
// Check for phone call support.
// canLaunchUrl(Uri(scheme: 'tel', path: '123')).then((bool result) {
// setState(() {
// _hasCallSupport = result;
// });
// });
}
_getCode() async {
EasyLoading.show(status: "发送验证码...");
var phone = controller.text
.replaceAll("+", "")
.replaceAll(new RegExp(r"\s+\b|\b\s"), "");
try {
MsmEntity? res = await UserService().sendSms({"phone": phone});
print("$res");
if (res?.status == 200) {
EasyLoading.showSuccess('验证码发送正确');
Navigator.of(context)
.pushNamed('/ms-code', arguments: {"phone": phone});
// Navigator.of(context).pushNamed("/chat",
// arguments: {"phone": message.question})
} else {
EasyLoading.showError("${res?.message}");
}
EasyLoading.dismiss();
} catch (e) {
EasyLoading.showError("发送验证码频率过快");
EasyLoading.dismiss();
}
}
@override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
body: Padding(
padding: const EdgeInsets.all(15),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
const Padding(
padding: EdgeInsets.all(15),
// child: ,
// child: SizedBox(
// width: double.infinity,
// child: FittedBox(
// child: Text('Logged in user UID'),
// ),
// ),
// onPressed calls using this URL are not gated on a 'canLaunch' check
// because the assumption is that every device can launch a web URL.
final Uri toLaunch =
Uri(scheme: 'https', host: 'www.cylog.org', path: 'headers/');
const focusedBorderColor = Color.fromRGBO(23, 171, 144, 1);
const fillColor = Color.fromRGBO(243, 246, 249, 0);
const borderColor = Color.fromRGBO(23, 171, 144, 0.4);
final defaultPinTheme = PinTheme(
width: 56,
height: 56,
textStyle: const TextStyle(
fontSize: 22,
color: Color.fromRGBO(30, 60, 87, 1),
),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(19),
border: Border.all(color: borderColor),
),
);
return Scaffold(
appBar: AppBar(),
body: Container(
decoration: BoxDecoration(
image: DecorationImage(
image: Image.asset("assets/images/bg.png").image,
fit: BoxFit.cover),
),
// p
padding: EdgeInsets.symmetric(horizontal: 40),
// color: Colors.red,
width: double.infinity,
height: double.infinity,
child: Center(
child:
Column(mainAxisAlignment: MainAxisAlignment.center, children: [
TextField(
autofocus: true,
controller: controller,
keyboardType: TextInputType.phone,
style: const TextStyle(color: Colors.white, fontSize: 16),
decoration: InputDecoration(
labelText: '电话号码',
border: OutlineInputBorder(
borderSide: BorderSide(),
),
),
textInputAction: TextInputAction.done,
inputFormatters: <TextInputFormatter>[
LengthLimitingTextInputFormatter(13)
],
onChanged: (v) => _splitPhoneNumber(v),
),
// SizedBox(
// width: double.infinity,
// child: FittedBox(
// // child: Text(Globals.firebaseUser!.uid),
// ),
// ),
EasyContainer(
onTap: () async {
// await FirebasePhoneAuthHandler.signOut(context);
// showSnackBar('Logged out successfully!');
// ignore: use_build_context_synchronously
// Navigator.pushNamedAndRemoveUntil(
// context,
// AuthenticationScreen.id,
// (route) => false,
// );
},
child: const Text('Logout'),
SizedBox(
height: 20,
),
],
MaterialButton(
child: Text('确定'),
color: Theme.of(context).primaryColor,
textColor: Colors.white,
onPressed: _getCode),
]),
),
),
),
);
));
}
}
int inputLength = 0;
void _splitPhoneNumber(String text) {
if (text.length > inputLength) {
//输入
if (text.length == 4 || text.length == 9) {
text = text.substring(0, text.length - 1) +
" " +
text.substring(text.length - 1, text.length);
controller.text = text;
controller.selection = TextSelection.fromPosition(TextPosition(
affinity: TextAffinity.downstream, offset: text.length));
}
} else {
//删除
if (text.length == 4 || text.length == 9) {
text = text.substring(0, text.length - 1);
controller.text = text;
controller.selection = TextSelection.fromPosition(TextPosition(
affinity: TextAffinity.downstream, offset: text.length));
}
}
// Scaffold(
// appBar: AppBar(
// title: Text('Phone Field Example'),
// ),
// body: ,
// );
\ No newline at end of file
inputLength = text.length;
}
}
This diff is collapsed.
import 'package:flutter/material.dart';
// import 'package:phone_auth_handler_demo/screens/authentication_screen.dart';
import 'package:chart/pages/login/authentication_screen.dart';
// import 'package:phone_auth_handler_demo/screens/home_screen.dart';
import 'package:chart/pages/login/login_page.dart';
// import 'package:phone_auth_handler_demo/utils/globals.dart';
// import 'package:phone_auth_handler_demo/widgets/custom_loader.dart';
import 'package:chart/widgets/custom_loader.dart';
import 'package:chart/utils/globals.dart';
// import 'package:chart/utils/helpers.dart';
class SplashScreen extends StatefulWidget {
static const id = 'SplashScreen';
const SplashScreen({
Key? key,
}) : super(key: key);
@override
// ignore: library_private_types_in_public_api
_SplashScreenState createState() => _SplashScreenState();
}
class _SplashScreenState extends State<SplashScreen> {
@override
void initState() {
(() async {
await Future.delayed(Duration.zero);
final isLoggedIn = Globals.firebaseUser != null;
if (!mounted) return;
Navigator.pushReplacementNamed(
context,
isLoggedIn ? LoginPage.id : AuthenticationScreen.id,
);
})();
super.initState();
}
@override
Widget build(BuildContext context) {
return const SafeArea(
child: Scaffold(
body: CustomLoader(),
),
);
}
}
import 'package:firebase_phone_auth_handler/firebase_phone_auth_handler.dart';
import 'package:flutter/material.dart';
import 'package:chart/pages/login/login_page.dart';
// import 'package:phone_auth_handler_demo/utils/helpers.dart';
import 'package:chart/widgets/custom_loader.dart';
import 'package:chart/widgets/pin_input_field.dart';
// import 'package:chart/utils/globals.dart';
import 'package:chart/utils/helpers.dart';
// import 'package:phone_auth_handler_demo/utils/helpers.dart';
// import 'package:phone_auth_handler_demo/widgets/custom_loader.dart';
// import 'package:phone_auth_handler_demo/widgets/pin_input_field.dart';
class VerifyPhoneNumberScreen extends StatefulWidget {
static const id = 'VerifyPhoneNumberScreen';
final String phoneNumber;
const VerifyPhoneNumberScreen({
Key? key,
required this.phoneNumber,
}) : super(key: key);
@override
State<VerifyPhoneNumberScreen> createState() =>
_VerifyPhoneNumberScreenState();
}
class _VerifyPhoneNumberScreenState extends State<VerifyPhoneNumberScreen>
with WidgetsBindingObserver {
bool isKeyboardVisible = false;
late final ScrollController scrollController;
@override
void initState() {
scrollController = ScrollController();
WidgetsBinding.instance.addObserver(this);
super.initState();
}
@override
void dispose() {
WidgetsBinding.instance.removeObserver(this);
scrollController.dispose();
super.dispose();
}
@override
void didChangeMetrics() {
final bottomViewInsets = WidgetsBinding.instance.window.viewInsets.bottom;
isKeyboardVisible = bottomViewInsets > 0;
}
// scroll to bottom of screen, when pin input field is in focus.
Future<void> _scrollToBottomOnKeyboardOpen() async {
while (!isKeyboardVisible) {
await Future.delayed(const Duration(milliseconds: 50));
}
await Future.delayed(const Duration(milliseconds: 250));
await scrollController.animateTo(
scrollController.position.maxScrollExtent,
duration: const Duration(milliseconds: 250),
curve: Curves.easeIn,
);
}
@override
Widget build(BuildContext context) {
return SafeArea(
child: FirebasePhoneAuthHandler(
phoneNumber: widget.phoneNumber,
signOutOnSuccessfulVerification: false,
sendOtpOnInitialize: true,
linkWithExistingUser: false,
autoRetrievalTimeOutDuration: const Duration(seconds: 60),
otpExpirationDuration: const Duration(seconds: 60),
onCodeSent: () {
log(VerifyPhoneNumberScreen.id, msg: 'OTP sent!');
},
onLoginSuccess: (userCredential, autoVerified) async {
log(
VerifyPhoneNumberScreen.id,
msg: autoVerified
? 'OTP was fetched automatically!'
: 'OTP was verified manually!',
);
showSnackBar('Phone number verified successfully!');
log(
VerifyPhoneNumberScreen.id,
msg: 'Login Success UID: ${userCredential.user?.uid}',
);
Navigator.pushNamedAndRemoveUntil(
context,
LoginPage.id,
(route) => false,
);
},
onLoginFailed: (authException, stackTrace) {
log(
VerifyPhoneNumberScreen.id,
msg: authException.message,
error: authException,
stackTrace: stackTrace,
);
switch (authException.code) {
case 'invalid-phone-number':
// invalid phone number
return showSnackBar('Invalid phone number!');
case 'invalid-verification-code':
// invalid otp entered
return showSnackBar('The entered OTP is invalid!');
// handle other error codes
default:
showSnackBar('Something went wrong!');
// handle error further if needed
}
},
onError: (error, stackTrace) {
log(
VerifyPhoneNumberScreen.id,
error: error,
stackTrace: stackTrace,
);
showSnackBar('An error occurred!');
},
builder: (context, controller) {
return Scaffold(
appBar: AppBar(
leadingWidth: 0,
leading: const SizedBox.shrink(),
title: const Text('Verify Phone Number'),
actions: [
if (controller.codeSent)
TextButton(
onPressed: controller.isOtpExpired
? () async {
log(VerifyPhoneNumberScreen.id, msg: 'Resend OTP');
await controller.sendOTP();
}
: null,
child: Text(
controller.isOtpExpired
? 'Resend'
: '${controller.otpExpirationTimeLeft.inSeconds}s',
style: const TextStyle(color: Colors.blue, fontSize: 18),
),
),
const SizedBox(width: 5),
],
),
body: controller.isSendingCode
? Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: const [
CustomLoader(),
SizedBox(height: 50),
Center(
child: Text(
'Sending OTP',
style: TextStyle(fontSize: 25),
),
),
],
)
: ListView(
padding: const EdgeInsets.all(20),
controller: scrollController,
children: [
Text(
"We've sent an SMS with a verification code to ${widget.phoneNumber}",
style: const TextStyle(fontSize: 25),
),
const SizedBox(height: 10),
const Divider(),
if (controller.isListeningForOtpAutoRetrieve)
Column(
children: const [
CustomLoader(),
SizedBox(height: 50),
Text(
'Listening for OTP',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 25,
fontWeight: FontWeight.w600,
),
),
SizedBox(height: 15),
Divider(),
Text('OR', textAlign: TextAlign.center),
Divider(),
],
),
const SizedBox(height: 15),
const Text(
'Enter OTP',
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.w600,
),
),
const SizedBox(height: 15),
PinInputField(
length: 6,
onFocusChange: (hasFocus) async {
if (hasFocus) await _scrollToBottomOnKeyboardOpen();
},
onSubmit: (enteredOtp) async {
final verified =
await controller.verifyOtp(enteredOtp);
if (verified) {
// number verify success
// will call onLoginSuccess handler
} else {
// phone verification failed
// will call onLoginFailed or onError callbacks with the error
}
},
),
],
),
);
},
),
);
}
}
import 'package:flutter/material.dart';
import 'package:babstrap_settings_screen/babstrap_settings_screen.dart';
import 'package:provider/provider.dart';
import '../../models/user_model.dart';
class UserPage extends StatefulWidget {
@override
......@@ -20,92 +23,122 @@ class UserPageState extends State<UserPage> {
@override
Widget build(BuildContext context) {
UserModel _userModel = Provider.of<UserModel>(context);
// TODO: implement build
return Padding(
padding: const EdgeInsets.all(10),
child: ListView(
children: [
// User card
BigUserCard(
// cardColor: Colors.red,
userName: "Babacar Ndong",
userProfilePic: AssetImage("assets/images/logo.png"),
cardActionWidget: SettingsItem(
icons: Icons.edit,
iconStyle: IconStyle(
withBackground: true,
borderRadius: 50,
backgroundColor: Colors.yellow[600],
),
title: "Modify",
subtitle: "Tap to change your data",
onTap: () {
print("OK");
},
),
),
SettingsGroup(
items: [
SettingsItem(
onTap: () {},
icons: Icons.exit_to_app_rounded,
iconStyle: IconStyle(),
title: 'Appearance',
subtitle: "Make Ziar'App yours",
),
SettingsItem(
onTap: () {},
icons: Icons.dark_mode_rounded,
print("${_userModel.isLogin}");
// appBar: AppBar(
// title: Text("GPT大师傅"),
// backgroundColor: Color.fromRGBO(41, 45, 62, 1.00),
// ),
// // SailAppBar(
// // appTitle: _appTitle,
// // // rgba(41, 45, 62, 1.00)
// // backgroundColor: Color.fromRGBO(41, 45, 62, 1.00),
// // textColor: Colors.white
// // //rgba(41, 45, 62, 1.00)
// // ),
// // extendBody: true,
// // backgroundColor: Colors.amber,
// // _appModel.isOn ? AppColors.yellowColor : AppColors.grayColor,
// body: Container(
// decoration: BoxDecoration(
// image: DecorationImage(
// image: Image.asset("assets/images/bg.png").image,
// fit: BoxFit.cover),
// ),
return Container(
decoration: BoxDecoration(
image: DecorationImage(
image: Image.asset("assets/images/bg.png").image,
fit: BoxFit.cover),
),
child: Padding(
padding: const EdgeInsets.all(10),
child: ListView(
children: [
// User card
BigUserCard(
// cardColor: Colors.red,
userName: "Babacar Ndong",
userProfilePic: AssetImage("assets/images/logo.png"),
cardActionWidget: SettingsItem(
icons: Icons.edit,
iconStyle: IconStyle(
iconsColor: Colors.white,
withBackground: true,
backgroundColor: Colors.red,
),
title: 'Dark mode',
subtitle: "Automatic",
trailing: Switch.adaptive(
value: false,
onChanged: (value) {},
),
),
],
),
SettingsGroup(
items: [
SettingsItem(
onTap: () {},
icons: Icons.info_rounded,
iconStyle: IconStyle(
backgroundColor: Colors.purple,
borderRadius: 50,
backgroundColor: Colors.yellow[600],
),
title: 'About',
subtitle: "Learn more about Ziar'App",
),
],
),
// You can add a settings title
SettingsGroup(
settingsGroupTitle: "Account",
items: [
SettingsItem(
title: "Modify",
subtitle: "Tap to change your data",
onTap: () {
Navigator.of(context).pushNamed('/login');
print("OK");
},
icons: Icons.exit_to_app_rounded,
title: "Sign Out",
),
SettingsItem(
onTap: () {},
icons: Icons.exit_to_app_rounded,
title: "Delete account",
titleStyle: TextStyle(
color: Colors.red,
fontWeight: FontWeight.bold,
),
SettingsGroup(
items: [
SettingsItem(
onTap: () {},
icons: Icons.exit_to_app_rounded,
iconStyle: IconStyle(),
title: 'Appearance',
subtitle: "Make Ziar'App yours",
),
),
],
),
],
SettingsItem(
onTap: () {},
icons: Icons.dark_mode_rounded,
iconStyle: IconStyle(
iconsColor: Colors.white,
withBackground: true,
backgroundColor: Colors.red,
),
title: 'Dark mode',
subtitle: "Automatic",
trailing: Switch.adaptive(
value: false,
onChanged: (value) {},
),
),
],
),
SettingsGroup(
items: [
SettingsItem(
onTap: () {},
icons: Icons.info_rounded,
iconStyle: IconStyle(
backgroundColor: Colors.purple,
),
title: 'About',
subtitle: "Learn more about Ziar'App",
),
],
),
// You can add a settings title
SettingsGroup(
items: [
SettingsItem(
onTap: () {
Navigator.of(context).pushNamed('/ms-code');
},
icons: Icons.exit_to_app_rounded,
title: "Sign Out",
),
SettingsItem(
onTap: () {},
icons: Icons.exit_to_app_rounded,
title: "Delete account",
titleStyle: TextStyle(
color: Colors.red,
fontWeight: FontWeight.bold,
),
),
],
),
],
),
),
);
}
......
......@@ -5,6 +5,7 @@ import 'package:chart/pages/home/home_page.dart';
import 'package:chart/pages/login/login_page.dart';
import 'package:chart/pages/chat/chat_page.dart';
import 'package:chart/pages/goods/goods_page.dart';
import 'package:chart/pages/login/msm_page.dart';
// import 'package:/chart/pages/goods/goods_page.dart';
// import 'package:sail/pages/plan/plan_page.dart';
// import 'package:sail/pages/server_list.dart';
......@@ -18,6 +19,11 @@ import 'package:chart/pages/goods/goods_page.dart';
// return const MainPage();
// });
Handler msgCodeHandler = Handler(
handlerFunc: (BuildContext? context, Map<String, List<String>> parameters) {
return const MsmPage();
});
/// 登录页
Handler loginHandler = Handler(
handlerFunc: (BuildContext? context, Map<String, List<String>> parameters) {
......
......@@ -10,6 +10,7 @@ class Routers {
static String webView = "/web-view";
static String chat = "/chat";
static String goods = "/goods";
static String msgCode = "/ms-code";
static void configureRoutes(FluroRouter router) {
// router.notFoundHandler = notFindHandler;
......@@ -21,6 +22,8 @@ class Routers {
router.define(chat, handler: chatHandle);
router.define(goods, handler: goodsHandler);
router.define(msgCode, handler: msgCodeHandler);
// router.define(serverList, handler: serverListHandler);
// router.define(webView, handler: webViewHandler);
......
......@@ -54,7 +54,26 @@ class UserService {
return ApplePayEntity.fromMap(result['data']);
});
}
Future<MsmEntity>? sendSms(Map<String, dynamic> parameters) {
return HttpUtil.instance
?.get(AppUrls.sendSms, parameters: parameters)
.then((result) {
return MsmEntity.fromMap(result);
});
}
Future<LoginEntity>? register(Map<String, dynamic> parameters) {
return HttpUtil.instance
?.post(AppUrls.register, parameters: parameters)
.then((result) {
return LoginEntity.fromMap(result['data']);
});
}
}
// getGoodsList
\ No newline at end of file
// getGoodsList
......@@ -28,13 +28,15 @@ class HttpUtil {
print("url=${options.uri.toString()}");
print("headers=${options.headers}");
print("params=${options.data}");
// options.headers["appVersionName"]="V 4.0.6";
//如果token存在在请求参数加上token
await SharedPreferencesUtil.getInstance()
?.getString(AppStrings.token)
.then((token) {
if (token != null) {
options.queryParameters[AppStrings.token] = token;
options.headers['Authorization'] = token;
// ["Authorization"] = token;
print("token=$token");
}
});
......
......@@ -106,6 +106,20 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "1.2.4"
contact_picker_platform_interface:
dependency: transitive
description:
name: contact_picker_platform_interface
url: "https://pub.dartlang.org"
source: hosted
version: "4.7.0"
contact_picker_web:
dependency: transitive
description:
name: contact_picker_web
url: "https://pub.dartlang.org"
source: hosted
version: "4.7.0"
crisp:
dependency: "direct main"
description:
......@@ -183,6 +197,13 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.5"
extended_phone_number_input:
dependency: "direct main"
description:
name: extended_phone_number_input
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.2"
fake_async:
dependency: transitive
description:
......@@ -427,6 +448,13 @@ packages:
description: flutter
source: sdk
version: "0.0.0"
fluttercontactpicker:
dependency: transitive
description:
name: fluttercontactpicker
url: "https://pub.dartlang.org"
source: hosted
version: "4.7.0"
fluttertoast:
dependency: "direct main"
description:
......@@ -665,6 +693,20 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "5.1.0"
phone_number_metadata:
dependency: transitive
description:
name: phone_number_metadata
url: "https://pub.dartlang.org"
source: hosted
version: "4.0.2"
phone_numbers_parser:
dependency: transitive
description:
name: phone_numbers_parser
url: "https://pub.dartlang.org"
source: hosted
version: "4.2.1"
photo_view:
dependency: transitive
description:
......
......@@ -92,6 +92,7 @@ dependencies:
firebase_phone_auth_handler: ^1.0.8
easy_container: ^1.0.4
intl_phone_field: ^3.1.0
extended_phone_number_input: ^1.0.2
# package:bubble/bubble.dart
dev_dependencies:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment