From 9a10f448997b713a8164f35afb7a096a36126e7f Mon Sep 17 00:00:00 2001 From: Weller <1812208341@qq.com> Date: Fri, 25 Sep 2020 16:02:43 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E8=B4=A6=E5=8F=B7=E5=AE=89?= =?UTF-8?q?=E5=85=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../goods_details_page.dart | 9 +- .../models/security_style_model.dart | 2 +- .../models/security_bind_alipay_model.dart | 104 +++++++++ .../security_bind_alipay_bloc.dart | 67 ++++++ .../security_bind_alipay_page.dart | 210 +++++++++++++++++ .../security_mobile/security_mobile.dart | 215 ++++++++++++++++++ .../security_mobile_unbind.dart | 167 ++++++++++++++ lib/pages/security_page/security_page.dart | 9 +- .../security_page/security_page_bloc.dart | 64 +++--- .../security_password/security_password.dart | 181 +++++++++++++++ .../security_unbin_alipay.dart | 157 +++++++++++++ .../widgets/security_bind_input.dart | 90 ++++++++ .../widgets/security_code_button.dart | 47 ++++ .../widgets/security_confirm_button.dart | 45 ++++ lib/pages/setting_page/setting_page_bloc.dart | 35 +-- lib/register.dart | 19 +- 16 files changed, 1373 insertions(+), 48 deletions(-) create mode 100644 lib/pages/security_page/security_bind_alipay/models/security_bind_alipay_model.dart create mode 100644 lib/pages/security_page/security_bind_alipay/security_bind_alipay_bloc.dart create mode 100644 lib/pages/security_page/security_bind_alipay/security_bind_alipay_page.dart create mode 100644 lib/pages/security_page/security_mobile/security_mobile.dart create mode 100644 lib/pages/security_page/security_mobile/security_mobile_unbind.dart create mode 100644 lib/pages/security_page/security_password/security_password.dart create mode 100644 lib/pages/security_page/security_unbind_alipay/security_unbin_alipay.dart create mode 100644 lib/pages/security_page/widgets/security_bind_input.dart create mode 100644 lib/pages/security_page/widgets/security_code_button.dart create mode 100644 lib/pages/security_page/widgets/security_confirm_button.dart diff --git a/lib/pages/goods_details_page/goods_details_page.dart b/lib/pages/goods_details_page/goods_details_page.dart index 657857b..e42c3f1 100644 --- a/lib/pages/goods_details_page/goods_details_page.dart +++ b/lib/pages/goods_details_page/goods_details_page.dart @@ -132,9 +132,12 @@ class _GoodsDetailsContainerState extends State { Widget _getMainWidget(List> datas) { return Scaffold( backgroundColor: Colors.white, - body: CustomScrollView( - controller: _controller, - slivers: _createContent(context, datas ?? []), + body: Container( + color: Color(0xfff1f1f1), + child: CustomScrollView( + controller: _controller, + slivers: _createContent(context, datas ?? []), + ), ), /// appBar diff --git a/lib/pages/security_page/models/security_style_model.dart b/lib/pages/security_page/models/security_style_model.dart index a56b4dc..d0315a6 100644 --- a/lib/pages/security_page/models/security_style_model.dart +++ b/lib/pages/security_page/models/security_style_model.dart @@ -55,7 +55,6 @@ class SecurityStyleItemModel extends SkipModel { String descColor; // 绑定状态,本地标记 - bool isBind; String desc; SecurityStyleItemModel( @@ -75,6 +74,7 @@ class SecurityStyleItemModel extends SkipModel { data['name'] = this.name; data['name_color'] = this.nameColor; data['desc_color'] = this.descColor; + return data; } } diff --git a/lib/pages/security_page/security_bind_alipay/models/security_bind_alipay_model.dart b/lib/pages/security_page/security_bind_alipay/models/security_bind_alipay_model.dart new file mode 100644 index 0000000..32dde3b --- /dev/null +++ b/lib/pages/security_page/security_bind_alipay/models/security_bind_alipay_model.dart @@ -0,0 +1,104 @@ +class SecurityBindAlipayModel { + String appBarName; + String appBarName2; + String appBarNameColor; + String appBarBgColor; + String realNameText; + String alipayRealNameTextColor; + String alipayRealNameHintText; + String alipayRealNameHintTextColor; + String alipayAccountTextColor; + String alipayAccountHintText; + String alipayAccountHintTextColor; + String validCodeText; + String validCodeTextColor; + String validCodeHintText; + String validCodeHintTextColor; + String btnValidCodeText; + String btnValidCodeInactiveColor; + String btnValidCodeTextColor; + String btnValidCodeBgColor; + String btnValidCodeBorderColor; + String btnBindAckText; + String btnBindAckTextColor; + String btnBindAckActiveTextColor; + + SecurityBindAlipayModel( + {this.appBarName, + this.appBarName2, + this.appBarNameColor, + this.appBarBgColor, + this.realNameText, + this.alipayRealNameTextColor, + this.alipayRealNameHintText, + this.alipayRealNameHintTextColor, + this.alipayAccountTextColor, + this.alipayAccountHintText, + this.alipayAccountHintTextColor, + this.validCodeText, + this.validCodeTextColor, + this.validCodeHintText, + this.validCodeHintTextColor, + this.btnValidCodeText, + this.btnValidCodeInactiveColor, + this.btnValidCodeTextColor, + this.btnValidCodeBgColor, + this.btnValidCodeBorderColor, + this.btnBindAckText, + this.btnBindAckTextColor, + this.btnBindAckActiveTextColor}); + + SecurityBindAlipayModel.fromJson(Map json) { + appBarName = json['app_bar_name']; + appBarName2 = json['app_bar_name2']; + appBarNameColor = json['app_bar_name_color']; + appBarBgColor = json['app_bar_bg_color']; + realNameText = json['real_name_text']; + alipayRealNameTextColor = json['alipay_real_name_text_color']; + alipayRealNameHintText = json['alipay_real_name_hint_text']; + alipayRealNameHintTextColor = json['alipay_real_name_hint_text_color']; + alipayAccountTextColor = json['alipay_account_text_color']; + alipayAccountHintText = json['alipay_account_hint_text']; + alipayAccountHintTextColor = json['alipay_account_hint_text_color']; + validCodeText = json['valid_code_text']; + validCodeTextColor = json['valid_code_text_color']; + validCodeHintText = json['valid_code_hint_text']; + validCodeHintTextColor = json['valid_code_hint_text_color']; + btnValidCodeText = json['btn_valid_code_text']; + btnValidCodeInactiveColor = json['btn_valid_code_inactive_color']; + btnValidCodeTextColor = json['btn_valid_code_text_color']; + btnValidCodeBgColor = json['btn_valid_code_bg_color']; + btnValidCodeBorderColor = json['btn_valid_code_border_color']; + btnBindAckText = json['btn_bind_ack_text']; + btnBindAckTextColor = json['btn_bind_ack_text_color']; + btnBindAckActiveTextColor = json['btn_bind_ack_active_text_color']; + } + + Map toJson() { + final Map data = new Map(); + data['app_bar_name'] = this.appBarName; + data['app_bar_name2'] = this.appBarName2; + data['app_bar_name_color'] = this.appBarNameColor; + data['app_bar_bg_color'] = this.appBarBgColor; + data['real_name_text'] = this.realNameText; + data['alipay_real_name_text_color'] = this.alipayRealNameTextColor; + data['alipay_real_name_hint_text'] = this.alipayRealNameHintText; + data['alipay_real_name_hint_text_color'] = this.alipayRealNameHintTextColor; + data['alipay_account_text_color'] = this.alipayAccountTextColor; + data['alipay_account_hint_text'] = this.alipayAccountHintText; + data['alipay_account_hint_text_color'] = this.alipayAccountHintTextColor; + data['valid_code_text'] = this.validCodeText; + data['valid_code_text_color'] = this.validCodeTextColor; + data['valid_code_hint_text'] = this.validCodeHintText; + data['valid_code_hint_text_color'] = this.validCodeHintTextColor; + data['btn_valid_code_text'] = this.btnValidCodeText; + data['btn_valid_code_inactive_color'] = this.btnValidCodeInactiveColor; + data['btn_valid_code_text_color'] = this.btnValidCodeTextColor; + data['btn_valid_code_bg_color'] = this.btnValidCodeBgColor; + data['btn_valid_code_border_color'] = this.btnValidCodeBorderColor; + data['btn_bind_ack_text'] = this.btnBindAckText; + data['btn_bind_ack_text_color'] = this.btnBindAckTextColor; + data['btn_bind_ack_active_text_color'] = this.btnBindAckActiveTextColor; + return data; + } +} diff --git a/lib/pages/security_page/security_bind_alipay/security_bind_alipay_bloc.dart b/lib/pages/security_page/security_bind_alipay/security_bind_alipay_bloc.dart new file mode 100644 index 0000000..a0cf6a5 --- /dev/null +++ b/lib/pages/security_page/security_bind_alipay/security_bind_alipay_bloc.dart @@ -0,0 +1,67 @@ +import 'dart:async'; +import 'dart:convert' as convert; + +import 'package:fluttertoast/fluttertoast.dart'; +import 'package:zhiying_base_widget/pages/security_page/security_bind_alipay/models/security_bind_alipay_model.dart'; +import 'package:zhiying_comm/util/base_bloc.dart'; +import 'package:zhiying_comm/zhiying_comm.dart'; + +class SecurityBindAlipayBloc extends BlocBase { + SecurityBindAlipayModel _model; + + StreamController _dataController = + StreamController(); + + Stream get outData => _dataController.stream; + + @override + void dispose() { + _dataController.close(); + _dataController = null; + } + + void loadData(String skipIdentifier) async { + NetUtil.request('/api/v1/mod/${skipIdentifier.toString()}', + method: NetMethod.GET, onCache: (data) { + _loadData(data); + }, onSuccess: (data) { + _loadData(data); + }); + } + + void _loadData(dynamic data) { + try { + Map json = Map.from(data); + if (json == null || json.length == 0) { + return; + } + List mods = json['mod_list']; + if (mods.first != null) { + json = Map.from(mods.first); + String d = json['data']; + Map da = + Map.from(convert.jsonDecode(d)); + _model = SecurityBindAlipayModel.fromJson(da); + _dataController.add(_model); + } + } catch (err) { + Logger.error(err); + } + } + + Future bindAlipay(String name, String account, String code) { + return NetUtil.post('/api/v1/settings/account/security/alipay', + method: NetMethod.POST, + params: Map.from({ + 'alipay_real_name': name, + 'alipay_account': account, + 'valid_code': code, + })).then((result) { + if (result['code'] == 1) return true; + return false; + }).catchError((error) { + Fluttertoast.showToast(msg: error); + return false; + }); + } +} diff --git a/lib/pages/security_page/security_bind_alipay/security_bind_alipay_page.dart b/lib/pages/security_page/security_bind_alipay/security_bind_alipay_page.dart new file mode 100644 index 0000000..763bdeb --- /dev/null +++ b/lib/pages/security_page/security_bind_alipay/security_bind_alipay_page.dart @@ -0,0 +1,210 @@ +import 'dart:async'; + +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:fluttertoast/fluttertoast.dart'; +import 'package:zhiying_base_widget/pages/security_page/security_bind_alipay/models/security_bind_alipay_model.dart'; +import 'package:zhiying_base_widget/pages/security_page/security_bind_alipay/security_bind_alipay_bloc.dart'; +import 'package:zhiying_base_widget/pages/security_page/security_unbind_alipay/security_unbin_alipay.dart'; +import 'package:zhiying_base_widget/pages/security_page/widgets/security_bind_input.dart'; +import 'package:zhiying_base_widget/pages/security_page/widgets/security_code_button.dart'; +import 'package:zhiying_base_widget/pages/security_page/widgets/security_confirm_button.dart'; +import 'package:zhiying_comm/util/base_bloc.dart'; +import 'package:zhiying_comm/zhiying_comm.dart'; + +// 绑定支付宝 +class SecurityBindAlipayPage extends StatefulWidget { + final Map model; + + const SecurityBindAlipayPage(this.model, {Key key}) : super(key: key); + + @override + _SecurityBindAlipayPageState createState() => _SecurityBindAlipayPageState(); +} + +class _SecurityBindAlipayPageState extends State { + @override + Widget build(BuildContext context) { + Logger.debug(widget.model.toString()); + Map status = widget.model['status']; + Map datas = widget.model['data']; + if (status['alipay_setting'] == '1') { + return SecurityUnbinAlipay(widget.model); + } else { + return BlocProvider( + bloc: SecurityBindAlipayBloc(), + child: _SecurityBindAlipayContainer(datas), + ); + } + } +} + +class _SecurityBindAlipayContainer extends StatefulWidget { + final Map model; + + const _SecurityBindAlipayContainer(this.model, {Key key}) : super(key: key); + + @override + _SecurityBindAlipayContainerState createState() => + _SecurityBindAlipayContainerState(); +} + +class _SecurityBindAlipayContainerState + extends State<_SecurityBindAlipayContainer> { + SecurityBindAlipayBloc _bloc; + SecurityBindAlipayModel _model; + + TextEditingController _nameController = TextEditingController(); + TextEditingController _accountController = TextEditingController(); + TextEditingController _codeController = TextEditingController(); + int _second = 0; + bool _canConfirm = false; + + @override + void initState() { + _bloc = BlocProvider.of(context); + _bloc.loadData(widget.model['skip_identifier'].toString()); + + _nameController.addListener(_verifiy); + _accountController.addListener(_verifiy); + _codeController.addListener(_verifiy); + + super.initState(); + } + + void _verifiy() { + bool canConfirm = _nameController.text.length > 0 && + _accountController.text.length > 0 && + _codeController.text.length == 6; + if (canConfirm != _canConfirm) { + setState(() { + _canConfirm = canConfirm; + }); + } + } + + @override + Widget build(BuildContext context) { + return StreamBuilder( + stream: _bloc.outData, + builder: (BuildContext context, AsyncSnapshot snapshot) { + _model = snapshot.data; + return GestureDetector( + onTap: () { + FocusScope.of(context).requestFocus(FocusNode()); + }, + child: Scaffold( + appBar: _createNav(), + body: Padding( + padding: const EdgeInsets.only(top: 5), + child: _model == null + ? Container() + : Column( + children: [ + SecurityBindInput( + '真实姓名', + '请输入支付宝认证的真实姓名', + controller: _nameController, + ), + SecurityBindInput( + '支付宝号', + '请输入要绑定的支付宝账号', + controller: _accountController, + ), + SecurityBindInput( + '验证码', + '请输入验证码', + controller: _codeController, + rightWidget: SecurityCodeButton( + _second <= 0 ? '获取验证码' : '${_second.toString()}s', + enabled: _second <= 0, + onSend: () { + _sendCode(); + Logger.debug('发送验证码'); + }, + ), + keyboardType: TextInputType.number, + inputFormatters: [ + LengthLimitingTextInputFormatter(6) + ], + ), + Padding( + padding: const EdgeInsets.only(top: 8), + child: SecurityConfirmButton( + text: '确定', + enabled: _canConfirm, + onClick: () async { + Logger.debug('确定'); + FocusScope.of(context).requestFocus(FocusNode()); + if (await _bloc.bindAlipay( + _nameController.text, + _accountController.text, + _codeController.text)) { + Fluttertoast.showToast(msg: '绑定成功'); + Navigator.of(context).pop(true); + } + }, + ), + ), + ], + ), + ), + ), + ); + }, + ); + } + + // 导航栏 + Widget _createNav() { + return CupertinoNavigationBar( + border: Border( + bottom: BorderSide( + width: 0.0, // One physical pixel. + style: BorderStyle.none, + ), + ), + backgroundColor: HexColor.fromHex('#ffffff'), + leading: Navigator.canPop(context) + ? GestureDetector( + child: Container( + padding: EdgeInsets.zero, + child: Icon( + Icons.arrow_back_ios, + size: 20, + ), + ), + onTap: () { + if (Navigator.canPop(context)) { + Navigator.pop(context); + } + }, + ) + : Container(), + middle: Text( + '绑定支付宝', + style: TextStyle( + fontSize: 15, + color: HexColor.fromHex('#333333'), + ), + ), + ); + } + + void _sendCode() async { + NetUtil.request('/api/v1/settings/account/security/alipay/sms', + onSuccess: (result) { + Logger.debug(result); + Fluttertoast.showToast(msg: '发送成功'); + _second = 60; + Timer.periodic(Duration(seconds: 1), (timer) { + _second--; + if (_second <= 0) { + timer.cancel(); + } + setState(() {}); + }); + }); + } +} diff --git a/lib/pages/security_page/security_mobile/security_mobile.dart b/lib/pages/security_page/security_mobile/security_mobile.dart new file mode 100644 index 0000000..15d6eef --- /dev/null +++ b/lib/pages/security_page/security_mobile/security_mobile.dart @@ -0,0 +1,215 @@ +import 'dart:async'; + +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:fluttertoast/fluttertoast.dart'; +import 'package:zhiying_base_widget/pages/security_page/security_mobile/security_mobile_unbind.dart'; +import 'package:zhiying_base_widget/pages/security_page/widgets/security_bind_input.dart'; +import 'package:zhiying_base_widget/pages/security_page/widgets/security_code_button.dart'; +import 'package:zhiying_base_widget/pages/security_page/widgets/security_confirm_button.dart'; +import 'package:zhiying_comm/zhiying_comm.dart'; + +class SecurityMobile extends StatefulWidget { + final Map model; + + const SecurityMobile(this.model, {Key key}) : super(key: key); + + @override + _SecurityMobileState createState() => _SecurityMobileState(); +} + +class _SecurityMobileState extends State { + @override + Widget build(BuildContext context) { + Map status = widget.model['status']; + if (status['mobile_setting'] == '1') { + return SecurityMobileUnbind(widget.model); + } else { + return _SecurityMobileContainer(widget.model); + } + } +} + +class _SecurityMobileContainer extends StatefulWidget { + final Map model; + + const _SecurityMobileContainer(this.model, {Key key}) : super(key: key); + + @override + _SecurityMobileContainerState createState() => + _SecurityMobileContainerState(); +} + +class _SecurityMobileContainerState extends State<_SecurityMobileContainer> { + TextEditingController _phoneController = TextEditingController(); + TextEditingController _codeController = TextEditingController(); + int _second = 0; + bool _canConfirm = false; + String _phone; + String _unbindCode = ''; + + @override + void initState() { + Logger.debug(widget.model.toString()); + Map status = widget.model['status']; + _phone = status['mobile_setting_text']; + _unbindCode = status['code']; + + _phoneController.addListener(_verifiy); + _codeController.addListener(_verifiy); + + super.initState(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: _createNav(), + body: Padding( + padding: const EdgeInsets.only(top: 8.0), + child: Column( + children: [ + _unbindCode == null || _unbindCode == '' + ? Container() + : Container( + width: double.infinity, + padding: EdgeInsets.only( + left: 12.5, right: 12.5, top: 10, bottom: 10), + child: Text( + '请绑定新的手机号码,如未完成绑定将继续使用原手机号码', + style: TextStyle(fontSize: 12, color: Color(0xff999999)), + ), + ), + SecurityBindInput( + '手机号', + '请输入要绑定的手机号', + keyboardType: TextInputType.number, + controller: _phoneController, + ), + SecurityBindInput( + '验证码', + '请输入验证码', + controller: _codeController, + rightWidget: SecurityCodeButton( + _second <= 0 ? '获取验证码' : '${_second.toString()}s', + enabled: _second <= 0, + onSend: () { + _sendCode(); + Logger.debug('发送验证码'); + }, + ), + keyboardType: TextInputType.number, + inputFormatters: [LengthLimitingTextInputFormatter(6)], + ), + Padding( + padding: const EdgeInsets.only(top: 8), + child: SecurityConfirmButton( + text: '确定', + enabled: _canConfirm, + onClick: () async { + Logger.debug('确定'); + FocusScope.of(context).requestFocus(FocusNode()); + _updatePhone(); + }, + ), + ), + ], + ), + ), + ); + } + + // 导航栏 + Widget _createNav() { + return CupertinoNavigationBar( + border: Border( + bottom: BorderSide( + width: 0.0, // One physical pixel. + style: BorderStyle.none, + ), + ), + backgroundColor: HexColor.fromHex('#ffffff'), + leading: Navigator.canPop(context) + ? GestureDetector( + child: Container( + padding: EdgeInsets.zero, + child: Icon( + Icons.arrow_back_ios, + size: 20, + ), + ), + onTap: () { + if (Navigator.canPop(context)) { + Navigator.pop(context); + } + }, + ) + : Container(), + middle: Text( + '设置手机号', + style: TextStyle( + fontSize: 15, + color: HexColor.fromHex('#333333'), + ), + ), + ); + } + + void _verifiy() { + bool canConfirm = + _phoneController.text.length > 0 && _codeController.text.length == 6; + if (canConfirm != _canConfirm) { + setState(() { + _canConfirm = canConfirm; + }); + } + } + + void _sendCode() async { + NetUtil.request('/api/v1/settings/account/security/mobile/sms', + params: Map.from({ + 'mobile': _phoneController.text, + }), + method: NetMethod.POST, onSuccess: (result) { + Logger.debug(result); + Fluttertoast.showToast(msg: '发送成功'); + _second = 60; + Timer.periodic(Duration(seconds: 1), (timer) { + _second--; + if (_second <= 0) { + timer.cancel(); + } + setState(() {}); + }); + }); + } + + // 设置手机号,没有手机号的调这个😵 + void _setPhone() async { + NetUtil.request('/api/v1/settings/account/security/mobile', + params: Map.from({ + 'mobile': _phoneController.text, + 'valid_code': _codeController.text, + }), + method: NetMethod.POST, onSuccess: (result) { + Logger.debug(result); + Fluttertoast.showToast(msg: '设置成功'); + Navigator.of(context).pop(); + }); + } + + // 更新手机号,有手机号的调这个 + void _updatePhone() async { + NetUtil.request('/api/v1/settings/account/security/mobile/unbind/update', + params: Map.from({ + 'mobile': _phoneController.text, + 'valid_code': _codeController.text, + }), + method: NetMethod.POST, onSuccess: (result) { + Logger.debug(result); + Fluttertoast.showToast(msg: '设置成功'); + Navigator.of(context).pop(); + }); + } +} diff --git a/lib/pages/security_page/security_mobile/security_mobile_unbind.dart b/lib/pages/security_page/security_mobile/security_mobile_unbind.dart new file mode 100644 index 0000000..bc7c244 --- /dev/null +++ b/lib/pages/security_page/security_mobile/security_mobile_unbind.dart @@ -0,0 +1,167 @@ +import 'dart:async'; + +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:fluttertoast/fluttertoast.dart'; +import 'package:zhiying_base_widget/pages/security_page/security_mobile/security_mobile.dart'; +import 'package:zhiying_base_widget/pages/security_page/widgets/security_bind_input.dart'; +import 'package:zhiying_base_widget/pages/security_page/widgets/security_code_button.dart'; +import 'package:zhiying_base_widget/pages/security_page/widgets/security_confirm_button.dart'; +import 'package:zhiying_comm/zhiying_comm.dart'; + +class SecurityMobileUnbind extends StatefulWidget { + final Map model; + + const SecurityMobileUnbind(this.model, {Key key}) : super(key: key); + + @override + _SecurityMobileUnbindState createState() => _SecurityMobileUnbindState(); +} + +class _SecurityMobileUnbindState extends State { + TextEditingController _codeController = TextEditingController(); + int _second = 0; + bool _canConfirm = false; + String _phone; + Map _status; + + @override + void initState() { + Logger.debug(widget.model.toString()); + Map status = widget.model['status']; + _phone = status['mobile_setting_text']; + _status = widget.model['status']; + _codeController.addListener(_verifiy); + + super.initState(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: _createNav(), + body: Column( + children: [ + Container( + width: double.infinity, + padding: + EdgeInsets.only(left: 12.5, right: 12.5, top: 10, bottom: 10), + child: Text( + '为了您的账户安全,将对原有手机号进行验证', + style: TextStyle(fontSize: 12, color: Color(0xff999999)), + ), + ), + SecurityBindInput( + '验证原手机号', + _phone ?? '******', + keyboardType: TextInputType.number, + enabled: false, + ), + SecurityBindInput( + '验证码', + '请输入验证码', + controller: _codeController, + rightWidget: SecurityCodeButton( + _second <= 0 ? '获取验证码' : '${_second.toString()}s', + enabled: _second <= 0, + onSend: () { + _sendCode(); + Logger.debug('发送验证码'); + }, + ), + keyboardType: TextInputType.number, + inputFormatters: [LengthLimitingTextInputFormatter(6)], + ), + Padding( + padding: const EdgeInsets.only(top: 8), + child: SecurityConfirmButton( + text: '确定', + enabled: _canConfirm, + onClick: () async { + Logger.debug('确定'); + FocusScope.of(context).requestFocus(FocusNode()); + _unbind(); + }, + ), + ), + ], + ), + ); + } + + // 导航栏 + Widget _createNav() { + return CupertinoNavigationBar( + border: Border( + bottom: BorderSide( + width: 0.0, // One physical pixel. + style: BorderStyle.none, + ), + ), + backgroundColor: HexColor.fromHex('#ffffff'), + leading: Navigator.canPop(context) + ? GestureDetector( + child: Container( + padding: EdgeInsets.zero, + child: Icon( + Icons.arrow_back_ios, + size: 20, + ), + ), + onTap: () { + if (Navigator.canPop(context)) { + Navigator.pop(context); + } + }, + ) + : Container(), + middle: Text( + '解绑手机号', + style: TextStyle( + fontSize: 15, + color: HexColor.fromHex('#333333'), + ), + ), + ); + } + + void _verifiy() { + bool canConfirm = _codeController.text.length == 6; + if (canConfirm != _canConfirm) { + setState(() { + _canConfirm = canConfirm; + }); + } + } + + void _sendCode() async { + NetUtil.request('/api/v1/settings/account/security/mobile/sms', + method: NetMethod.GET, onSuccess: (result) { + Logger.debug(result); + Fluttertoast.showToast(msg: '发送成功'); + _second = 60; + Timer.periodic(Duration(seconds: 1), (timer) { + _second--; + if (_second <= 0) { + timer.cancel(); + } + setState(() {}); + }); + }); + } + + // 解绑手机号 + void _unbind() async { + NetUtil.request('/api/v1/settings/account/security/mobile/unbind', + params: Map.from({ + 'valid_code': _codeController.text, + }), + method: NetMethod.POST, onSuccess: (result) { + _status['mobile_setting'] = '0'; + _status['code'] = _codeController.text; + Navigator.of(context).pushReplacement(MaterialPageRoute( + builder: (context) => SecurityMobile(widget.model))); + }); + } +} diff --git a/lib/pages/security_page/security_page.dart b/lib/pages/security_page/security_page.dart index d920354..8b922fc 100644 --- a/lib/pages/security_page/security_page.dart +++ b/lib/pages/security_page/security_page.dart @@ -145,8 +145,13 @@ class _SecurityContainerState extends State<_SecurityContainer> { ], ), ), - onTap: () { - RouterUtil.route(item, item.toJson(), context); + onTap: () async { + await RouterUtil.route( + item, + Map.from( + {'status': _bloc.securityStatus, 'data': item.toJson()}), + context); + _bloc.loadData(widget.data['skip_identifier']); }, ); } diff --git a/lib/pages/security_page/security_page_bloc.dart b/lib/pages/security_page/security_page_bloc.dart index 6eb4647..be295ba 100644 --- a/lib/pages/security_page/security_page_bloc.dart +++ b/lib/pages/security_page/security_page_bloc.dart @@ -7,7 +7,7 @@ import 'package:zhiying_comm/zhiying_comm.dart'; class SecurityPageBloc extends BlocBase { SecurityStyleModel _style; - Map _securityStatus; + Map securityStatus; StreamController _styleController = StreamController(); @@ -21,43 +21,51 @@ class SecurityPageBloc extends BlocBase { } void loadData(String skipIdentifier) async { - Api api = Api( - '/api/v1/mod/${skipIdentifier.toString()}', - method: NetMethod.GET, - ); - _loadData(await api.onCache()); - - _securityStatus = Map.from(await _getStatus()); - _loadData(await api.onRequest()); + NetUtil.request('/api/v1/mod/${skipIdentifier.toString()}', + method: NetMethod.GET, onCache: (data) { + _loadData(data); + }, onSuccess: (data) async { + securityStatus = Map.from(await _getStatus()); + _loadData(data); + }); } // 获取授权状态等信息 - Future _getStatus() { - Api api = Api( + Future _getStatus() async { + var result = await NetUtil.post( '/api/v1/settings/account/security', method: NetMethod.GET, ); - return api.onRequest(); + return result['data']; } void _loadData(dynamic data) { - Map json = Map.from(data); - if (json == null || json.length == 0) { - return; - } - String d = json['data']; - Map da = Map.from(convert.jsonDecode(d)); - _style = SecurityStyleModel.fromJson(da); - - if (_securityStatus != null) { - _style.settings.forEach((item) { - List keys = item.dataKeys; - if (keys.length > 0) { - item.desc = _securityStatus[keys.first] ?? ''; + try { + Map json = Map.from(data); + if (json == null || json.length == 0) { + return; + } + List mods = json['mod_list']; + if (mods.first != null) { + json = Map.from(mods.first); + String d = json['data']; + Map da = + Map.from(convert.jsonDecode(d)); + _style = SecurityStyleModel.fromJson(da); + + if (securityStatus != null) { + _style.settings.forEach((item) { + List keys = item.dataKeys; + if (keys.length > 0) { + item.desc = securityStatus[keys.first] ?? ''; + } + }); } - }); - } - _styleController.add(_style); + _styleController.add(_style); + } + } catch (err) { + Logger.error(err); + } } } diff --git a/lib/pages/security_page/security_password/security_password.dart b/lib/pages/security_page/security_password/security_password.dart new file mode 100644 index 0000000..cbe4608 --- /dev/null +++ b/lib/pages/security_page/security_password/security_password.dart @@ -0,0 +1,181 @@ +import 'dart:async'; + +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:fluttertoast/fluttertoast.dart'; +import 'package:zhiying_base_widget/pages/security_page/widgets/security_bind_input.dart'; +import 'package:zhiying_base_widget/pages/security_page/widgets/security_code_button.dart'; +import 'package:zhiying_base_widget/pages/security_page/widgets/security_confirm_button.dart'; +import 'package:zhiying_comm/zhiying_comm.dart'; + +class SecurityPassword extends StatefulWidget { + final Map model; + + const SecurityPassword(this.model, {Key key}) : super(key: key); + + @override + _SecurityPasswordState createState() => _SecurityPasswordState(); +} + +class _SecurityPasswordState extends State { + TextEditingController _passwordController = TextEditingController(); + TextEditingController _confirmController = TextEditingController(); + TextEditingController _codeController = TextEditingController(); + int _second = 0; + bool _canConfirm = false; + String _phone; + + @override + void initState() { + Logger.debug(widget.model.toString()); + Map status = widget.model['status']; + _phone = status['mobile_setting_text']; + + _passwordController.addListener(_verifiy); + _confirmController.addListener(_verifiy); + _codeController.addListener(_verifiy); + + super.initState(); + } + + @override + Widget build(BuildContext context) { + return GestureDetector( + onTap: () { + FocusScope.of(context).requestFocus(FocusNode()); + }, + child: Scaffold( + appBar: _createNav(), + body: Container( + padding: EdgeInsets.only(top: 8), + child: Column( + children: [ + SecurityBindInput( + '新密码', + '请输入需更改的密码', + controller: _passwordController, + obscureText: true, + ), + SecurityBindInput( + '确认密码', + '请确认新输入的密码', + controller: _confirmController, + obscureText: true, + ), + SecurityBindInput( + '密保手机', + _phone ?? '******', + enabled: false, + ), + SecurityBindInput( + '验证码', + '请输入验证码', + controller: _codeController, + rightWidget: SecurityCodeButton( + _second <= 0 ? '获取验证码' : '${_second.toString()}s', + enabled: _second <= 0, + onSend: () { + _sendCode(); + Logger.debug('发送验证码'); + }, + ), + keyboardType: TextInputType.number, + inputFormatters: [LengthLimitingTextInputFormatter(6)], + ), + Padding( + padding: const EdgeInsets.only(top: 8), + child: SecurityConfirmButton( + text: '确认修改', + enabled: _canConfirm, + onClick: () async { + Logger.debug('确定'); + FocusScope.of(context).requestFocus(FocusNode()); + _confirm(); + }, + ), + ), + ], + ), + ), + ), + ); + } + + // 导航栏 + Widget _createNav() { + return CupertinoNavigationBar( + border: Border( + bottom: BorderSide( + width: 0.0, // One physical pixel. + style: BorderStyle.none, + ), + ), + backgroundColor: HexColor.fromHex('#ffffff'), + leading: Navigator.canPop(context) + ? GestureDetector( + child: Container( + padding: EdgeInsets.zero, + child: Icon( + Icons.arrow_back_ios, + size: 20, + ), + ), + onTap: () { + if (Navigator.canPop(context)) { + Navigator.pop(context); + } + }, + ) + : Container(), + middle: Text( + '修改密码', + style: TextStyle( + fontSize: 15, + color: HexColor.fromHex('#333333'), + ), + ), + ); + } + + void _verifiy() { + bool canConfirm = _passwordController.text.length >= 6 && + _confirmController.text.length >= 6 && + _codeController.text.length == 6; + if (canConfirm != _canConfirm) { + setState(() { + _canConfirm = canConfirm; + }); + } + } + + void _sendCode() async { + NetUtil.request('/api/v1/settings/account/security/password/sms', + method: NetMethod.POST, onSuccess: (result) { + Logger.debug(result); + Fluttertoast.showToast(msg: '发送成功'); + _second = 60; + Timer.periodic(Duration(seconds: 1), (timer) { + _second--; + if (_second <= 0) { + timer.cancel(); + } + setState(() {}); + }); + }); + } + + void _confirm() async { + NetUtil.request('/api/v1/settings/account/security/password', + params: Map.from({ + 'new_password': _passwordController.text, + 'new_password_ack': _confirmController.text, + 'valid_code': _codeController.text, + }), + method: NetMethod.POST, onSuccess: (result) { + Logger.debug(result); + Fluttertoast.showToast(msg: '设置成功'); + Navigator.of(context).pop(); + }); + } +} diff --git a/lib/pages/security_page/security_unbind_alipay/security_unbin_alipay.dart b/lib/pages/security_page/security_unbind_alipay/security_unbin_alipay.dart new file mode 100644 index 0000000..def44e9 --- /dev/null +++ b/lib/pages/security_page/security_unbind_alipay/security_unbin_alipay.dart @@ -0,0 +1,157 @@ +import 'dart:async'; + +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:fluttertoast/fluttertoast.dart'; +import 'package:zhiying_base_widget/pages/security_page/security_bind_alipay/security_bind_alipay_page.dart'; +import 'package:zhiying_base_widget/pages/security_page/widgets/security_bind_input.dart'; +import 'package:zhiying_base_widget/pages/security_page/widgets/security_code_button.dart'; +import 'package:zhiying_base_widget/pages/security_page/widgets/security_confirm_button.dart'; +import 'package:zhiying_comm/zhiying_comm.dart'; + +class SecurityUnbinAlipay extends StatefulWidget { + final Map model; + + const SecurityUnbinAlipay(this.model, {Key key}) : super(key: key); + + @override + _SecurityUnbinAlipayState createState() => _SecurityUnbinAlipayState(); +} + +class _SecurityUnbinAlipayState extends State { + TextEditingController _codeController = TextEditingController(); + Map _status; + int _second = 0; + bool _canConfirm = false; + + @override + void initState() { + Logger.debug(widget.model.toString()); + + _status = widget.model['status']; + _codeController.addListener(_verifiy); + super.initState(); + } + + void _verifiy() { + bool canConfirm = _codeController.text.length == 6; + if (canConfirm != _canConfirm) { + setState(() { + _canConfirm = canConfirm; + }); + } + } + + @override + Widget build(BuildContext context) { + return GestureDetector( + child: Scaffold( + appBar: _createNav(), + body: Column( + children: [ + SecurityBindInput( + '验证手机号', + _status['mobile_setting_text'] ?? '', + enabled: false, + ), + SecurityBindInput( + '验证码', + '请输入验证码', + controller: _codeController, + rightWidget: SecurityCodeButton( + _second <= 0 ? '获取验证码' : '${_second.toString()}s', + enabled: _second <= 0, + onSend: () { + _sendCode(); + Logger.debug('发送验证码'); + }, + ), + keyboardType: TextInputType.number, + inputFormatters: [LengthLimitingTextInputFormatter(6)], + ), + Padding( + padding: const EdgeInsets.only(top: 8), + child: SecurityConfirmButton( + text: '确定', + enabled: _canConfirm, + onClick: () async { + Logger.debug('确定'); + FocusScope.of(context).requestFocus(FocusNode()); + _unbind(); + }, + ), + ), + ], + ), + ), + onTap: () { + FocusScope.of(context).requestFocus(FocusNode()); + }, + ); + } + + // 导航栏 + Widget _createNav() { + return CupertinoNavigationBar( + border: Border( + bottom: BorderSide( + width: 0.0, // One physical pixel. + style: BorderStyle.none, + ), + ), + backgroundColor: HexColor.fromHex('#ffffff'), + leading: Navigator.canPop(context) + ? GestureDetector( + child: Container( + padding: EdgeInsets.zero, + child: Icon( + Icons.arrow_back_ios, + size: 20, + ), + ), + onTap: () { + if (Navigator.canPop(context)) { + Navigator.pop(context); + } + }, + ) + : Container(), + middle: Text( + '解绑支付宝', + style: TextStyle( + fontSize: 15, + color: HexColor.fromHex('#333333'), + ), + ), + ); + } + + void _sendCode() async { + NetUtil.request('/api/v1/settings/account/security/alipay/sms', + method: NetMethod.GET, onSuccess: (result) { + Logger.debug(result); + Fluttertoast.showToast(msg: '发送成功'); + _second = 60; + Timer.periodic(Duration(seconds: 1), (timer) { + _second--; + if (_second <= 0) { + timer.cancel(); + } + setState(() {}); + }); + }); + } + + void _unbind() async { + NetUtil.request('/api/v1/settings/account/security/alipay/unbind', + params: Map.from({'valid_code': _codeController.text}), + method: NetMethod.POST, onSuccess: (result) { + Logger.debug(result); + Fluttertoast.showToast(msg: '解绑成功'); + _status['alipay_setting'] = '0'; + Navigator.of(context).pushReplacement(MaterialPageRoute( + builder: (context) => SecurityBindAlipayPage(widget.model))); + }); + } +} diff --git a/lib/pages/security_page/widgets/security_bind_input.dart b/lib/pages/security_page/widgets/security_bind_input.dart new file mode 100644 index 0000000..b36a8ae --- /dev/null +++ b/lib/pages/security_page/widgets/security_bind_input.dart @@ -0,0 +1,90 @@ +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; + +class SecurityBindInput extends StatefulWidget { + final String title; + final Color titleColor; + final String placeholder; + final Color placeholderColor; + final Widget rightWidget; + final TextInputType keyboardType; + final List inputFormatters; + final TextEditingController controller; + final bool enabled; + final bool obscureText; // 是否密码 + + const SecurityBindInput( + this.title, + this.placeholder, { + Key key, + this.rightWidget, + this.titleColor, + this.placeholderColor, + this.keyboardType, + this.inputFormatters, + this.controller, + this.enabled = true, + this.obscureText = false, + }) : super(key: key); + + @override + _SecurityBindInputState createState() => _SecurityBindInputState(); +} + +class _SecurityBindInputState extends State { + @override + Widget build(BuildContext context) { + return Container( + color: Colors.white, + width: double.infinity, + padding: EdgeInsets.only(left: 12.5, right: 12.5), + height: 50, + child: Row( + children: [ + _createTitle(), + _createTextField(), + widget.rightWidget ?? Container(), + ], + ), + ); + } + + Widget _createTitle() { + return Container( + width: 80, + child: Text( + widget.title ?? '', + style: TextStyle( + fontSize: 13, + fontWeight: FontWeight.bold, + ), + ), + ); + } + + Widget _createTextField() { + return Expanded( + child: CupertinoTextField( + placeholder: widget.placeholder, + placeholderStyle: TextStyle( + fontSize: 13, + fontWeight: FontWeight.bold, + color: widget.placeholderColor ?? Color(0xff999999)), + decoration: BoxDecoration(color: Colors.transparent), + style: TextStyle( + color: widget.titleColor ?? Color(0xff333333), + fontSize: 13, + ), + keyboardType: widget.keyboardType, + inputFormatters: widget.inputFormatters, + controller: widget.controller, + onSubmitted: (_) { + FocusScope.of(context).requestFocus(FocusNode()); + }, + enabled: widget.enabled, + obscureText: widget.obscureText, + ), + ); + } +} diff --git a/lib/pages/security_page/widgets/security_code_button.dart b/lib/pages/security_page/widgets/security_code_button.dart new file mode 100644 index 0000000..bf870d4 --- /dev/null +++ b/lib/pages/security_page/widgets/security_code_button.dart @@ -0,0 +1,47 @@ +import 'package:flutter/material.dart'; + +class SecurityCodeButton extends StatelessWidget { + final String title; + final VoidCallback onSend; + final Color color; + final bool enabled; + + const SecurityCodeButton( + this.title, { + Key key, + this.onSend, + this.enabled = true, + this.color = const Color(0xffff4242), + }) : super(key: key); + + @override + Widget build(BuildContext context) { + return GestureDetector( + child: Container( + width: 72, + height: 26, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(13), + border: Border.all( + width: 0.5, + color: enabled ? color : Color(0xff999999), + ), + ), + child: Center( + child: Text( + title ?? '获取验证码', + style: TextStyle( + fontSize: 10, + color: enabled ? color : Color(0xff999999), + ), + ), + ), + ), + onTap: () { + if (enabled && onSend != null) { + onSend(); + } + }, + ); + } +} diff --git a/lib/pages/security_page/widgets/security_confirm_button.dart b/lib/pages/security_page/widgets/security_confirm_button.dart new file mode 100644 index 0000000..4a72623 --- /dev/null +++ b/lib/pages/security_page/widgets/security_confirm_button.dart @@ -0,0 +1,45 @@ +import 'package:flutter/material.dart'; + +class SecurityConfirmButton extends StatelessWidget { + final String text; + final String disableText; + final bool enabled; + final VoidCallback onClick; + + const SecurityConfirmButton({ + Key key, + this.text, + this.disableText, + this.enabled = true, + this.onClick, + }) : super(key: key); + + @override + Widget build(BuildContext context) { + return GestureDetector( + child: Container( + width: double.infinity, + height: 48, + margin: EdgeInsets.only(left: 12.5, right: 12.5, top: 4, bottom: 4), + decoration: BoxDecoration( + color: enabled ? Color(0xffff4242) : Color(0xffd8d8d8), + borderRadius: BorderRadius.circular(24), + ), + child: Center( + child: Text( + (enabled ? text : (disableText ?? text)) ?? '', + style: TextStyle( + fontSize: 13, + color: Colors.white, + ), + ), + ), + ), + onTap: () { + if (enabled && onClick != null) { + onClick(); + } + }, + ); + } +} diff --git a/lib/pages/setting_page/setting_page_bloc.dart b/lib/pages/setting_page/setting_page_bloc.dart index 6e63ad1..08db6c6 100644 --- a/lib/pages/setting_page/setting_page_bloc.dart +++ b/lib/pages/setting_page/setting_page_bloc.dart @@ -20,22 +20,31 @@ class SettingPageBloc extends BlocBase { } void loadData(String skipIdentifier) async { - Api api = Api( - '/api/v1/mod/${skipIdentifier.toString()}', - method: NetMethod.GET, - ); - _loadData(await api.onCache()); - _loadData(await api.onRequest()); + NetUtil.request('/api/v1/mod/${skipIdentifier.toString()}', + method: NetMethod.GET, onCache: (data) { + _loadData(data); + }, onSuccess: (data) { + _loadData(data); + }); } void _loadData(dynamic data) { - Map json = Map.from(data); - if (json == null || json.length == 0) { - return; + try { + Map json = Map.from(data); + if (json == null || json.length == 0) { + return; + } + List mods = json['mod_list']; + if (mods.first != null) { + json = Map.from(mods.first); + String d = json['data']; + Map da = + Map.from(convert.jsonDecode(d)); + _style = SettingPageStyleModel.fromJson(da); + _styleController.add(_style); + } + } catch (err) { + Logger.error(err); } - String d = json['data']; - Map da = Map.from(convert.jsonDecode(d)); - _style = SettingPageStyleModel.fromJson(da); - _styleController.add(_style); } } diff --git a/lib/register.dart b/lib/register.dart index a6c9c74..ef3fe19 100644 --- a/lib/register.dart +++ b/lib/register.dart @@ -3,10 +3,15 @@ import 'package:zhiying_base_widget/pages/home_page/home_page.dart'; import 'package:zhiying_base_widget/pages/main_page/main_page.dart'; import 'package:zhiying_base_widget/pages/mine_detail_page/mine_detail_page.dart'; import 'package:zhiying_base_widget/pages/orders_page/orders_page.dart'; +import 'package:zhiying_base_widget/pages/security_page/security_bind_alipay/security_bind_alipay_page.dart'; +import 'package:zhiying_base_widget/pages/security_page/security_mobile/security_mobile.dart'; +import 'package:zhiying_base_widget/pages/security_page/security_page.dart'; +import 'package:zhiying_base_widget/pages/security_page/security_password/security_password.dart'; import 'package:zhiying_base_widget/pages/setting_page/setting_page.dart'; import 'package:zhiying_base_widget/pages/sreach_page/sreach_page.dart'; import 'package:zhiying_base_widget/pages/sreach_result_page/sreach_result_page.dart'; import 'package:zhiying_base_widget/pages/wallet_page/wallet_page.dart'; +import 'package:zhiying_base_widget/pages/webview/base_webview.dart'; import 'package:zhiying_base_widget/widgets/goods_details/footer/goods_details_footer_widget.dart'; import 'package:zhiying_base_widget/widgets/goods_details/goods_list/goods_list_widget.dart'; import 'package:zhiying_base_widget/widgets/goods_details/price/goods_details_price_widget.dart'; @@ -18,7 +23,6 @@ import 'package:zhiying_base_widget/widgets/home/home_banner/home_banner_widget. import 'package:zhiying_base_widget/widgets/home/home_goods/home_goods_creater.dart'; import 'package:zhiying_base_widget/widgets/home/home_notice/home_notice_widget.dart'; import 'package:zhiying_base_widget/widgets/home/home_slide_banner/home_slide_banner_creater.dart'; -import 'package:zhiying_base_widget/widgets/home/home_sreach/home_sreach_creater.dart'; import 'package:zhiying_base_widget/widgets/home/home_sreach/home_sreach_widget.dart'; import 'package:zhiying_base_widget/widgets/mine/mine_data/mine_data.dart'; import 'package:zhiying_base_widget/widgets/mine/mine_header/mine_header.dart'; @@ -59,11 +63,24 @@ class BaseWidgetRegister { // PageFactory.regist('login_account', (model) => LoginAccountPage(model)); // PageFactory.regist('login_invite', (model) => LoginInvitePage()); + // webview + PageFactory.regist('pub.flutter.url', (model) => BaseWebview(model)); + PageFactory.regist( 'pub.flutter.profile_settings', (model) => MineDetailPage()); PageFactory.regist('pub.flutter.settings', (model) => SettingPage(model)); PageFactory.regist('pub.flutter.my_orders', (model) => OrdersPage(model)); + PageFactory.regist( + 'pub.flutter.account_security', (model) => SecurityPage(model)); + PageFactory.regist('pub.flutter.account_security_alipay', + (model) => SecurityBindAlipayPage(model)); + // 登录密码 + PageFactory.regist('pub.flutter.account_security_password', + (model) => SecurityPassword(model)); + // 修改手机号 + PageFactory.regist('pub.flutter.account_security_mobile', + (model) => SecurityMobile(model)); } // 注册控件