Parcourir la source

添加账号安全

tags/0.0.1
Weller il y a 4 ans
Parent
révision
9a10f44899
16 fichiers modifiés avec 1373 ajouts et 48 suppressions
  1. +6
    -3
      lib/pages/goods_details_page/goods_details_page.dart
  2. +1
    -1
      lib/pages/security_page/models/security_style_model.dart
  3. +104
    -0
      lib/pages/security_page/security_bind_alipay/models/security_bind_alipay_model.dart
  4. +67
    -0
      lib/pages/security_page/security_bind_alipay/security_bind_alipay_bloc.dart
  5. +210
    -0
      lib/pages/security_page/security_bind_alipay/security_bind_alipay_page.dart
  6. +215
    -0
      lib/pages/security_page/security_mobile/security_mobile.dart
  7. +167
    -0
      lib/pages/security_page/security_mobile/security_mobile_unbind.dart
  8. +7
    -2
      lib/pages/security_page/security_page.dart
  9. +36
    -28
      lib/pages/security_page/security_page_bloc.dart
  10. +181
    -0
      lib/pages/security_page/security_password/security_password.dart
  11. +157
    -0
      lib/pages/security_page/security_unbind_alipay/security_unbin_alipay.dart
  12. +90
    -0
      lib/pages/security_page/widgets/security_bind_input.dart
  13. +47
    -0
      lib/pages/security_page/widgets/security_code_button.dart
  14. +45
    -0
      lib/pages/security_page/widgets/security_confirm_button.dart
  15. +22
    -13
      lib/pages/setting_page/setting_page_bloc.dart
  16. +18
    -1
      lib/register.dart

+ 6
- 3
lib/pages/goods_details_page/goods_details_page.dart Voir le fichier

@@ -132,9 +132,12 @@ class _GoodsDetailsContainerState extends State<GoodsDetailsContainer> {
Widget _getMainWidget(List<Map<String, dynamic>> 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


+ 1
- 1
lib/pages/security_page/models/security_style_model.dart Voir le fichier

@@ -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;
}
}

+ 104
- 0
lib/pages/security_page/security_bind_alipay/models/security_bind_alipay_model.dart Voir le fichier

@@ -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<String, dynamic> 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<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
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;
}
}

+ 67
- 0
lib/pages/security_page/security_bind_alipay/security_bind_alipay_bloc.dart Voir le fichier

@@ -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<SecurityBindAlipayModel> _dataController =
StreamController<SecurityBindAlipayModel>();

Stream<SecurityBindAlipayModel> 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<String, dynamic> json = Map<String, dynamic>.from(data);
if (json == null || json.length == 0) {
return;
}
List mods = json['mod_list'];
if (mods.first != null) {
json = Map<String, dynamic>.from(mods.first);
String d = json['data'];
Map<String, dynamic> da =
Map<String, dynamic>.from(convert.jsonDecode(d));
_model = SecurityBindAlipayModel.fromJson(da);
_dataController.add(_model);
}
} catch (err) {
Logger.error(err);
}
}

Future<bool> bindAlipay(String name, String account, String code) {
return NetUtil.post('/api/v1/settings/account/security/alipay',
method: NetMethod.POST,
params: Map<String, dynamic>.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;
});
}
}

+ 210
- 0
lib/pages/security_page/security_bind_alipay/security_bind_alipay_page.dart Voir le fichier

@@ -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<String, dynamic> model;

const SecurityBindAlipayPage(this.model, {Key key}) : super(key: key);

@override
_SecurityBindAlipayPageState createState() => _SecurityBindAlipayPageState();
}

class _SecurityBindAlipayPageState extends State<SecurityBindAlipayPage> {
@override
Widget build(BuildContext context) {
Logger.debug(widget.model.toString());
Map<String, dynamic> status = widget.model['status'];
Map<String, dynamic> datas = widget.model['data'];
if (status['alipay_setting'] == '1') {
return SecurityUnbinAlipay(widget.model);
} else {
return BlocProvider<SecurityBindAlipayBloc>(
bloc: SecurityBindAlipayBloc(),
child: _SecurityBindAlipayContainer(datas),
);
}
}
}

class _SecurityBindAlipayContainer extends StatefulWidget {
final Map<String, dynamic> 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<SecurityBindAlipayBloc>(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<SecurityBindAlipayModel>(
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: <Widget>[
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(() {});
});
});
}
}

+ 215
- 0
lib/pages/security_page/security_mobile/security_mobile.dart Voir le fichier

@@ -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<String, dynamic> model;

const SecurityMobile(this.model, {Key key}) : super(key: key);

@override
_SecurityMobileState createState() => _SecurityMobileState();
}

class _SecurityMobileState extends State<SecurityMobile> {
@override
Widget build(BuildContext context) {
Map<String, dynamic> status = widget.model['status'];
if (status['mobile_setting'] == '1') {
return SecurityMobileUnbind(widget.model);
} else {
return _SecurityMobileContainer(widget.model);
}
}
}

class _SecurityMobileContainer extends StatefulWidget {
final Map<String, dynamic> 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<String, dynamic> 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: <Widget>[
_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<String, dynamic>.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<String, dynamic>.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<String, dynamic>.from({
'mobile': _phoneController.text,
'valid_code': _codeController.text,
}),
method: NetMethod.POST, onSuccess: (result) {
Logger.debug(result);
Fluttertoast.showToast(msg: '设置成功');
Navigator.of(context).pop();
});
}
}

+ 167
- 0
lib/pages/security_page/security_mobile/security_mobile_unbind.dart Voir le fichier

@@ -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<String, dynamic> model;

