Commit d2add4bdc6cdeaa6bafe601b0148e11ebde0f2e3

Authored by xiaoyu
2 parents 98e40f5f ecfd79f5

Merge branch 'master' into xy_phone

# Conflicts:
#	lib/pages/user/user_page.dart
lib/common/widgets/textfield_customer_widget.dart
@@ -4,6 +4,20 @@ import 'package:flutter_screenutil/flutter_screenutil.dart'; @@ -4,6 +4,20 @@ import 'package:flutter_screenutil/flutter_screenutil.dart';
4 import 'package:wow_english/common/extension/string_extension.dart'; 4 import 'package:wow_english/common/extension/string_extension.dart';
5 5
6 class TextFieldCustomerWidget extends StatefulWidget { 6 class TextFieldCustomerWidget extends StatefulWidget {
  7 + final TextEditingController? controller;
  8 + final TextStyle? hitStyle;
  9 + final TextStyle? textStyle;
  10 + final String? bgImageName;
  11 + final String? hitText;
  12 + final double? width;
  13 + final double? height;
  14 + final TextAlign? textAlign;
  15 + final TextInputType? textInputType;
  16 + final bool? obscureText;
  17 + final Function(String value)? onChangeValue;
  18 + final List<TextInputFormatter>? inputFormatters;
  19 + final bool? enabel;
  20 +
7 const TextFieldCustomerWidget({ 21 const TextFieldCustomerWidget({
8 super.key, 22 super.key,
9 this.controller, 23 this.controller,
@@ -18,21 +32,9 @@ class TextFieldCustomerWidget extends StatefulWidget { @@ -18,21 +32,9 @@ class TextFieldCustomerWidget extends StatefulWidget {
18 this.obscureText, 32 this.obscureText,
19 this.onChangeValue, 33 this.onChangeValue,
20 this.inputFormatters, 34 this.inputFormatters,
  35 + this.enabel = true,
21 }); 36 });
22 37
23 - final TextEditingController? controller;  
24 - final TextStyle? hitStyle;  
25 - final TextStyle? textStyle;  
26 - final String? bgImageName;  
27 - final String? hitText;  
28 - final double? width;  
29 - final double? height;  
30 - final TextAlign? textAlign;  
31 - final TextInputType? textInputType;  
32 - final bool? obscureText;  
33 - final Function(String value)? onChangeValue;  
34 - final List<TextInputFormatter>? inputFormatters;  
35 -  
36 @override 38 @override
37 State<StatefulWidget> createState() { 39 State<StatefulWidget> createState() {
38 return _TextFieldCustomerWidgetState(); 40 return _TextFieldCustomerWidgetState();
@@ -52,6 +54,7 @@ class _TextFieldCustomerWidgetState extends State&lt;TextFieldCustomerWidget&gt; { @@ -52,6 +54,7 @@ class _TextFieldCustomerWidgetState extends State&lt;TextFieldCustomerWidget&gt; {
52 fit: BoxFit.fill, 54 fit: BoxFit.fill,
53 )), 55 )),
54 child: TextField( 56 child: TextField(
  57 + enabled: widget.enabel,
55 inputFormatters: widget.inputFormatters, 58 inputFormatters: widget.inputFormatters,
56 controller: widget.controller, 59 controller: widget.controller,
57 textAlign: widget.textAlign ?? TextAlign.center, 60 textAlign: widget.textAlign ?? TextAlign.center,
@@ -61,7 +64,8 @@ class _TextFieldCustomerWidgetState extends State&lt;TextFieldCustomerWidget&gt; { @@ -61,7 +64,8 @@ class _TextFieldCustomerWidgetState extends State&lt;TextFieldCustomerWidget&gt; {
61 decoration: InputDecoration( 64 decoration: InputDecoration(
62 hintText: widget.hitText ?? '', 65 hintText: widget.hitText ?? '',
63 border: InputBorder.none, 66 border: InputBorder.none,
64 - hintStyle: widget.hitStyle ?? TextStyle(fontSize: 16.sp, color: const Color(0xFF999999))), 67 + hintStyle: widget.hitStyle ??
  68 + TextStyle(fontSize: 16.sp, color: const Color(0xFF999999))),
65 style: widget.textStyle ?? 69 style: widget.textStyle ??
66 TextStyle( 70 TextStyle(
67 color: const Color(0xFF333333), 71 color: const Color(0xFF333333),
lib/pages/home/bloc.dart
1 import 'package:bloc/bloc.dart'; 1 import 'package:bloc/bloc.dart';
2 -import 'package:flutter/cupertino.dart';  
3 -import 'package:flutter/foundation.dart';  
4 2
5 import '../../common/core/app_config_helper.dart'; 3 import '../../common/core/app_config_helper.dart';
6 import '../../common/request/dao/system_dao.dart'; 4 import '../../common/request/dao/system_dao.dart';
@@ -12,12 +10,22 @@ import &#39;state.dart&#39;; @@ -12,12 +10,22 @@ import &#39;state.dart&#39;;
12 class HomeBloc extends Bloc<HomeEvent, HomeState> { 10 class HomeBloc extends Bloc<HomeEvent, HomeState> {
13 HomeBloc() : super(HomeState().init()) { 11 HomeBloc() : super(HomeState().init()) {
14 on<InitEvent>(_init); 12 on<InitEvent>(_init);
  13 + on<ExchangeSuccessEvent>(_exchangeSuccess);
15 } 14 }
16 15
  16 + bool exchangeResult = false;
  17 +
17 void _init(InitEvent event, Emitter<HomeState> emit) async { 18 void _init(InitEvent event, Emitter<HomeState> emit) async {
18 await _checkUpdate(emit); 19 await _checkUpdate(emit);
19 } 20 }
20 21
  22 + void _exchangeSuccess(
  23 + ExchangeSuccessEvent event, Emitter<HomeState> emit) async {
  24 + if (exchangeResult) {
  25 + emit(HomeState());
  26 + }
  27 + }
  28 +
21 Future<void> _checkUpdate(Emitter<HomeState> emit) async { 29 Future<void> _checkUpdate(Emitter<HomeState> emit) async {
22 if (AppConfigHelper.checkedUpdate) { 30 if (AppConfigHelper.checkedUpdate) {
23 return; 31 return;
@@ -28,10 +36,12 @@ class HomeBloc extends Bloc&lt;HomeEvent, HomeState&gt; { @@ -28,10 +36,12 @@ class HomeBloc extends Bloc&lt;HomeEvent, HomeState&gt; {
28 if (appVersionEntity == null) { 36 if (appVersionEntity == null) {
29 return; 37 return;
30 } 38 }
31 - Log.d("WQF _checkUpdate appVersionEntity: $appVersionEntity localVersion=$localVersion"); 39 + Log.d(
  40 + "WQF _checkUpdate appVersionEntity: $appVersionEntity localVersion=$localVersion");
32 if (localVersion < int.parse(appVersionEntity.version ?? '0')) { 41 if (localVersion < int.parse(appVersionEntity.version ?? '0')) {
33 emit(UpdateDialogState( 42 emit(UpdateDialogState(
34 - appVersionEntity.volType == UpdateStrategy.FORCE.name, appVersionEntity)); 43 + appVersionEntity.volType == UpdateStrategy.FORCE.name,
  44 + appVersionEntity));
35 } 45 }
36 } 46 }
37 } 47 }
lib/pages/home/event.dart
1 abstract class HomeEvent {} 1 abstract class HomeEvent {}
2 2
3 -class InitEvent extends HomeEvent {}  
4 \ No newline at end of file 3 \ No newline at end of file
  4 +class InitEvent extends HomeEvent {}
  5 +
  6 +class ExchangeSuccessEvent extends HomeEvent {}
lib/pages/home/view.dart
1 -  
2 import 'package:flutter/material.dart'; 1 import 'package:flutter/material.dart';
3 import 'package:flutter_app_update/azhon_app_update.dart'; 2 import 'package:flutter_app_update/azhon_app_update.dart';
4 import 'package:flutter_app_update/update_model.dart'; 3 import 'package:flutter_app_update/update_model.dart';
@@ -9,6 +8,7 @@ import &#39;package:wow_english/common/extension/string_extension.dart&#39;; @@ -9,6 +8,7 @@ import &#39;package:wow_english/common/extension/string_extension.dart&#39;;
9 import 'package:wow_english/models/app_version_entity.dart'; 8 import 'package:wow_english/models/app_version_entity.dart';
10 import 'package:wow_english/pages/home/state.dart'; 9 import 'package:wow_english/pages/home/state.dart';
11 import 'package:wow_english/pages/home/widgets/BaseHomeHeaderWidget.dart'; 10 import 'package:wow_english/pages/home/widgets/BaseHomeHeaderWidget.dart';
  11 +import 'package:wow_english/pages/shop/exchane/bloc/exchange_lesson_bloc.dart';
12 import 'package:wow_english/pages/user/bloc/user_bloc.dart'; 12 import 'package:wow_english/pages/user/bloc/user_bloc.dart';
13 13
14 import '../../common/core/user_util.dart'; 14 import '../../common/core/user_util.dart';
@@ -24,9 +24,9 @@ class HomePage extends StatelessWidget { @@ -24,9 +24,9 @@ class HomePage extends StatelessWidget {
24 @override 24 @override
25 Widget build(BuildContext context) { 25 Widget build(BuildContext context) {
26 return BlocProvider( 26 return BlocProvider(
27 - create: (BuildContext context) =>  
28 - HomeBloc()  
29 - ..add(InitEvent()), 27 + create: (BuildContext context) => HomeBloc()
  28 + ..add(InitEvent())
  29 + ..add(ExchangeSuccessEvent()),
30 child: Builder(builder: (context) => _HomePageView()), 30 child: Builder(builder: (context) => _HomePageView()),
31 ); 31 );
32 } 32 }
@@ -36,12 +36,12 @@ class _HomePageView extends StatelessWidget { @@ -36,12 +36,12 @@ class _HomePageView extends StatelessWidget {
36 @override 36 @override
37 Widget build(BuildContext context) { 37 Widget build(BuildContext context) {
38 return MultiBlocListener(listeners: [ 38 return MultiBlocListener(listeners: [
39 - BlocListener<UserBloc, UserState>(listener: (context, state) {  
40 - }), 39 + BlocListener<UserBloc, UserState>(listener: (context, state) {}),
41 BlocListener<HomeBloc, HomeState>( 40 BlocListener<HomeBloc, HomeState>(
42 listener: (context, state) { 41 listener: (context, state) {
43 if (state is UpdateDialogState) { 42 if (state is UpdateDialogState) {
44 - _showUpdateDialog(context, state.forceUpdate, state.appVersionEntity); 43 + _showUpdateDialog(
  44 + context, state.forceUpdate, state.appVersionEntity);
45 } 45 }
46 }, 46 },
47 ), 47 ),
@@ -49,24 +49,67 @@ class _HomePageView extends StatelessWidget { @@ -49,24 +49,67 @@ class _HomePageView extends StatelessWidget {
49 } 49 }
50 50
51 Widget _homeView() => 51 Widget _homeView() =>
52 - BlocBuilder<HomeBloc, HomeState>(  
53 - builder: (context, state) {  
54 - return Scaffold(  
55 - body: Container(  
56 - color: Colors.white,  
57 - child: Column(  
58 - children: [  
59 - const BaseHomeHeaderWidget(),  
60 - Expanded(  
61 - child: Center(  
62 - child: Row(  
63 - children: [  
64 - Expanded(  
65 - child: GestureDetector( 52 + BlocBuilder<HomeBloc, HomeState>(builder: (context, state) {
  53 + final bloc = BlocProvider.of<HomeBloc>(context);
  54 + return Scaffold(
  55 + body: Container(
  56 + color: Colors.white,
  57 + child: Column(
  58 + children: [
  59 + BaseHomeHeaderWidget(
  60 + callBack: (value) => {
  61 + bloc.exchangeResult = value['exchange'],
  62 + bloc.add(ExchangeSuccessEvent())
  63 + }),
  64 + Expanded(
  65 + child: Center(
  66 + child: Row(
  67 + children: [
  68 + Expanded(
  69 + child: GestureDetector(
  70 + onTap: () {
  71 + _checkPermission(() {
  72 + pushNamed(AppRouteName.courseUnit)
  73 + .then((value) => {
  74 + if (value != null)
  75 + {
  76 + bloc.exchangeResult =
  77 + value['exchange'],
  78 + bloc.add(ExchangeSuccessEvent())
  79 + }
  80 + });
  81 + }, bloc);
  82 + },
  83 + child: Column(
  84 + mainAxisAlignment: MainAxisAlignment.center,
  85 + children: [
  86 + Stack(
  87 + alignment: AlignmentDirectional.center,
  88 + children: [
  89 + Image.asset('bg_frame_module'.assetPng,
  90 + width: 162.5.w, height: 203.5.h),
  91 + Center(
  92 + child: Image.asset(
  93 + 'pic_module_study'.assetPng,
  94 + width: 140.5.w,
  95 + height: 172.h),
  96 + )
  97 + ]),
  98 + 10.verticalSpace,
  99 + Image.asset('label_module_study'.assetPng,
  100 + width: 124.w, height: 34.h),
  101 + ],
  102 + ),
  103 + ),
  104 + ),
  105 + Expanded(
  106 + child: BlocBuilder<UserBloc, UserState>(
  107 + builder: (context, userState) {
  108 + return GestureDetector(
66 onTap: () { 109 onTap: () {
67 _checkPermission(() { 110 _checkPermission(() {
68 - pushNamed(AppRouteName.courseUnit);  
69 - }); 111 + pushNamed(AppRouteName.games);
  112 + }, bloc);
70 }, 113 },
71 child: Column( 114 child: Column(
72 mainAxisAlignment: MainAxisAlignment.center, 115 mainAxisAlignment: MainAxisAlignment.center,
@@ -76,69 +119,31 @@ class _HomePageView extends StatelessWidget { @@ -76,69 +119,31 @@ class _HomePageView extends StatelessWidget {
76 children: [ 119 children: [
77 Image.asset( 120 Image.asset(
78 'bg_frame_module'.assetPng, 121 'bg_frame_module'.assetPng,
79 - width: 162.5.w, height: 203.5.h),  
80 - Center(  
81 - child: Image.asset(  
82 - 'pic_module_study'.assetPng,  
83 - width: 140.5.w,  
84 - height: 172.h),  
85 - ) 122 + width: 162.5.w,
  123 + height: 203.5.h),
  124 + Image.asset(
  125 + 'pic_module_game'.assetPng,
  126 + width: 140.5.w,
  127 + height: 172.h)
86 ]), 128 ]),
87 10.verticalSpace, 129 10.verticalSpace,
88 - Image.asset('label_module_study'.assetPng, 130 + Image.asset('label_module_game'.assetPng,
89 width: 124.w, height: 34.h), 131 width: 124.w, height: 34.h),
90 ], 132 ],
91 - ),  
92 - ),  
93 - ),  
94 - Expanded(  
95 - child: BlocBuilder<UserBloc, UserState>(  
96 - builder: (context, userState) {  
97 - return GestureDetector(  
98 - onTap: () {  
99 - _checkPermission(() {  
100 - pushNamed(AppRouteName.games);  
101 - });  
102 - },  
103 - child: Column(  
104 - mainAxisAlignment: MainAxisAlignment  
105 - .center,  
106 - children: [  
107 - Stack(  
108 - alignment: AlignmentDirectional  
109 - .center,  
110 - children: [  
111 - Image.asset(  
112 - 'bg_frame_module'  
113 - .assetPng,  
114 - width: 162.5.w,  
115 - height: 203.5.h),  
116 - Image.asset(  
117 - 'pic_module_game'  
118 - .assetPng,  
119 - width: 140.5.w,  
120 - height: 172.h)  
121 - ]),  
122 - 10.verticalSpace,  
123 - Image.asset(  
124 - 'label_module_game'.assetPng,  
125 - width: 124.w, height: 34.h),  
126 - ],  
127 - ));  
128 - }),  
129 - ),  
130 - ], 133 + ));
  134 + }),
131 ), 135 ),
132 - ),  
133 - )  
134 - ],  
135 - ),  
136 - ),  
137 - );  
138 - });  
139 - 136 + ],
  137 + ),
  138 + ),
  139 + )
  140 + ],
  141 + ),
  142 + ),
  143 + );
  144 + });
140 145
141 - _checkPermission(VoidCallback onAllowed) { 146 + _checkPermission(VoidCallback onAllowed, HomeBloc bloc) {
142 if (UserUtil.isLogined()) { 147 if (UserUtil.isLogined()) {
143 if (AppConfigHelper.shouldHidePay()) { 148 if (AppConfigHelper.shouldHidePay()) {
144 onAllowed(); 149 onAllowed();
@@ -146,13 +151,18 @@ class _HomePageView extends StatelessWidget { @@ -146,13 +151,18 @@ class _HomePageView extends StatelessWidget {
146 if (UserUtil.hasPermission()) { 151 if (UserUtil.hasPermission()) {
147 onAllowed(); 152 onAllowed();
148 } else { 153 } else {
149 - showTwoActionDialog('提示', '忽略', '去续费',  
150 - '您的课程已到期,请快快续费继续学习吧!', leftTap: () {  
151 - popPage();  
152 - }, rightTap: () {  
153 - popPage();  
154 - pushNamed(AppRouteName.shop);  
155 - }); 154 + showTwoActionDialog('提示', '忽略', '去续费', '您的课程已到期,请快快续费继续学习吧!',
  155 + leftTap: () {
  156 + popPage();
  157 + }, rightTap: () {
  158 + popPage();
  159 + pushNamed(AppRouteName.shop).then((value) {
  160 + if (value != null) {
  161 + bloc.exchangeResult = value['exchange'];
  162 + bloc.add(ExchangeSuccessEvent());
  163 + }
  164 + });
  165 + });
156 } 166 }
157 } 167 }
158 } else { 168 } else {
@@ -161,7 +171,6 @@ class _HomePageView extends StatelessWidget { @@ -161,7 +171,6 @@ class _HomePageView extends StatelessWidget {
161 } 171 }
162 } 172 }
163 173
164 -  
165 ///Flutter侧处理升级对话框 174 ///Flutter侧处理升级对话框
166 ///[forcedUpgrade] 是否强制升级 175 ///[forcedUpgrade] 是否强制升级
167 _showUpdateDialog(BuildContext context, bool forcedUpgrade, 176 _showUpdateDialog(BuildContext context, bool forcedUpgrade,
@@ -175,20 +184,15 @@ class _HomePageView extends StatelessWidget { @@ -175,20 +184,15 @@ class _HomePageView extends StatelessWidget {
175 onWillPop: () => Future.value(!forcedUpgrade), 184 onWillPop: () => Future.value(!forcedUpgrade),
176 child: AlertDialog( 185 child: AlertDialog(
177 title: const Text('发现新版本'), 186 title: const Text('发现新版本'),
178 - content: Text(  
179 - appVersionEntity.remark ??  
180 - '修复了一些已知问题'), 187 + content: Text(appVersionEntity.remark ?? '修复了一些已知问题'),
181 actions: <Widget>[ 188 actions: <Widget>[
182 TextButton( 189 TextButton(
183 child: Text(forcedUpgrade ? '退出' : '取消'), 190 child: Text(forcedUpgrade ? '退出' : '取消'),
184 - onPressed: () =>  
185 - {  
186 - if (forcedUpgrade) {  
187 - AppConfigHelper.exitApp()  
188 - } else  
189 - {  
190 - Navigator.of(context).pop()  
191 - } 191 + onPressed: () => {
  192 + if (forcedUpgrade)
  193 + {AppConfigHelper.exitApp()}
  194 + else
  195 + {Navigator.of(context).pop()}
192 }, 196 },
193 ), 197 ),
194 TextButton( 198 TextButton(
@@ -208,8 +212,8 @@ class _HomePageView extends StatelessWidget { @@ -208,8 +212,8 @@ class _HomePageView extends StatelessWidget {
208 "ic_launcher", 212 "ic_launcher",
209 '', 213 '',
210 ); 214 );
211 - AzhonAppUpdate.update(model).then((value) =>  
212 - debugPrint('$value')); 215 + AzhonAppUpdate.update(model)
  216 + .then((value) => debugPrint('$value'));
213 if (!forcedUpgrade) { 217 if (!forcedUpgrade) {
214 Navigator.of(context).pop(); 218 Navigator.of(context).pop();
215 } 219 }
lib/pages/home/widgets/BaseHomeHeaderWidget.dart
@@ -10,10 +10,13 @@ import &#39;../../../route/route.dart&#39;; @@ -10,10 +10,13 @@ import &#39;../../../route/route.dart&#39;;
10 import '../../../utils/image_util.dart'; 10 import '../../../utils/image_util.dart';
11 import '../../user/bloc/user_bloc.dart'; 11 import '../../user/bloc/user_bloc.dart';
12 12
  13 +typedef HeaderCallback = void Function(dynamic);
  14 +
13 class BaseHomeHeaderWidget extends StatelessWidget { 15 class BaseHomeHeaderWidget extends StatelessWidget {
14 - const BaseHomeHeaderWidget({super.key, this.entity}); 16 + const BaseHomeHeaderWidget({super.key, this.entity, this.callBack});
15 17
16 final CourseEntity? entity; 18 final CourseEntity? entity;
  19 + final HeaderCallback? callBack;
17 20
18 @override 21 @override
19 Widget build(BuildContext context) { 22 Widget build(BuildContext context) {
@@ -50,9 +53,7 @@ class BaseHomeHeaderWidget extends StatelessWidget { @@ -50,9 +53,7 @@ class BaseHomeHeaderWidget extends StatelessWidget {
50 ), 53 ),
51 ), 54 ),
52 GestureDetector( 55 GestureDetector(
53 - onTap: () {  
54 - onUserClick();  
55 - }, 56 + onTap: () => {onUserClick()},
56 child: Container( 57 child: Container(
57 margin: const EdgeInsets.only(left: 7), 58 margin: const EdgeInsets.only(left: 7),
58 padding: const EdgeInsets.all(4.0), 59 padding: const EdgeInsets.all(4.0),
@@ -83,10 +84,16 @@ class BaseHomeHeaderWidget extends StatelessWidget { @@ -83,10 +84,16 @@ class BaseHomeHeaderWidget extends StatelessWidget {
83 !UserUtil.isLogined(), 84 !UserUtil.isLogined(),
84 child: GestureDetector( 85 child: GestureDetector(
85 onTap: () => { 86 onTap: () => {
86 - pushNamed(AppRouteName.shop), 87 + pushNamed(AppRouteName.shop).then((value) {
  88 + if (value != null) {
  89 + if (callBack == null) {
  90 + } else {
  91 + callBack!(value);
  92 + }
  93 + }
  94 + })
87 }, 95 },
88 - child: Row(  
89 - children: <Widget>[ 96 + child: Row(children: <Widget>[
90 Image( 97 Image(
91 width: 20.0.w, 98 width: 20.0.w,
92 height: 20.0.h, 99 height: 20.0.h,
@@ -94,7 +101,9 @@ class BaseHomeHeaderWidget extends StatelessWidget { @@ -94,7 +101,9 @@ class BaseHomeHeaderWidget extends StatelessWidget {
94 // 替换为你的图片资源路径 101 // 替换为你的图片资源路径
95 const SizedBox(width: 6.0), 102 const SizedBox(width: 6.0),
96 // 图片和文本之间的间隔 103 // 图片和文本之间的间隔
97 - Text('还剩${UserUtil.getRemainingValidity()}天'), 104 + UserUtil.hasPermission()
  105 + ? Text('还剩${UserUtil.getRemainingValidity()}天')
  106 + : const Text('未购买'),
98 ]), 107 ]),
99 )), 108 )),
100 ScreenUtil().bottomBarHeight.horizontalSpace, 109 ScreenUtil().bottomBarHeight.horizontalSpace,
@@ -103,12 +112,19 @@ class BaseHomeHeaderWidget extends StatelessWidget { @@ -103,12 +112,19 @@ class BaseHomeHeaderWidget extends StatelessWidget {
103 }, 112 },
104 ); 113 );
105 } 114 }
106 -}  
107 115
108 -void onUserClick() {  
109 - if (UserUtil.isLogined()) {  
110 - pushNamed(AppRouteName.user);  
111 - } else {  
112 - pushNamed(AppRouteName.login); 116 + void onUserClick() {
  117 + if (UserUtil.isLogined()) {
  118 + pushNamed(AppRouteName.user).then((value) {
  119 + if (value != null) {
  120 + if (callBack == null) {
  121 + } else {
  122 + callBack!(value);
  123 + }
  124 + }
  125 + });
  126 + } else {
  127 + pushNamed(AppRouteName.login);
  128 + }
113 } 129 }
114 } 130 }
lib/pages/login/forgetpwd/bloc/forget_pwd_home_bloc.dart
1 import 'package:common_utils/common_utils.dart'; 1 import 'package:common_utils/common_utils.dart';
2 import 'package:flutter/cupertino.dart'; 2 import 'package:flutter/cupertino.dart';
  3 +import 'package:flutter/material.dart';
3 import 'package:flutter_bloc/flutter_bloc.dart'; 4 import 'package:flutter_bloc/flutter_bloc.dart';
4 import 'package:wow_english/common/request/dao/user_dao.dart'; 5 import 'package:wow_english/common/request/dao/user_dao.dart';
5 import 'package:wow_english/common/request/exception.dart'; 6 import 'package:wow_english/common/request/exception.dart';
6 import 'package:wow_english/utils/loading.dart'; 7 import 'package:wow_english/utils/loading.dart';
7 import 'package:wow_english/utils/toast_util.dart'; 8 import 'package:wow_english/utils/toast_util.dart';
8 9
  10 +import 'package:wow_english/common/core/user_util.dart';
  11 +
9 part 'forget_pwd_home_event.dart'; 12 part 'forget_pwd_home_event.dart';
10 part 'forget_pwd_home_state.dart'; 13 part 'forget_pwd_home_state.dart';
11 14
12 class ForgetPwdHomeBloc extends Bloc<ForgetPwdHomeEvent, ForgetPwdHomeState> { 15 class ForgetPwdHomeBloc extends Bloc<ForgetPwdHomeEvent, ForgetPwdHomeState> {
13 - ///是否可以发送验证码  
14 - bool _canSendSms = false;  
15 bool _canSetPwd = false; 16 bool _canSetPwd = false;
16 - 17 + bool _canSendSms = false;
17 bool get canSendSms => _canSendSms; 18 bool get canSendSms => _canSendSms;
18 19
19 bool get canSetPwd => _canSetPwd; 20 bool get canSetPwd => _canSetPwd;
  21 + bool get enableInputPhone {
  22 + if (UserUtil.getUser() == null) {
  23 + return true;
  24 + } else {
  25 + return UserUtil.getUser()!.phoneNum.isEmpty;
  26 + }
  27 + }
20 28
21 - final TextEditingController phoneNumController = TextEditingController(); 29 + final TextEditingController phoneNumController =
  30 + TextEditingController(text: UserUtil.getUser()?.phoneNum);
22 final TextEditingController checkNumController = TextEditingController(); 31 final TextEditingController checkNumController = TextEditingController();
23 -  
24 ForgetPwdHomeBloc() : super(ForgetPwdHomeInitial()) { 32 ForgetPwdHomeBloc() : super(ForgetPwdHomeInitial()) {
25 - on<PhoneNumChangeEvent>(_changePhoneNumber);  
26 on<CheckCodeChangeEvent>(_changeCodeNumber); 33 on<CheckCodeChangeEvent>(_changeCodeNumber);
27 on<SetPassWordEvent>(_setPassWord); 34 on<SetPassWordEvent>(_setPassWord);
28 on<SendSmsCodeEvent>(_sendSmsCode); 35 on<SendSmsCodeEvent>(_sendSmsCode);
  36 + on<PhoneNumChangeEvent>(_changePhoneNumber);
29 } 37 }
30 38
31 - void _changePhoneNumber(PhoneNumChangeEvent event, Emitter<ForgetPwdHomeState> emitter) async { 39 + void _changePhoneNumber(
  40 + PhoneNumChangeEvent event, Emitter<ForgetPwdHomeState> emitter) async {
32 if (phoneNumController.text.isNotEmpty) { 41 if (phoneNumController.text.isNotEmpty) {
33 if (!_canSendSms) { 42 if (!_canSendSms) {
34 _canSendSms = true; 43 _canSendSms = true;
@@ -44,7 +53,8 @@ class ForgetPwdHomeBloc extends Bloc&lt;ForgetPwdHomeEvent, ForgetPwdHomeState&gt; { @@ -44,7 +53,8 @@ class ForgetPwdHomeBloc extends Bloc&lt;ForgetPwdHomeEvent, ForgetPwdHomeState&gt; {
44 } 53 }
45 } 54 }
46 55
47 - void _changeCodeNumber(CheckCodeChangeEvent event, Emitter<ForgetPwdHomeState> emitter) async { 56 + void _changeCodeNumber(
  57 + CheckCodeChangeEvent event, Emitter<ForgetPwdHomeState> emitter) async {
48 if (checkNumController.text.isNotEmpty) { 58 if (checkNumController.text.isNotEmpty) {
49 if (!_canSetPwd) { 59 if (!_canSetPwd) {
50 _canSetPwd = true; 60 _canSetPwd = true;
@@ -60,7 +70,8 @@ class ForgetPwdHomeBloc extends Bloc&lt;ForgetPwdHomeEvent, ForgetPwdHomeState&gt; { @@ -60,7 +70,8 @@ class ForgetPwdHomeBloc extends Bloc&lt;ForgetPwdHomeEvent, ForgetPwdHomeState&gt; {
60 } 70 }
61 } 71 }
62 72
63 - void _setPassWord(SetPassWordEvent event, Emitter<ForgetPwdHomeState> emitter) async { 73 + void _setPassWord(
  74 + SetPassWordEvent event, Emitter<ForgetPwdHomeState> emitter) async {
64 if (!RegexUtil.isMobileExact(phoneNumController.text)) { 75 if (!RegexUtil.isMobileExact(phoneNumController.text)) {
65 showToast('手机号不正确!'); 76 showToast('手机号不正确!');
66 return; 77 return;
@@ -68,7 +79,8 @@ class ForgetPwdHomeBloc extends Bloc&lt;ForgetPwdHomeEvent, ForgetPwdHomeState&gt; { @@ -68,7 +79,8 @@ class ForgetPwdHomeBloc extends Bloc&lt;ForgetPwdHomeEvent, ForgetPwdHomeState&gt; {
68 emitter(SetPwdCheckCodeState()); 79 emitter(SetPwdCheckCodeState());
69 } 80 }
70 81
71 - void _sendSmsCode(SendSmsCodeEvent event, Emitter<ForgetPwdHomeState> emitter) async { 82 + void _sendSmsCode(
  83 + SendSmsCodeEvent event, Emitter<ForgetPwdHomeState> emitter) async {
72 final phoneNumber = phoneNumController.text; 84 final phoneNumber = phoneNumController.text;
73 if (!RegexUtil.isMobileExact(phoneNumber)) { 85 if (!RegexUtil.isMobileExact(phoneNumber)) {
74 showToast('请检查手机号'); 86 showToast('请检查手机号');
@@ -76,12 +88,12 @@ class ForgetPwdHomeBloc extends Bloc&lt;ForgetPwdHomeEvent, ForgetPwdHomeState&gt; { @@ -76,12 +88,12 @@ class ForgetPwdHomeBloc extends Bloc&lt;ForgetPwdHomeEvent, ForgetPwdHomeState&gt; {
76 } 88 }
77 try { 89 try {
78 await loading(() async { 90 await loading(() async {
79 - await UserDao.sendCode(phoneNumber,smsType:'change_passWord'); 91 + await UserDao.sendCode(phoneNumber, smsType: 'change_passWord');
80 }); 92 });
81 emitter(SendSmsCodeState()); 93 emitter(SendSmsCodeState());
82 } catch (e) { 94 } catch (e) {
83 - if(e is ApiException) {  
84 - showToast(e.message??'网络请求失败'); 95 + if (e is ApiException) {
  96 + showToast(e.message ?? '网络请求失败');
85 } 97 }
86 } 98 }
87 } 99 }
lib/pages/login/forgetpwd/bloc/forget_pwd_home_event.dart
@@ -3,10 +3,10 @@ part of &#39;forget_pwd_home_bloc.dart&#39;; @@ -3,10 +3,10 @@ part of &#39;forget_pwd_home_bloc.dart&#39;;
3 @immutable 3 @immutable
4 abstract class ForgetPwdHomeEvent {} 4 abstract class ForgetPwdHomeEvent {}
5 5
6 -class PhoneNumChangeEvent extends ForgetPwdHomeEvent {}  
7 -  
8 class CheckCodeChangeEvent extends ForgetPwdHomeEvent {} 6 class CheckCodeChangeEvent extends ForgetPwdHomeEvent {}
9 7
10 class SetPassWordEvent extends ForgetPwdHomeEvent {} 8 class SetPassWordEvent extends ForgetPwdHomeEvent {}
11 9
12 class SendSmsCodeEvent extends ForgetPwdHomeEvent {} 10 class SendSmsCodeEvent extends ForgetPwdHomeEvent {}
  11 +
  12 +class PhoneNumChangeEvent extends ForgetPwdHomeEvent {}
lib/pages/login/forgetpwd/forget_password_home_page.dart
@@ -41,44 +41,49 @@ class _ForgetPasswordHomePageView extends StatelessWidget { @@ -41,44 +41,49 @@ class _ForgetPasswordHomePageView extends StatelessWidget {
41 } 41 }
42 // todo 后续需要改成在当前页面,验证过验证码后,再跳转到设置密码页面 42 // todo 后续需要改成在当前页面,验证过验证码后,再跳转到设置密码页面
43 // change_passWord 43 // change_passWord
44 - SetPassWordPage.push(context, SetPwdPageType.resetPwd, phoneNum: phoneNum, smsCode: smsCode); 44 + SetPassWordPage.push(context, SetPwdPageType.resetPwd,
  45 + phoneNum: phoneNum, smsCode: smsCode);
45 } 46 }
46 }, 47 },
47 child: _buildForgetPwdView(), 48 child: _buildForgetPwdView(),
48 ); 49 );
49 } 50 }
50 51
51 - Widget _buildForgetPwdView() => BlocBuilder<ForgetPwdHomeBloc, ForgetPwdHomeState>(builder: (context, state) {  
52 - final bloc = BlocProvider.of<ForgetPwdHomeBloc>(context);  
53 - return Scaffold(  
54 - appBar: const WEAppBar(),  
55 - body: Container(  
56 - color: Colors.white,  
57 - child: SafeArea(  
58 - child: SingleChildScrollView(  
59 - child: Padding(  
60 - padding: EdgeInsets.only(left: 49.w, right: 10.w),  
61 - child: Column(  
62 - children: [  
63 - Row( 52 + Widget _buildForgetPwdView() =>
  53 + BlocBuilder<ForgetPwdHomeBloc, ForgetPwdHomeState>(
  54 + builder: (context, state) {
  55 + final bloc = BlocProvider.of<ForgetPwdHomeBloc>(context);
  56 + return Scaffold(
  57 + appBar: const WEAppBar(),
  58 + body: Container(
  59 + color: Colors.white,
  60 + child: SafeArea(
  61 + child: SingleChildScrollView(
  62 + child: Padding(
  63 + padding: EdgeInsets.only(left: 49.w, right: 10.w),
  64 + child: Column(
64 children: [ 65 children: [
65 - Image.asset(  
66 - 'wow_logo'.assetPng,  
67 - height: 49.w,  
68 - width: 83.5.h, 66 + Row(
  67 + children: [
  68 + Image.asset(
  69 + 'wow_logo'.assetPng,
  70 + height: 49.w,
  71 + width: 83.5.h,
  72 + ),
  73 + 12.5.horizontalSpace,
  74 + Text(
  75 + '修改密码\n请输入您的手机号和验证码吧',
  76 + style: TextStyle(
  77 + fontSize: 16.sp,
  78 + color: const Color(0xFF666666)),
  79 + )
  80 + ],
69 ), 81 ),
70 - 12.5.horizontalSpace,  
71 - Text(  
72 - '修改密码\n请输入您的手机号和验证码吧',  
73 - style: TextStyle(fontSize: 16.sp, color: const Color(0xFF666666)),  
74 - )  
75 - ],  
76 - ),  
77 - Row(  
78 - crossAxisAlignment: CrossAxisAlignment.start,  
79 - children: [  
80 - Expanded(  
81 - child: Column( 82 + Row(
  83 + crossAxisAlignment: CrossAxisAlignment.start,
  84 + children: [
  85 + Expanded(
  86 + child: Column(
82 children: [ 87 children: [
83 44.5.verticalSpace, 88 44.5.verticalSpace,
84 Row( 89 Row(
@@ -91,20 +96,31 @@ class _ForgetPasswordHomePageView extends StatelessWidget { @@ -91,20 +96,31 @@ class _ForgetPasswordHomePageView extends StatelessWidget {
91 15.horizontalSpace, 96 15.horizontalSpace,
92 Expanded( 97 Expanded(
93 child: TextFieldCustomerWidget( 98 child: TextFieldCustomerWidget(
94 - height: 50.h,  
95 - hitText: '请输入当前手机号',  
96 - textInputType: TextInputType.phone,  
97 - bgImageName: 'Input_layer_up',  
98 - onChangeValue: (String value) {  
99 - bloc.add(PhoneNumChangeEvent());  
100 - },  
101 - controller: bloc.phoneNumController,  
102 - )) 99 + height: 50.h,
  100 + textStyle: !bloc.enableInputPhone
  101 + ? TextStyle(
  102 + fontWeight: FontWeight.w500,
  103 + color: const Color(0xFF999999),
  104 + fontSize: 21.sp,
  105 + )
  106 + : TextStyle(
  107 + color: const Color(0xFF333333),
  108 + fontSize: 16.sp,
  109 + ),
  110 + textInputType: TextInputType.phone,
  111 + bgImageName: 'Input_layer_up',
  112 + enabel: bloc.enableInputPhone,
  113 + onChangeValue: (String value) {
  114 + bloc.add(PhoneNumChangeEvent());
  115 + },
  116 + controller: bloc.phoneNumController,
  117 + ))
103 ], 118 ],
104 ), 119 ),
105 11.5.verticalSpace, 120 11.5.verticalSpace,
106 Row( 121 Row(
107 - mainAxisAlignment: MainAxisAlignment.spaceBetween, 122 + mainAxisAlignment:
  123 + MainAxisAlignment.spaceBetween,
108 children: [ 124 children: [
109 Image.asset( 125 Image.asset(
110 'lock'.assetPng, 126 'lock'.assetPng,
@@ -114,57 +130,64 @@ class _ForgetPasswordHomePageView extends StatelessWidget { @@ -114,57 +130,64 @@ class _ForgetPasswordHomePageView extends StatelessWidget {
114 18.5.horizontalSpace, 130 18.5.horizontalSpace,
115 Expanded( 131 Expanded(
116 child: TextFieldCustomerWidget( 132 child: TextFieldCustomerWidget(
117 - hitText: '请输入验证码',  
118 - bgImageName: 'Input_layer_down',  
119 - onChangeValue: (String value) {  
120 - bloc.add(CheckCodeChangeEvent());  
121 - },  
122 - textInputType: TextInputType.emailAddress,  
123 - controller: bloc.checkNumController,  
124 - )), 133 + hitText: '请输入验证码',
  134 + bgImageName: 'Input_layer_down',
  135 + onChangeValue: (String value) {
  136 + bloc.add(CheckCodeChangeEvent());
  137 + },
  138 + textInputType: TextInputType.emailAddress,
  139 + controller: bloc.checkNumController,
  140 + )),
125 16.5.horizontalSpace, 141 16.5.horizontalSpace,
126 TimerWidget( 142 TimerWidget(
127 pageType: 1, 143 pageType: 1,
128 - canSendSms: bloc.canSendSms,  
129 - sendSmsEvent: () => bloc.add(SendSmsCodeEvent()), 144 + canSendSms: bloc.enableInputPhone
  145 + ? bloc.canSendSms
  146 + : true,
  147 + sendSmsEvent: () =>
  148 + bloc.add(SendSmsCodeEvent()),
130 ) 149 )
131 ], 150 ],
132 ) 151 )
133 ], 152 ],
134 )), 153 )),
135 - 2.verticalSpace,  
136 - Image.asset(  
137 - 'steven_bride'.assetPng,  
138 - height: 173.h,  
139 - width: 157.w, 154 + 2.verticalSpace,
  155 + Image.asset(
  156 + 'steven_bride'.assetPng,
  157 + height: 173.h,
  158 + width: 157.w,
  159 + )
  160 + ],
  161 + ),
  162 + GestureDetector(
  163 + onTap: () {
  164 + if (bloc.canSetPwd) {
  165 + bloc.add(SetPassWordEvent());
  166 + }
  167 + },
  168 + child: Container(
  169 + decoration: BoxDecoration(
  170 + image: DecorationImage(
  171 + image: AssetImage(bloc.canSetPwd
  172 + ? 'login_enter'.assetPng
  173 + : 'login_enter_dis'.assetPng),
  174 + fit: BoxFit.fill),
  175 + ),
  176 + padding: EdgeInsets.symmetric(
  177 + horizontal: 28.w, vertical: 14.h),
  178 + child: Text(
  179 + '确定',
  180 + style:
  181 + TextStyle(fontSize: 16.sp, color: Colors.white),
  182 + ),
  183 + ),
140 ) 184 )
141 ], 185 ],
142 ), 186 ),
143 - GestureDetector(  
144 - onTap: () {  
145 - if (bloc.canSetPwd) {  
146 - bloc.add(SetPassWordEvent());  
147 - }  
148 - },  
149 - child: Container(  
150 - decoration: BoxDecoration(  
151 - image: DecorationImage(  
152 - image: AssetImage(bloc.canSetPwd ? 'login_enter'.assetPng : 'login_enter_dis'.assetPng),  
153 - fit: BoxFit.fill),  
154 - ),  
155 - padding: EdgeInsets.symmetric(horizontal: 28.w, vertical: 14.h),  
156 - child: Text(  
157 - '确定',  
158 - style: TextStyle(fontSize: 16.sp, color: Colors.white),  
159 - ),  
160 - ),  
161 - )  
162 - ], 187 + ),
163 ), 188 ),
164 ), 189 ),
165 ), 190 ),
166 - ),  
167 - ),  
168 - );  
169 - }); 191 + );
  192 + });
170 } 193 }
lib/pages/reading/bloc/reading_bloc.dart
@@ -130,8 +130,6 @@ class ReadingPageBloc @@ -130,8 +130,6 @@ class ReadingPageBloc
130 "setMethodCallHandler method=${call.method} arguments=${call.arguments}"); 130 "setMethodCallHandler method=${call.method} arguments=${call.arguments}");
131 if (call.method == 'voiceResult') { 131 if (call.method == 'voiceResult') {
132 //评测结果 132 //评测结果
133 - await audioPlayer.setAudioContext(AudioContext());  
134 - await audioPlayer.setBalance(0.0);  
135 add(XSVoiceResultEvent(call.arguments)); 133 add(XSVoiceResultEvent(call.arguments));
136 return; 134 return;
137 } 135 }
@@ -152,8 +150,6 @@ class ReadingPageBloc @@ -152,8 +150,6 @@ class ReadingPageBloc
152 print(call.method == 'voiceEnd' ? '评测结束' : '评测取消'); 150 print(call.method == 'voiceEnd' ? '评测结束' : '评测取消');
153 } 151 }
154 _isRecording = false; 152 _isRecording = false;
155 - await audioPlayer.setAudioContext(AudioContext());  
156 - await audioPlayer.setBalance(0.0);  
157 add(OnXSVoiceStateChangeEvent()); 153 add(OnXSVoiceStateChangeEvent());
158 return; 154 return;
159 } 155 }
@@ -161,8 +157,6 @@ class ReadingPageBloc @@ -161,8 +157,6 @@ class ReadingPageBloc
161 if (call.method == 'voiceFail') { 157 if (call.method == 'voiceFail') {
162 //评测失败 158 //评测失败
163 _isRecording = false; 159 _isRecording = false;
164 - await audioPlayer.setAudioContext(AudioContext());  
165 - await audioPlayer.setBalance(0.0);  
166 EasyLoading.showToast('评测失败'); 160 EasyLoading.showToast('评测失败');
167 return; 161 return;
168 } 162 }
@@ -231,7 +225,8 @@ class ReadingPageBloc @@ -231,7 +225,8 @@ class ReadingPageBloc
231 ///播放原音音频 225 ///播放原音音频
232 /// - [force]: 是否强制播放(true:不管当前状态如何,都会播放目标原音音频,比如翻页场景) 226 /// - [force]: 是否强制播放(true:不管当前状态如何,都会播放目标原音音频,比如翻页场景)
233 /// (false:如果正在播放,暂停播放,比如点击播放按钮场景) 227 /// (false:如果正在播放,暂停播放,比如点击播放按钮场景)
234 - void _playOriginalAudioInner(String? audioUrl, {bool forcePlay = false}) async { 228 + void _playOriginalAudioInner(String? audioUrl,
  229 + {bool forcePlay = false}) async {
235 if (_isRecordAudioPlaying) { 230 if (_isRecordAudioPlaying) {
236 await audioPlayer.stop(); 231 await audioPlayer.stop();
237 _isRecordAudioPlaying = false; 232 _isRecordAudioPlaying = false;
@@ -261,8 +256,7 @@ class ReadingPageBloc @@ -261,8 +256,7 @@ class ReadingPageBloc
261 256
262 Future<void> _playRecordAudioInner() async { 257 Future<void> _playRecordAudioInner() async {
263 Log.d( 258 Log.d(
264 - "_playRecordAudioInner _isOriginAudioPlaying=$_isOriginAudioPlaying _isRecordAudioPlaying=$_isRecordAudioPlaying url=${currentPageData()  
265 - ?.recordUrl}"); 259 + "_playRecordAudioInner _isOriginAudioPlaying=$_isOriginAudioPlaying _isRecordAudioPlaying=$_isRecordAudioPlaying url=${currentPageData()?.recordUrl}");
266 if (_isOriginAudioPlaying) { 260 if (_isOriginAudioPlaying) {
267 ///如果正在播放原音,暂停 261 ///如果正在播放原音,暂停
268 await audioPlayer.stop(); 262 await audioPlayer.stop();
@@ -282,9 +276,7 @@ class ReadingPageBloc @@ -282,9 +276,7 @@ class ReadingPageBloc
282 276
283 Future<void> _playAudio(String? audioUrl) async { 277 Future<void> _playAudio(String? audioUrl) async {
284 if (audioUrl!.isNotEmpty) { 278 if (audioUrl!.isNotEmpty) {
285 - await audioPlayer.play(UrlSource(audioUrl),  
286 - balance: 0.0, ctx: AudioContext()  
287 - ); 279 + await audioPlayer.play(UrlSource(audioUrl));
288 } 280 }
289 } 281 }
290 282
@@ -354,6 +346,7 @@ class ReadingPageBloc @@ -354,6 +346,7 @@ class ReadingPageBloc
354 duration: const Duration(seconds: 2)); 346 duration: const Duration(seconds: 2));
355 currentPageData()?.recordScore = overall; 347 currentPageData()?.recordScore = overall;
356 currentPageData()?.recordUrl = args['audioUrl'] + '.mp3'; 348 currentPageData()?.recordUrl = args['audioUrl'] + '.mp3';
  349 +
357 ///完成录音后紧接着播放录音 350 ///完成录音后紧接着播放录音
358 await _playRecordAudioInner(); 351 await _playRecordAudioInner();
359 if (isLastPage()) { 352 if (isLastPage()) {
lib/pages/shop/exchane/bloc/exchange_lesson_bloc.dart
1 import 'package:flutter/cupertino.dart'; 1 import 'package:flutter/cupertino.dart';
2 import 'package:flutter_bloc/flutter_bloc.dart'; 2 import 'package:flutter_bloc/flutter_bloc.dart';
  3 +import 'package:wow_english/common/request/dao/user_dao.dart';
3 import 'package:wow_english/utils/loading.dart'; 4 import 'package:wow_english/utils/loading.dart';
4 5
  6 +import 'package:wow_english/common/core/user_util.dart';
  7 +import 'package:wow_english/models/user_entity.dart';
  8 +
5 import '../../../../common/request/dao/request_dao.dart'; 9 import '../../../../common/request/dao/request_dao.dart';
6 10
7 part 'exchange_lesson_event.dart'; 11 part 'exchange_lesson_event.dart';
8 part 'exchange_lesson_state.dart'; 12 part 'exchange_lesson_state.dart';
9 13
10 -class ExchangeLessonBloc extends Bloc<ExchangeLessonEvent, ExchangeLessonState> {  
11 - 14 +class ExchangeLessonBloc
  15 + extends Bloc<ExchangeLessonEvent, ExchangeLessonState> {
12 final TextEditingController codeNumberController = TextEditingController(); 16 final TextEditingController codeNumberController = TextEditingController();
13 17
14 bool _checkCode = false; 18 bool _checkCode = false;
  19 + bool exchangeSuccess = false;
15 20
16 bool get checkCode => _checkCode; 21 bool get checkCode => _checkCode;
17 22
@@ -20,8 +25,9 @@ class ExchangeLessonBloc extends Bloc&lt;ExchangeLessonEvent, ExchangeLessonState&gt; @@ -20,8 +25,9 @@ class ExchangeLessonBloc extends Bloc&lt;ExchangeLessonEvent, ExchangeLessonState&gt;
20 on<CheckCodeEvent>(_requestCheckCode); 25 on<CheckCodeEvent>(_requestCheckCode);
21 } 26 }
22 27
23 - _codeNumberChange(CodeNumberChangeEvent event,Emitter<ExchangeLessonState> emitter) async {  
24 - if(codeNumberController.text.isNotEmpty) { 28 + _codeNumberChange(
  29 + CodeNumberChangeEvent event, Emitter<ExchangeLessonState> emitter) async {
  30 + if (codeNumberController.text.isNotEmpty) {
25 if (!_checkCode) { 31 if (!_checkCode) {
26 _checkCode = true; 32 _checkCode = true;
27 emitter(CheckCodeTypeChangeState()); 33 emitter(CheckCodeTypeChangeState());
@@ -34,13 +40,23 @@ class ExchangeLessonBloc extends Bloc&lt;ExchangeLessonEvent, ExchangeLessonState&gt; @@ -34,13 +40,23 @@ class ExchangeLessonBloc extends Bloc&lt;ExchangeLessonEvent, ExchangeLessonState&gt;
34 } 40 }
35 } 41 }
36 42
37 - _requestCheckCode(CheckCodeEvent event, Emitter<ExchangeLessonState> emitter) async { 43 + _requestCheckCode(
  44 + CheckCodeEvent event, Emitter<ExchangeLessonState> emitter) async {
38 try { 45 try {
39 await loading(() async { 46 await loading(() async {
40 await RequestDao.exchange(codeNumberController.text); 47 await RequestDao.exchange(codeNumberController.text);
  48 + // 更新本地数据
  49 + UserEntity? userEntity = await UserDao.getUserInfo();
  50 + final token = UserUtil.getUser()?.token;
  51 + if (userEntity != null) {
  52 + userEntity.token = token;
  53 + UserUtil.saveUser(userEntity);
  54 + }
  55 + exchangeSuccess = true;
41 emitter(CheckCodeResultState(true)); 56 emitter(CheckCodeResultState(true));
42 }); 57 });
43 } catch (e) { 58 } catch (e) {
  59 + exchangeSuccess = false;
44 emitter(CheckCodeResultState(false)); 60 emitter(CheckCodeResultState(false));
45 } 61 }
46 } 62 }
lib/pages/shop/exchane/exchange_lesson_page.dart
@@ -3,6 +3,7 @@ import &#39;package:flutter_bloc/flutter_bloc.dart&#39;; @@ -3,6 +3,7 @@ import &#39;package:flutter_bloc/flutter_bloc.dart&#39;;
3 import 'package:flutter_screenutil/flutter_screenutil.dart'; 3 import 'package:flutter_screenutil/flutter_screenutil.dart';
4 import 'package:wow_english/common/extension/string_extension.dart'; 4 import 'package:wow_english/common/extension/string_extension.dart';
5 import 'package:wow_english/common/widgets/textfield_customer_widget.dart'; 5 import 'package:wow_english/common/widgets/textfield_customer_widget.dart';
  6 +import 'package:wow_english/pages/home/event.dart';
6 import 'package:wow_english/pages/shop/exchane/widegts/exchange_result_dialog.dart'; 7 import 'package:wow_english/pages/shop/exchane/widegts/exchange_result_dialog.dart';
7 import 'package:wow_english/route/route.dart'; 8 import 'package:wow_english/route/route.dart';
8 9
@@ -27,6 +28,8 @@ class _ExchangeLessonPage extends StatelessWidget { @@ -27,6 +28,8 @@ class _ExchangeLessonPage extends StatelessWidget {
27 return BlocListener<ExchangeLessonBloc, ExchangeLessonState>( 28 return BlocListener<ExchangeLessonBloc, ExchangeLessonState>(
28 listener: (context, state) { 29 listener: (context, state) {
29 if (state is CheckCodeResultState) { 30 if (state is CheckCodeResultState) {
  31 + final bloc = BlocProvider.of<ExchangeLessonBloc>(context);
  32 + bloc.exchangeSuccess = state.result;
30 showDialog<ExChangeResultDialog>( 33 showDialog<ExChangeResultDialog>(
31 context: context, 34 context: context,
32 barrierDismissible: !state.result, 35 barrierDismissible: !state.result,
@@ -34,7 +37,7 @@ class _ExchangeLessonPage extends StatelessWidget { @@ -34,7 +37,7 @@ class _ExchangeLessonPage extends StatelessWidget {
34 return ExChangeResultDialog( 37 return ExChangeResultDialog(
35 resultType: state.result, 38 resultType: state.result,
36 onTap: () { 39 onTap: () {
37 - popPage(); 40 + popPage(data: {'exchange': bloc.exchangeSuccess});
38 }); 41 });
39 }); 42 });
40 } 43 }
@@ -117,12 +120,15 @@ class _ExchangeLessonPage extends StatelessWidget { @@ -117,12 +120,15 @@ class _ExchangeLessonPage extends StatelessWidget {
117 ], 120 ],
118 ), 121 ),
119 ), 122 ),
120 - const Positioned( 123 + Positioned(
121 top: 0, 124 top: 0,
122 left: 0, 125 left: 0,
123 right: 0, 126 right: 0,
124 child: WEAppBar( 127 child: WEAppBar(
125 backgroundColor: Colors.transparent, 128 backgroundColor: Colors.transparent,
  129 + onBack: () {
  130 + popPage(data: {'exchange': bloc.exchangeSuccess});
  131 + },
126 ), 132 ),
127 ), 133 ),
128 ], 134 ],
lib/pages/shop/home/bloc/shop_home_bloc.dart
  1 +import 'dart:ffi';
1 2
2 import 'package:bloc/bloc.dart'; 3 import 'package:bloc/bloc.dart';
3 import 'package:meta/meta.dart'; 4 import 'package:meta/meta.dart';
@@ -12,11 +13,12 @@ part &#39;shop_home_event.dart&#39;; @@ -12,11 +13,12 @@ part &#39;shop_home_event.dart&#39;;
12 part 'shop_home_state.dart'; 13 part 'shop_home_state.dart';
13 14
14 class ShopHomeBloc extends Bloc<ShopHomeEvent, ShopHomeState> { 15 class ShopHomeBloc extends Bloc<ShopHomeEvent, ShopHomeState> {
15 -  
16 List<ProductEntity?> _productDatas = []; 16 List<ProductEntity?> _productDatas = [];
17 17
18 List<ProductEntity?> get productDatas => _productDatas; 18 List<ProductEntity?> get productDatas => _productDatas;
19 19
  20 + bool exchangeResult = false;
  21 +
20 ShopHomeBloc() : super(ShopHomeInitial()) { 22 ShopHomeBloc() : super(ShopHomeInitial()) {
21 on<ShopHomeEvent>((event, emit) { 23 on<ShopHomeEvent>((event, emit) {
22 // TODO: implement event handler 24 // TODO: implement event handler
@@ -24,7 +26,8 @@ class ShopHomeBloc extends Bloc&lt;ShopHomeEvent, ShopHomeState&gt; { @@ -24,7 +26,8 @@ class ShopHomeBloc extends Bloc&lt;ShopHomeEvent, ShopHomeState&gt; {
24 on<RequestDataEvent>(_requestData); 26 on<RequestDataEvent>(_requestData);
25 } 27 }
26 28
27 - void _requestData(RequestDataEvent event, Emitter<ShopHomeState> emitter) async { 29 + void _requestData(
  30 + RequestDataEvent event, Emitter<ShopHomeState> emitter) async {
28 try { 31 try {
29 await loading(() async { 32 await loading(() async {
30 _productDatas = await ShopDao.productList() ?? []; 33 _productDatas = await ShopDao.productList() ?? [];
lib/pages/shop/home/shop_home_page.dart
@@ -44,7 +44,10 @@ class _ShopHomeView extends StatelessWidget { @@ -44,7 +44,10 @@ class _ShopHomeView extends StatelessWidget {
44 ), 44 ),
45 color: Colors.white, 45 color: Colors.white,
46 onPressed: () { 46 onPressed: () {
47 - Navigator.of(context).pushNamed(AppRouteName.exLesson); 47 + pushNamed(AppRouteName.exLesson).then((value) => {
  48 + if (value != null)
  49 + {bloc.exchangeResult = value['exchange']}
  50 + });
48 }, 51 },
49 ), 52 ),
50 IconButton( 53 IconButton(
@@ -59,6 +62,9 @@ class _ShopHomeView extends StatelessWidget { @@ -59,6 +62,9 @@ class _ShopHomeView extends StatelessWidget {
59 }, 62 },
60 ) 63 )
61 ], 64 ],
  65 + onBack: () {
  66 + popPage(data: {'exchange': bloc.exchangeResult});
  67 + },
62 ), 68 ),
63 body: Center( 69 body: Center(
64 child: Padding( 70 child: Padding(
@@ -73,9 +79,11 @@ class _ShopHomeView extends StatelessWidget { @@ -73,9 +79,11 @@ class _ShopHomeView extends StatelessWidget {
73 ), 79 ),
74 itemBuilder: (BuildContext context, int index) { 80 itemBuilder: (BuildContext context, int index) {
75 final productEntity = bloc.productDatas[index]; 81 final productEntity = bloc.productDatas[index];
76 - return ProductItem(onTap: () {  
77 - pushNamed(AppRouteName.pay, arguments: productEntity);  
78 - }, entity: productEntity); 82 + return ProductItem(
  83 + onTap: () {
  84 + pushNamed(AppRouteName.pay, arguments: productEntity);
  85 + },
  86 + entity: productEntity);
79 }), 87 }),
80 ), 88 ),
81 ), 89 ),
lib/pages/unit/bloc.dart
@@ -12,7 +12,6 @@ import &#39;event.dart&#39;; @@ -12,7 +12,6 @@ import &#39;event.dart&#39;;
12 import 'state.dart'; 12 import 'state.dart';
13 13
14 class UnitBloc extends Bloc<UnitEvent, UnitState> { 14 class UnitBloc extends Bloc<UnitEvent, UnitState> {
15 -  
16 CourseModuleEntity? _moduleEntity; 15 CourseModuleEntity? _moduleEntity;
17 16
18 CourseModuleEntity? get moduleEntity => _moduleEntity; 17 CourseModuleEntity? get moduleEntity => _moduleEntity;
@@ -21,12 +20,14 @@ class UnitBloc extends Bloc&lt;UnitEvent, UnitState&gt; { @@ -21,12 +20,14 @@ class UnitBloc extends Bloc&lt;UnitEvent, UnitState&gt; {
21 20
22 CourseUnitEntity? get unitData => _unitData; 21 CourseUnitEntity? get unitData => _unitData;
23 22
  23 + bool exchangeResult = false;
24 24
25 UnitBloc(CourseModuleEntity? courseEntity) : super(UnitState().init()) { 25 UnitBloc(CourseModuleEntity? courseEntity) : super(UnitState().init()) {
26 on<RequestUnitDataEvent>(_requestUnitDatas); 26 on<RequestUnitDataEvent>(_requestUnitDatas);
27 } 27 }
28 28
29 - void _requestUnitDatas(RequestUnitDataEvent event, Emitter<UnitState> emitter) async { 29 + void _requestUnitDatas(
  30 + RequestUnitDataEvent event, Emitter<UnitState> emitter) async {
30 try { 31 try {
31 await loading(() async { 32 await loading(() async {
32 _unitData = await LessonDao.courseUnit(event.moduleId); 33 _unitData = await LessonDao.courseUnit(event.moduleId);
@@ -51,7 +52,8 @@ class UnitBloc extends Bloc&lt;UnitEvent, UnitState&gt; { @@ -51,7 +52,8 @@ class UnitBloc extends Bloc&lt;UnitEvent, UnitState&gt; {
51 } else if (type == HeaderActionType.listen) { 52 } else if (type == HeaderActionType.listen) {
52 pushNamed(AppRouteName.listen); 53 pushNamed(AppRouteName.listen);
53 } else if (type == HeaderActionType.shop) { 54 } else if (type == HeaderActionType.shop) {
54 - pushNamed(AppRouteName.shop); 55 + pushNamed(AppRouteName.shop)
  56 + .then((value) => {exchangeResult = value['exchange']});
55 } else if (type == HeaderActionType.user) { 57 } else if (type == HeaderActionType.user) {
56 pushNamed(AppRouteName.user); 58 pushNamed(AppRouteName.user);
57 } 59 }
lib/pages/unit/view.dart
@@ -40,6 +40,9 @@ class UnitPage extends StatelessWidget { @@ -40,6 +40,9 @@ class UnitPage extends StatelessWidget {
40 children: [ 40 children: [
41 HomeTabHeaderWidget( 41 HomeTabHeaderWidget(
42 courseModuleCode: bloc.getCourseModuleCode(), 42 courseModuleCode: bloc.getCourseModuleCode(),
  43 + onBack: () {
  44 + popPage(data: {'exchange': bloc.exchangeResult});
  45 + },
43 actionTap: (HeaderActionType type) { 46 actionTap: (HeaderActionType type) {
44 bloc.headerActionEvent(type); 47 bloc.headerActionEvent(type);
45 }, 48 },
@@ -67,10 +70,12 @@ class UnitPage extends StatelessWidget { @@ -67,10 +70,12 @@ class UnitPage extends StatelessWidget {
67 'courseUnitId': data.id 70 'courseUnitId': data.id
68 }).then((value) { 71 }).then((value) {
69 if (value != null) { 72 if (value != null) {
70 - Map<String, dynamic> dataMap = value as Map<String, dynamic>; 73 + Map<String, dynamic> dataMap =
  74 + value as Map<String, dynamic>;
71 bool needRefresh = dataMap['needRefresh']; 75 bool needRefresh = dataMap['needRefresh'];
72 if (needRefresh) { 76 if (needRefresh) {
73 - bloc.add(RequestUnitDataEvent(courseModuleEntity?.id)); 77 + bloc.add(RequestUnitDataEvent(
  78 + courseModuleEntity?.id));
74 } 79 }
75 } 80 }
76 }); 81 });
lib/pages/unit/widget/home_tab_header_widget.dart
@@ -21,12 +21,13 @@ enum HeaderActionType { @@ -21,12 +21,13 @@ enum HeaderActionType {
21 } 21 }
22 22
23 class HomeTabHeaderWidget extends StatelessWidget { 23 class HomeTabHeaderWidget extends StatelessWidget {
24 - const HomeTabHeaderWidget({super.key, this.courseModuleCode, this.actionTap}); 24 + const HomeTabHeaderWidget(
  25 + {super.key, this.courseModuleCode, this.actionTap, this.onBack});
25 26
26 final String? courseModuleCode; 27 final String? courseModuleCode;
27 28
28 final Function(HeaderActionType type)? actionTap; 29 final Function(HeaderActionType type)? actionTap;
29 - 30 + final VoidCallback? onBack;
30 @override 31 @override
31 Widget build(BuildContext context) { 32 Widget build(BuildContext context) {
32 return BlocBuilder<UserBloc, UserState>( 33 return BlocBuilder<UserBloc, UserState>(
@@ -34,15 +35,18 @@ class HomeTabHeaderWidget extends StatelessWidget { @@ -34,15 +35,18 @@ class HomeTabHeaderWidget extends StatelessWidget {
34 return Container( 35 return Container(
35 height: 45, 36 height: 45,
36 width: double.infinity, 37 width: double.infinity,
37 - color:  
38 - CourseModuleModel(courseModuleCode ?? 'Phase-1').color, 38 + color: CourseModuleModel(courseModuleCode ?? 'Phase-1').color,
39 padding: EdgeInsets.symmetric(horizontal: 9.5.w), 39 padding: EdgeInsets.symmetric(horizontal: 9.5.w),
40 child: Row( 40 child: Row(
41 children: [ 41 children: [
42 ScreenUtil().bottomBarHeight.horizontalSpace, 42 ScreenUtil().bottomBarHeight.horizontalSpace,
43 GestureDetector( 43 GestureDetector(
44 onTap: () { 44 onTap: () {
45 - Navigator.pop(context); 45 + if (onBack == null) {
  46 + Navigator.pop(context);
  47 + } else {
  48 + onBack!();
  49 + }
46 }, 50 },
47 child: Container( 51 child: Container(
48 alignment: Alignment.center, 52 alignment: Alignment.center,
@@ -65,21 +69,25 @@ class HomeTabHeaderWidget extends StatelessWidget { @@ -65,21 +69,25 @@ class HomeTabHeaderWidget extends StatelessWidget {
65 onTap: () { 69 onTap: () {
66 if (actionTap != null) { 70 if (actionTap != null) {
67 actionTap!(HeaderActionType.phase); 71 actionTap!(HeaderActionType.phase);
68 - }; 72 + }
69 }, 73 },
70 - child: Image(image: AssetImage('home'.assetPng),  
71 - width: 36.0.w, height: 36.0.h, fit: BoxFit.contain)  
72 - ), 74 + child: Image(
  75 + image: AssetImage('home'.assetPng),
  76 + width: 36.0.w,
  77 + height: 36.0.h,
  78 + fit: BoxFit.contain)),
73 8.horizontalSpace, 79 8.horizontalSpace,
74 GestureDetector( 80 GestureDetector(
75 - onTap: () {  
76 - if (actionTap != null) {  
77 - actionTap!(HeaderActionType.listen);  
78 - };  
79 - },  
80 - child: Image(image: AssetImage('listen'.assetPng),  
81 - width: 36.0.w, height: 36.0.h, fit: BoxFit.contain)  
82 - ), 81 + onTap: () {
  82 + if (actionTap != null) {
  83 + actionTap!(HeaderActionType.listen);
  84 + }
  85 + },
  86 + child: Image(
  87 + image: AssetImage('listen'.assetPng),
  88 + width: 36.0.w,
  89 + height: 36.0.h,
  90 + fit: BoxFit.contain)),
83 8.horizontalSpace, 91 8.horizontalSpace,
84 Offstage( 92 Offstage(
85 offstage: AppConfigHelper.shouldHidePay(), 93 offstage: AppConfigHelper.shouldHidePay(),
@@ -87,11 +95,13 @@ class HomeTabHeaderWidget extends StatelessWidget { @@ -87,11 +95,13 @@ class HomeTabHeaderWidget extends StatelessWidget {
87 onTap: () { 95 onTap: () {
88 if (actionTap != null) { 96 if (actionTap != null) {
89 actionTap!(HeaderActionType.shop); 97 actionTap!(HeaderActionType.shop);
90 - }; 98 + }
91 }, 99 },
92 - child: Image(image: AssetImage('shop'.assetPng),  
93 - width: 36.0.w, height: 36.0.h, fit: BoxFit.contain)  
94 - ), 100 + child: Image(
  101 + image: AssetImage('shop'.assetPng),
  102 + width: 36.0.w,
  103 + height: 36.0.h,
  104 + fit: BoxFit.contain)),
95 ), 105 ),
96 ScreenUtil().bottomBarHeight.horizontalSpace, 106 ScreenUtil().bottomBarHeight.horizontalSpace,
97 ], 107 ],
lib/pages/user/bloc/user_bloc.dart
@@ -16,6 +16,7 @@ class UserBloc extends Bloc&lt;UserEvent, UserState&gt; { @@ -16,6 +16,7 @@ class UserBloc extends Bloc&lt;UserEvent, UserState&gt; {
16 16
17 UserEntity? get userEntityForPay => _userEntityForPay; 17 UserEntity? get userEntityForPay => _userEntityForPay;
18 18
  19 + bool exchangeResult = false;
19 UserBloc() : super(UserInitial()) { 20 UserBloc() : super(UserInitial()) {
20 on<UserLogout>(_logout); 21 on<UserLogout>(_logout);
21 on<UserDelete>(_deleteAccount); 22 on<UserDelete>(_deleteAccount);
@@ -37,7 +38,8 @@ class UserBloc extends Bloc&lt;UserEvent, UserState&gt; { @@ -37,7 +38,8 @@ class UserBloc extends Bloc&lt;UserEvent, UserState&gt; {
37 } 38 }
38 39
39 void _updateUser(UserUpdate event, Emitter<UserState> emitter) async { 40 void _updateUser(UserUpdate event, Emitter<UserState> emitter) async {
40 - Log.d('_updateUser, event: ${event.type}, emitter.isDone: ${emitter.isDone}, text=${event.content}'); 41 + Log.d(
  42 + '_updateUser, event: ${event.type}, emitter.isDone: ${emitter.isDone}, text=${event.content}');
41 UserEntity user = UserUtil.getUser()!; 43 UserEntity user = UserUtil.getUser()!;
42 try { 44 try {
43 switch (event.type) { 45 switch (event.type) {
@@ -84,7 +86,8 @@ class UserBloc extends Bloc&lt;UserEvent, UserState&gt; { @@ -84,7 +86,8 @@ class UserBloc extends Bloc&lt;UserEvent, UserState&gt; {
84 } 86 }
85 87
86 //支付状态变化 88 //支付状态变化
87 - void _patStateChanged(PayStateChangeEvent event, Emitter<UserState> emitter) async { 89 + void _patStateChanged(
  90 + PayStateChangeEvent event, Emitter<UserState> emitter) async {
88 // 由于userInfo接口不会返回token,所以这里需要再次保存一下token 91 // 由于userInfo接口不会返回token,所以这里需要再次保存一下token
89 final token = UserUtil.getUser()?.token; 92 final token = UserUtil.getUser()?.token;
90 _userEntityForPay = await UserDao.getUserInfo(); 93 _userEntityForPay = await UserDao.getUserInfo();
lib/pages/user/user_page.dart
@@ -29,7 +29,8 @@ class _UserView extends StatelessWidget { @@ -29,7 +29,8 @@ class _UserView extends StatelessWidget {
29 final String bannerUrl = ''; 29 final String bannerUrl = '';
30 30
31 /// 方法 31 /// 方法
32 - final MethodChannel methodChannel = const MethodChannel('wow_english/game_method_channel'); 32 + final MethodChannel methodChannel =
  33 + const MethodChannel('wow_english/game_method_channel');
33 34
34 @override 35 @override
35 Widget build(BuildContext context) { 36 Widget build(BuildContext context) {
@@ -37,34 +38,41 @@ class _UserView extends StatelessWidget { @@ -37,34 +38,41 @@ class _UserView extends StatelessWidget {
37 } 38 }
38 39
39 Widget _pageWidget() => BlocBuilder<UserBloc, UserState>( 40 Widget _pageWidget() => BlocBuilder<UserBloc, UserState>(
40 - builder: (context, state) {  
41 - UserEntity user = UserUtil.getUser()!;  
42 - final userBloc = BlocProvider.of<UserBloc>(context); 41 + builder: (context, state) {
  42 + UserEntity user = UserUtil.getUser()!;
  43 + final userBloc = BlocProvider.of<UserBloc>(context);
43 44
44 - // 常规按钮的字体样式  
45 - final textStyle21sp = TextStyle(  
46 - //fontWeight: FontWeight.w600,  
47 - color: const Color(0xFF333333),  
48 - fontSize: 21.sp,  
49 - ); 45 + // 常规按钮的字体样式
  46 + final textStyle21sp = TextStyle(
  47 + //fontWeight: FontWeight.w600,
  48 + color: const Color(0xFF333333),
  49 + fontSize: 21.sp,
  50 + );
50 51
51 - // 常规按钮的样式  
52 - var normalButtonStyle = ButtonStyle(  
53 - side: MaterialStateProperty.all(BorderSide(color: const Color(0xFF140C10), width: 1.5.w)),  
54 - shape: MaterialStateProperty.all(RoundedRectangleBorder(borderRadius: BorderRadius.circular(15.r))),  
55 - minimumSize: MaterialStateProperty.all(Size(double.infinity, 58.h)),  
56 - backgroundColor: MaterialStateProperty.all(Colors.white),  
57 - ); 52 + // 常规按钮的样式
  53 + var normalButtonStyle = ButtonStyle(
  54 + side: MaterialStateProperty.all(
  55 + BorderSide(color: const Color(0xFF140C10), width: 1.5.w)),
  56 + shape: MaterialStateProperty.all(RoundedRectangleBorder(
  57 + borderRadius: BorderRadius.circular(15.r))),
  58 + minimumSize: MaterialStateProperty.all(Size(double.infinity, 58.h)),
  59 + backgroundColor: MaterialStateProperty.all(Colors.white),
  60 + );
58 61
59 - return Scaffold(  
60 - appBar: const WEAppBar(),  
61 - body: SingleChildScrollView(  
62 - padding: EdgeInsets.only(left: 17.w, right: 17.w, top: 10.h, bottom: 22.h),  
63 - child: Column(  
64 - mainAxisAlignment: MainAxisAlignment.center,  
65 - children: <Widget>[  
66 - // todo banner,暂时没有接口获取banner URL  
67 - /*Offstage( 62 + return Scaffold(
  63 + appBar: WEAppBar(
  64 + onBack: () {
  65 + popPage(data: {'exchange': userBloc.exchangeResult});
  66 + },
  67 + ),
  68 + body: SingleChildScrollView(
  69 + padding: EdgeInsets.only(
  70 + left: 17.w, right: 17.w, top: 10.h, bottom: 22.h),
  71 + child: Column(
  72 + mainAxisAlignment: MainAxisAlignment.center,
  73 + children: <Widget>[
  74 + // todo banner,暂时没有接口获取banner URL
  75 + /*Offstage(
68 child: Column( 76 child: Column(
69 children: [ 77 children: [
70 Container(child: Image.asset(bannerUrl), constraints: BoxConstraints(maxHeight: 196.h)), 78 Container(child: Image.asset(bannerUrl), constraints: BoxConstraints(maxHeight: 196.h)),
@@ -72,23 +80,25 @@ class _UserView extends StatelessWidget { @@ -72,23 +80,25 @@ class _UserView extends StatelessWidget {
72 ], 80 ],
73 ), 81 ),
74 ),*/ 82 ),*/
75 - Row(  
76 - mainAxisAlignment: MainAxisAlignment.spaceBetween,  
77 - children: [  
78 - CircleAvatar(  
79 - radius: 40.r,  
80 - backgroundColor: const Color(0xFF140C10),  
81 - child: CircleAvatar(  
82 - radius: 38.5.r,  
83 - backgroundImage: ImageUtil.getImageProviderOnDefault(user.avatarUrl),  
84 - ),  
85 - /*child: ClipOval( 83 + Row(
  84 + mainAxisAlignment: MainAxisAlignment.spaceBetween,
  85 + children: [
  86 + CircleAvatar(
  87 + radius: 40.r,
  88 + backgroundColor: const Color(0xFF140C10),
  89 + child: CircleAvatar(
  90 + radius: 38.5.r,
  91 + backgroundImage:
  92 + ImageUtil.getImageProviderOnDefault(
  93 + user.avatarUrl),
  94 + ),
  95 + /*child: ClipOval(
86 child: OwImageWidget(name: user.avatarUrl ?? AssetsConst.wowLogo, fit: BoxFit.contain,), 96 child: OwImageWidget(name: user.avatarUrl ?? AssetsConst.wowLogo, fit: BoxFit.contain,),
87 )*/ 97 )*/
88 - ),  
89 - 32.horizontalSpace,  
90 - Expanded(  
91 - child: Column( 98 + ),
  99 + 32.horizontalSpace,
  100 + Expanded(
  101 + child: Column(
92 children: [ 102 children: [
93 Row( 103 Row(
94 children: [ 104 children: [
@@ -108,7 +118,8 @@ class _UserView extends StatelessWidget { @@ -108,7 +118,8 @@ class _UserView extends StatelessWidget {
108 ), 118 ),
109 14.horizontalSpace, 119 14.horizontalSpace,
110 Offstage( 120 Offstage(
111 - offstage: user.effectiveDate == null || AppConfigHelper.shouldHidePay(), 121 + offstage: user.effectiveDate == null ||
  122 + AppConfigHelper.shouldHidePay(),
112 child: Image.asset( 123 child: Image.asset(
113 AssetsConst.icVip, 124 AssetsConst.icVip,
114 height: 18.h, 125 height: 18.h,
@@ -117,7 +128,8 @@ class _UserView extends StatelessWidget { @@ -117,7 +128,8 @@ class _UserView extends StatelessWidget {
117 ], 128 ],
118 ), 129 ),
119 Offstage( 130 Offstage(
120 - offstage: user.effectiveDate == null || AppConfigHelper.shouldHidePay(), 131 + offstage: user.effectiveDate == null ||
  132 + AppConfigHelper.shouldHidePay(),
121 child: Row( 133 child: Row(
122 children: [ 134 children: [
123 Text( 135 Text(
@@ -132,132 +144,158 @@ class _UserView extends StatelessWidget { @@ -132,132 +144,158 @@ class _UserView extends StatelessWidget {
132 ) 144 )
133 ], 145 ],
134 )), 146 )),
135 - TextButton( 147 + TextButton(
  148 + child: Text(
  149 + "修改个人信息>",
  150 + style: textStyle21sp,
  151 + ),
  152 + onPressed: () {
  153 + pushNamed(AppRouteName.userInformation);
  154 + },
  155 + )
  156 + ],
  157 + ),
  158 + 30.verticalSpace,
  159 + // 打开游戏界面 供审核用
  160 + ((UserUtil.getUser()?.phoneNum == '17730280759' ||
  161 + UserUtil.getUser()?.phoneNum == '17718485544')
  162 + ? OutlinedButton(
  163 + onPressed: () {
  164 + methodChannel
  165 + .invokeMethod('openGamePage', {"gameId": 1});
  166 + },
  167 + style: normalButtonStyle,
  168 + child: Text(
  169 + "进入游戏",
  170 + style: textStyle21sp,
  171 + ),
  172 + )
  173 + : 1.verticalSpace),
  174 + ((UserUtil.getUser()?.phoneNum == '17730280759' ||
  175 + UserUtil.getUser()?.phoneNum == '17718485544')
  176 + ? 12.verticalSpace
  177 + : 1.verticalSpace),
  178 + OutlinedButton(
  179 + onPressed: () => pushNamed(AppRouteName.fogPwd),
  180 + style: normalButtonStyle,
136 child: Text( 181 child: Text(
137 - "修改个人信息>", 182 + "修改密码",
138 style: textStyle21sp, 183 style: textStyle21sp,
139 ), 184 ),
140 - onPressed: () {  
141 - pushNamed(AppRouteName.userInformation);  
142 - },  
143 - ) 185 + ),
  186 + 12.verticalSpace,
  187 + Offstage(
  188 + offstage: AppConfigHelper.shouldHidePay(),
  189 + child: OutlinedButton(
  190 + onPressed: () =>
  191 + pushNamed(AppRouteName.exLesson).then((value) => {
  192 + if (value != null)
  193 + {
  194 + userBloc.exchangeResult =
  195 + value['exchange']
  196 + }
  197 + }),
  198 + style: normalButtonStyle,
  199 + child: Text(
  200 + "兑换课程",
  201 + style: textStyle21sp,
  202 + )),
  203 + ),
  204 + Offstage(
  205 + offstage: AppConfigHelper.shouldHidePay(),
  206 + child: 12.verticalSpace,
  207 + ),
  208 + OutlinedButton(
  209 + onPressed: () {
  210 + pushNamed(AppRouteName.webView, arguments: {
  211 + 'urlStr': AppConsts.userPrivacyPolicyUrl,
  212 + 'webViewTitle': '隐私协议'
  213 + });
  214 + },
  215 + style: normalButtonStyle,
  216 + child: Text(
  217 + "隐私协议",
  218 + style: textStyle21sp,
  219 + )),
  220 + 12.verticalSpace,
  221 + OutlinedButton(
  222 + onPressed: () {
  223 + String phone = 'tel:+8618856084180';
  224 + _launchPhone(phone);
  225 + },
  226 + style: normalButtonStyle,
  227 + child: Text(
  228 + "联系客服",
  229 + style: textStyle21sp,
  230 + )),
  231 + 12.verticalSpace,
  232 + OutlinedButton(
  233 + onPressed: () {
  234 + pushNamed(AppRouteName.setting);
  235 + },
  236 + style: normalButtonStyle,
  237 + child: Text(
  238 + "设置",
  239 + style: textStyle21sp,
  240 + )),
  241 + 30.verticalSpace,
  242 + OutlinedButton(
  243 + onPressed: () {
  244 + showTwoActionDialog(
  245 + barrierDismissible: false,
  246 + '提示',
  247 + '取消',
  248 + '确认',
  249 + '您确认要退出Wow English吗?', leftTap: () {
  250 + popPage();
  251 + }, rightTap: () {
  252 + popPage();
  253 + userBloc.add(UserLogout());
  254 + });
  255 + },
  256 + style: ButtonStyle(
  257 + side: MaterialStateProperty.all(const BorderSide(
  258 + color: Color(0xFF140C10), width: 1.5)),
  259 + shape: MaterialStateProperty.all(
  260 + RoundedRectangleBorder(
  261 + borderRadius: BorderRadius.circular(15.r))),
  262 + minimumSize:
  263 + MaterialStateProperty.all(Size(295.w, 40.h)),
  264 + backgroundColor: MaterialStateProperty.all(
  265 + const Color(0xFFFBB621)),
  266 + ),
  267 + child: Text(
  268 + "退出登录",
  269 + style: TextStyle(
  270 + //fontWeight: FontWeight.w600,
  271 + color: Colors.white,
  272 + fontSize: 17.sp,
  273 + ),
  274 + )),
  275 + // 30.verticalSpace,
  276 + // TextButton(
  277 + // onPressed: () {
  278 + // //userBloc.add(UserDelete())
  279 + // showTwoActionDialog('注销账号', '取消', '注销', '请谨慎操作!\n注销后不可恢复哦!', () {
  280 + // popPage();
  281 + // }, () {
  282 + // userBloc.add(UserDelete());
  283 + // popPage();
  284 + // });
  285 + // },
  286 + // child: Text(
  287 + // "注销账号",
  288 + // style: TextStyle(
  289 + // //fontWeight: FontWeight.w600,
  290 + // color: Colors.red,
  291 + // fontSize: 15.sp,
  292 + // ),
  293 + // )),
144 ], 294 ],
145 ), 295 ),
146 - 30.verticalSpace,  
147 - // 打开游戏界面 供审核用  
148 - ((UserUtil.getUser()?.phoneNum == '17730280759' || UserUtil.getUser()?.phoneNum == '17718485544') ? OutlinedButton(  
149 - onPressed: () {  
150 - methodChannel.invokeMethod('openGamePage', { "gameId": 1 });  
151 - },  
152 - style: normalButtonStyle,  
153 - child: Text(  
154 - "进入游戏",  
155 - style: textStyle21sp,  
156 - ),  
157 - ) : 1.verticalSpace),  
158 - ((UserUtil.getUser()?.phoneNum == '17730280759' || UserUtil.getUser()?.phoneNum == '17718485544') ? 12.verticalSpace : 1.verticalSpace),  
159 - OutlinedButton(  
160 - onPressed: () => pushNamed(AppRouteName.fogPwd),  
161 - style: normalButtonStyle,  
162 - child: Text(  
163 - "修改密码",  
164 - style: textStyle21sp,  
165 - ),  
166 - ),  
167 - 12.verticalSpace,  
168 - Offstage(  
169 - offstage: AppConfigHelper.shouldHidePay(),  
170 - child: OutlinedButton(  
171 - onPressed: () => pushNamed(AppRouteName.exLesson),  
172 - style: normalButtonStyle,  
173 - child: Text(  
174 - "兑换课程",  
175 - style: textStyle21sp,  
176 - )),  
177 - ),  
178 - Offstage(  
179 - offstage: AppConfigHelper.shouldHidePay(),  
180 - child: 12.verticalSpace,  
181 - ),  
182 - OutlinedButton(  
183 - onPressed: () {  
184 - pushNamed(AppRouteName.webView,arguments: {'urlStr': AppConsts.userPrivacyPolicyUrl, 'webViewTitle': '隐私协议'});  
185 - },  
186 - style: normalButtonStyle,  
187 - child: Text(  
188 - "隐私协议",  
189 - style: textStyle21sp,  
190 - )),  
191 - 12.verticalSpace,  
192 - OutlinedButton(  
193 - onPressed: () {  
194 - String phone ='tel:+8618827093087';  
195 - _launchPhone(phone);  
196 - },  
197 - style: normalButtonStyle,  
198 - child: Text(  
199 - "联系客服",  
200 - style: textStyle21sp,  
201 - )),  
202 - 12.verticalSpace,  
203 - OutlinedButton(  
204 - onPressed: () {  
205 - pushNamed(AppRouteName.setting);  
206 - },  
207 - style: normalButtonStyle,  
208 - child: Text(  
209 - "设置",  
210 - style: textStyle21sp,  
211 - )),  
212 - 30.verticalSpace,  
213 - OutlinedButton(  
214 - onPressed: () {  
215 - showTwoActionDialog(barrierDismissible:false,'提示', '取消', '确认', '您确认要退出Wow English吗?',leftTap: (){  
216 - popPage();  
217 - },rightTap: (){  
218 - popPage();  
219 - userBloc.add(UserLogout());  
220 - });  
221 - },  
222 - style: ButtonStyle(  
223 - side: MaterialStateProperty.all(const BorderSide(color: Color(0xFF140C10), width: 1.5)),  
224 - shape: MaterialStateProperty.all(  
225 - RoundedRectangleBorder(borderRadius: BorderRadius.circular(15.r))),  
226 - minimumSize: MaterialStateProperty.all(Size(295.w, 40.h)),  
227 - backgroundColor: MaterialStateProperty.all(const Color(0xFFFBB621)),  
228 - ),  
229 - child: Text(  
230 - "退出登录",  
231 - style: TextStyle(  
232 - //fontWeight: FontWeight.w600,  
233 - color: Colors.white,  
234 - fontSize: 17.sp,  
235 - ),  
236 - )),  
237 - // 30.verticalSpace,  
238 - // TextButton(  
239 - // onPressed: () {  
240 - // //userBloc.add(UserDelete())  
241 - // showTwoActionDialog('注销账号', '取消', '注销', '请谨慎操作!\n注销后不可恢复哦!', () {  
242 - // popPage();  
243 - // }, () {  
244 - // userBloc.add(UserDelete());  
245 - // popPage();  
246 - // });  
247 - // },  
248 - // child: Text(  
249 - // "注销账号",  
250 - // style: TextStyle(  
251 - // //fontWeight: FontWeight.w600,  
252 - // color: Colors.red,  
253 - // fontSize: 15.sp,  
254 - // ),  
255 - // )),  
256 - ],  
257 - ),  
258 - ));  
259 - },  
260 - ); 296 + ));
  297 + },
  298 + );
261 299
262 void _launchPhone(String phone) async { 300 void _launchPhone(String phone) async {
263 if (await canLaunchUrl(Uri.parse(phone))) { 301 if (await canLaunchUrl(Uri.parse(phone))) {