const SecurityMobileUnbind(this.model, {Key key}) : super(key: key);

@override
_SecurityMobileUnbindState createState() => _SecurityMobileUnbindState();
}

class _SecurityMobileUnbindState extends State<SecurityMobileUnbind> {
TextEditingController _codeController = TextEditingController();
int _second = 0;
bool _canConfirm = false;
String _phone;
Map<String, dynamic> _status;

@override
void initState() {
Logger.debug(widget.model.toString());
Map<String, dynamic> 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: <Widget>[
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<String, dynamic>.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)));
});
}
}

+ 7
- 2
lib/pages/security_page/security_page.dart Voir le fichier

@@ -145,8 +145,13 @@ class _SecurityContainerState extends State<_SecurityContainer> {
],
),
),
onTap: () {
RouterUtil.route(item, item.toJson(), context);
onTap: () async {
await RouterUtil.route(
item,
Map<String, dynamic>.from(
{'status': _bloc.securityStatus, 'data': item.toJson()}),
context);
_bloc.loadData(widget.data['skip_identifier']);
},
);
}


+ 36
- 28
lib/pages/security_page/security_page_bloc.dart Voir le fichier

@@ -7,7 +7,7 @@ import 'package:zhiying_comm/zhiying_comm.dart';

class SecurityPageBloc extends BlocBase {
SecurityStyleModel _style;
Map<String, dynamic> _securityStatus;
Map<String, dynamic> securityStatus;

StreamController<SecurityStyleModel> _styleController =
StreamController<SecurityStyleModel>();
@@ -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<String, dynamic>.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<String, dynamic>.from(await _getStatus());
_loadData(data);
});
}

// 获取授权状态等信息
Future<Map> _getStatus() {
Api api = Api(
Future<Map> _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<String, dynamic> json = Map<String, dynamic>.from(data);
if (json == null || json.length == 0) {
return;
}
String d = json['data'];
Map<String, dynamic> da = Map<String, dynamic>.from(convert.jsonDecode(d));
_style = SecurityStyleModel.fromJson(da);

if (_securityStatus != null) {
_style.settings.forEach((item) {
List<String> keys = item.dataKeys;
if (keys.length > 0) {
item.desc = _securityStatus[keys.first] ?? '';
try {
Map<String, dynamic> json = Map<String, dynamic>.from(data);
if (json == null || json.length == 0) {
return;
}
List mods = json['mod_list'];
if (mods.first != null) {
json = Map<String, dynamic>.from(mods.first);
String d = json['data'];
Map<String, dynamic> da =
Map<String, dynamic>.from(convert.jsonDecode(d));
_style = SecurityStyleModel.fromJson(da);

if (securityStatus != null) {
_style.settings.forEach((item) {
List<String> keys = item.dataKeys;
if (keys.length > 0) {
item.desc = securityStatus[keys.first] ?? '';
}
});
}
});
}

_styleController.add(_style);
_styleController.add(_style);
}
} catch (err) {
Logger.error(err);
}
}
}

+ 181
- 0
lib/pages/security_page/security_password/security_password.dart Voir le fichier

@@ -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<String, dynamic> model;

const SecurityPassword(this.model, {Key key}) : super(key: key);

@override
_SecurityPasswordState createState() => _SecurityPasswordState();
}

class _SecurityPasswordState extends State<SecurityPassword> {
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<String, dynamic> 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: <Widget>[
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<String, dynamic>.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();
});
}
}

+ 157
- 0
lib/pages/security_page/security_unbind_alipay/security_unbin_alipay.dart Voir le fichier

@@ -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<String, dynamic> model;

const SecurityUnbinAlipay(this.model, {Key key}) : super(key: key);

@override
_SecurityUnbinAlipayState createState() => _SecurityUnbinAlipayState();
}

class _SecurityUnbinAlipayState extends State<SecurityUnbinAlipay> {
TextEditingController _codeController = TextEditingController();
Map<String, dynamic> _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: <Widget>[
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<String, dynamic>.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)));
});
}
}

+ 90
- 0
lib/pages/security_page/widgets/security_bind_input.dart Voir le fichier

@@ -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<TextInputFormatter> 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<SecurityBindInput> {
@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: <Widget>[
_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,
),
);
}
}

+ 47
- 0
lib/pages/security_page/widgets/security_code_button.dart Voir le fichier

@@ -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();
}
},
);
}
}

+ 45
- 0
lib/pages/security_page/widgets/security_confirm_button.dart Voir le fichier

@@ -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();
}
},
);
}
}

+ 22
- 13
lib/pages/setting_page/setting_page_bloc.dart Voir le fichier

@@ -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<String, dynamic> json = Map<String, dynamic>.from(data);
if (json == null || json.length == 0) {
return;
try {
Map<String, dynamic> json = Map<String, dynamic>.from(data);
if (json == null || json.length == 0) {
return;
}
List mods = json['mod_list'];
if (mods.first != null) {
json = Map<String, dynamic>.from(mods.first);
String d = json['data'];
Map<String, dynamic> da =
Map<String, dynamic>.from(convert.jsonDecode(d));
_style = SettingPageStyleModel.fromJson(da);
_styleController.add(_style);
}
} catch (err) {
Logger.error(err);
}
String d = json['data'];
Map<String, dynamic> da = Map<String, dynamic>.from(convert.jsonDecode(d));
_style = SettingPageStyleModel.fromJson(da);
_styleController.add(_style);
}
}

+ 18
- 1
lib/register.dart Voir le fichier

@@ -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));
}

// 注册控件


Chargement…
Annuler
Enregistrer