Commit 0bd6ea43a0094c85f9255ab96f9fdb7302a0db10

Authored by xiaoyu
2 parents 6b46f015 1748f1e6

Merge remote-tracking branch 'origin/feat-wqf-payment' into xiaoyu_cocossteve

android/app/build.gradle
@@ -94,5 +94,5 @@ dependencies { @@ -94,5 +94,5 @@ dependencies {
94 // kotlin扩展(可选) 94 // kotlin扩展(可选)
95 implementation 'com.geyifeng.immersionbar:immersionbar-ktx:3.2.2' 95 implementation 'com.geyifeng.immersionbar:immersionbar-ktx:3.2.2'
96 // coco2d游戏 96 // coco2d游戏
97 - implementation 'io.keyss.android.library:steve_game:1.0.0' 97 + implementation 'io.keyss.android.library:steve_game:1.0.1'
98 } 98 }
android/build.gradle
1 buildscript { 1 buildscript {
2 ext.kotlin_version = '1.8.21' 2 ext.kotlin_version = '1.8.21'
3 repositories { 3 repositories {
  4 + maven { url 'https://maven.aliyun.com/repository/google' }
  5 + maven { url "https://maven.aliyun.com/repository/public" }
  6 + maven { url 'https://jitpack.io' }
  7 +// maven { url 'https://maven.aliyun.com/nexus/content/groups/public' }
4 google() 8 google()
5 mavenCentral() 9 mavenCentral()
6 } 10 }
@@ -14,6 +18,10 @@ buildscript { @@ -14,6 +18,10 @@ buildscript {
14 18
15 allprojects { 19 allprojects {
16 repositories { 20 repositories {
  21 + maven { url 'https://maven.aliyun.com/repository/google' }
  22 + maven { url "https://maven.aliyun.com/repository/public" }
  23 + maven { url 'https://jitpack.io' }
  24 +// maven { url 'https://maven.aliyun.com/nexus/content/groups/public' }
17 google() 25 google()
18 mavenCentral() 26 mavenCentral()
19 maven { url 'https://repo.singsound.com/repository/singsound_ginger_android_sdk/' } 27 maven { url 'https://repo.singsound.com/repository/singsound_ginger_android_sdk/' }
assets/sounds/correct_voice.mp3 0 → 100644
No preview for this file type
assets/sounds/incorrect_voice.mp3 0 → 100644
No preview for this file type
lib/common/core/app_config_helper.dart
@@ -22,8 +22,8 @@ class AppConfigHelper { @@ -22,8 +22,8 @@ class AppConfigHelper {
22 static bool checkedUpdate = false; 22 static bool checkedUpdate = false;
23 23
24 // 获取用户信息 24 // 获取用户信息
25 - static Future<AppConfigEntity?> getAppConfig() async {  
26 - if (configEntityEntity != null) { 25 + static Future<AppConfigEntity?> getAppConfig({ bool forceSync = false }) async {
  26 + if (forceSync == false && configEntityEntity != null) {
27 return configEntityEntity; 27 return configEntityEntity;
28 } 28 }
29 configEntityEntity = await SystemDao.getAppConfig(); 29 configEntityEntity = await SystemDao.getAppConfig();
lib/common/core/user_util.dart
@@ -63,8 +63,8 @@ class UserUtil { @@ -63,8 +63,8 @@ class UserUtil {
63 pushNamedAndRemoveUntil(AppRouteName.login, (route) => false, arguments: {'showPasswordPage': showPasswordLoginPage}); 63 pushNamedAndRemoveUntil(AppRouteName.login, (route) => false, arguments: {'showPasswordPage': showPasswordLoginPage});
64 } 64 }
65 65
66 - // 是否有游戏权限  
67 - static bool hasGamePermission() { 66 + // 是否有权限
  67 + static bool hasPermission() {
68 return _userEntity?.valid ?? false; 68 return _userEntity?.valid ?? false;
69 } 69 }
70 70
lib/common/extension/string_extension.dart
1 /// 资源类扩展方法 1 /// 资源类扩展方法
2 extension AssetExtension on String { 2 extension AssetExtension on String {
3 static const String _assetImagePrefix = "assets/images/"; 3 static const String _assetImagePrefix = "assets/images/";
  4 + static const String _assetSoundPrefix = 'sounds/';
4 5
5 /// 图片url 6 /// 图片url
6 String get assetImg => _assetImagePrefix + this; 7 String get assetImg => _assetImagePrefix + this;
@@ -10,6 +11,10 @@ extension AssetExtension on String { @@ -10,6 +11,10 @@ extension AssetExtension on String {
10 String get assetWebp => '$assetImg.webp'; 11 String get assetWebp => '$assetImg.webp';
11 12
12 String get assetGif => '$assetImg.gif'; 13 String get assetGif => '$assetImg.gif';
  14 +
  15 + String get assetSound => _assetSoundPrefix + this;
  16 +
  17 + String get assetMp3 => '$assetSound.mp3';
13 } 18 }
14 19
15 extension StringExtension on String { 20 extension StringExtension on String {
lib/common/request/dao/user_dao.dart
@@ -2,6 +2,7 @@ import &#39;package:wow_english/common/core/user_util.dart&#39;; @@ -2,6 +2,7 @@ import &#39;package:wow_english/common/core/user_util.dart&#39;;
2 import 'package:wow_english/models/user_entity.dart'; 2 import 'package:wow_english/models/user_entity.dart';
3 import 'package:wow_english/utils/log_util.dart'; 3 import 'package:wow_english/utils/log_util.dart';
4 4
  5 +import '../../core/app_config_helper.dart';
5 import '../request_client.dart'; 6 import '../request_client.dart';
6 7
7 enum SmsType { login, change_passWord, stdDestroy } 8 enum SmsType { login, change_passWord, stdDestroy }
@@ -18,6 +19,8 @@ class UserDao { @@ -18,6 +19,8 @@ class UserDao {
18 UserUtil.saveUser(data); 19 UserUtil.saveUser(data);
19 // 由于userInfo接口不会返回token,所以这里需要再次保存一下token 20 // 由于userInfo接口不会返回token,所以这里需要再次保存一下token
20 final token = data.token; 21 final token = data.token;
  22 + //登录成功后刷新下配置信息
  23 + AppConfigHelper.getAppConfig(forceSync: true);
21 //登录成功后zip一下getUserInfo,因为进入首页需要的信息在userinfo里,保证进入首页数据是最新的 24 //登录成功后zip一下getUserInfo,因为进入首页需要的信息在userinfo里,保证进入首页数据是最新的
22 data = await getUserInfo(); 25 data = await getUserInfo();
23 data?.token = token; 26 data?.token = token;
lib/pages/home/view.dart
1 1
2 -import 'package:flutter/foundation.dart';  
3 import 'package:flutter/material.dart'; 2 import 'package:flutter/material.dart';
4 -import 'package:flutter/services.dart';  
5 import 'package:flutter_app_update/azhon_app_update.dart'; 3 import 'package:flutter_app_update/azhon_app_update.dart';
6 import 'package:flutter_app_update/update_model.dart'; 4 import 'package:flutter_app_update/update_model.dart';
7 import 'package:flutter_bloc/flutter_bloc.dart'; 5 import 'package:flutter_bloc/flutter_bloc.dart';
@@ -69,11 +67,9 @@ class _HomePageView extends StatelessWidget { @@ -69,11 +67,9 @@ class _HomePageView extends StatelessWidget {
69 Expanded( 67 Expanded(
70 child: GestureDetector( 68 child: GestureDetector(
71 onTap: () { 69 onTap: () {
72 - if (UserUtil.isLogined()) { 70 + _checkPermission(() {
73 pushNamed(AppRouteName.courseUnit); 71 pushNamed(AppRouteName.courseUnit);
74 - } else {  
75 - pushNamed(AppRouteName.login);  
76 - } 72 + });
77 }, 73 },
78 child: Column( 74 child: Column(
79 mainAxisAlignment: MainAxisAlignment.center, 75 mainAxisAlignment: MainAxisAlignment.center,
@@ -105,30 +101,9 @@ class _HomePageView extends StatelessWidget { @@ -105,30 +101,9 @@ class _HomePageView extends StatelessWidget {
105 'WQF ModuleSelectPage BlocBuilder state: $userState'); 101 'WQF ModuleSelectPage BlocBuilder state: $userState');
106 return GestureDetector( 102 return GestureDetector(
107 onTap: () { 103 onTap: () {
108 - //如果没登录先登录  
109 - if (UserUtil.isLogined()) {  
110 - if (AppConfigHelper  
111 - .shouldHidePay()) {  
112 - pushNamed(AppRouteName.games);  
113 - } else {  
114 - if (UserUtil  
115 - .hasGamePermission()) {  
116 - pushNamed(AppRouteName.games);  
117 - } else {  
118 - showTwoActionDialog(  
119 - '提示', '忽略', '去续费',  
120 - '您的课程已到期,请快快续费继续学习吧!',  
121 - leftTap: () {  
122 - popPage();  
123 - }, rightTap: () {  
124 - popPage();  
125 - pushNamed(AppRouteName.shop);  
126 - });  
127 - }  
128 - }  
129 - } else {  
130 - pushNamed(AppRouteName.login);  
131 - } 104 + _checkPermission(() {
  105 + pushNamed(AppRouteName.games);
  106 + });
132 }, 107 },
133 child: Column( 108 child: Column(
134 mainAxisAlignment: MainAxisAlignment 109 mainAxisAlignment: MainAxisAlignment
@@ -168,6 +143,30 @@ class _HomePageView extends StatelessWidget { @@ -168,6 +143,30 @@ class _HomePageView extends StatelessWidget {
168 }); 143 });
169 144
170 145
  146 + _checkPermission(VoidCallback onAllowed) {
  147 + if (UserUtil.isLogined()) {
  148 + if (AppConfigHelper.shouldHidePay()) {
  149 + onAllowed();
  150 + } else {
  151 + if (UserUtil.hasPermission()) {
  152 + onAllowed();
  153 + } else {
  154 + showTwoActionDialog('提示', '忽略', '去续费',
  155 + '您的课程已到期,请快快续费继续学习吧!', leftTap: () {
  156 + popPage();
  157 + }, rightTap: () {
  158 + popPage();
  159 + pushNamed(AppRouteName.shop);
  160 + });
  161 + }
  162 + }
  163 + } else {
  164 + //如果没登录先登录
  165 + pushNamed(AppRouteName.login);
  166 + }
  167 + }
  168 +
  169 +
171 ///Flutter侧处理升级对话框 170 ///Flutter侧处理升级对话框
172 ///[forcedUpgrade] 是否强制升级 171 ///[forcedUpgrade] 是否强制升级
173 _showUpdateDialog(BuildContext context, bool forcedUpgrade, 172 _showUpdateDialog(BuildContext context, bool forcedUpgrade,
lib/pages/home/widgets/BaseHomeHeaderWidget.dart
@@ -79,18 +79,24 @@ class BaseHomeHeaderWidget extends StatelessWidget { @@ -79,18 +79,24 @@ class BaseHomeHeaderWidget extends StatelessWidget {
79 style: TextStyle(color: Colors.white, fontSize: 30.0), 79 style: TextStyle(color: Colors.white, fontSize: 30.0),
80 )), 80 )),
81 Offstage( 81 Offstage(
82 - offstage: AppConfigHelper.shouldHidePay() || !UserUtil.isLogined(),  
83 - child: Row(children: <Widget>[  
84 - Image(  
85 - width: 20.0.w,  
86 - height: 20.0.h,  
87 - image: AssetImage('ic_countdown'.assetPng)),  
88 - // 替换为你的图片资源路径  
89 - const SizedBox(width: 10.0),  
90 - // 图片和文本之间的间隔  
91 - Text('还剩${UserUtil.getRemainingValidity()}天'),  
92 - ]),  
93 - ), 82 + offstage: AppConfigHelper.shouldHidePay() ||
  83 + !UserUtil.isLogined(),
  84 + child: GestureDetector(
  85 + onTap: () => {
  86 + pushNamed(AppRouteName.shop),
  87 + },
  88 + child: Row(
  89 + children: <Widget>[
  90 + Image(
  91 + width: 20.0.w,
  92 + height: 20.0.h,
  93 + image: AssetImage('ic_countdown'.assetPng)),
  94 + // 替换为你的图片资源路径
  95 + const SizedBox(width: 6.0),
  96 + // 图片和文本之间的间隔
  97 + Text('还剩${UserUtil.getRemainingValidity()}天'),
  98 + ]),
  99 + )),
94 ScreenUtil().bottomBarHeight.horizontalSpace, 100 ScreenUtil().bottomBarHeight.horizontalSpace,
95 ], 101 ],
96 )); 102 ));
lib/pages/practice/bloc/topic_picture_bloc.dart
@@ -5,6 +5,7 @@ import &#39;package:flutter/services.dart&#39;; @@ -5,6 +5,7 @@ import &#39;package:flutter/services.dart&#39;;
5 import 'package:flutter_bloc/flutter_bloc.dart'; 5 import 'package:flutter_bloc/flutter_bloc.dart';
6 import 'package:flutter_easyloading/flutter_easyloading.dart'; 6 import 'package:flutter_easyloading/flutter_easyloading.dart';
7 import 'package:permission_handler/permission_handler.dart'; 7 import 'package:permission_handler/permission_handler.dart';
  8 +import 'package:wow_english/common/extension/string_extension.dart';
8 import 'package:wow_english/common/request/dao/listen_dao.dart'; 9 import 'package:wow_english/common/request/dao/listen_dao.dart';
9 import 'package:wow_english/common/request/exception.dart'; 10 import 'package:wow_english/common/request/exception.dart';
10 import 'package:wow_english/models/course_process_entity.dart'; 11 import 'package:wow_english/models/course_process_entity.dart';
@@ -45,6 +46,16 @@ class TopicPictureBloc extends Bloc&lt;TopicPictureEvent, TopicPictureState&gt; { @@ -45,6 +46,16 @@ class TopicPictureBloc extends Bloc&lt;TopicPictureEvent, TopicPictureState&gt; {
45 ///正在播放音频 46 ///正在播放音频
46 VoicePlayState _voicePlayState = VoicePlayState.unKnow; 47 VoicePlayState _voicePlayState = VoicePlayState.unKnow;
47 48
  49 + // 是否是回答(选择)结果音效
  50 + bool _isResultSoundPlaying = false;
  51 +
  52 + bool get isResultSoundPlaying => _isResultSoundPlaying;
  53 +
  54 + // 答对播放音效时禁止任何点击(选择)操作
  55 + bool _forbiddenWhenCorrect = false;
  56 +
  57 + bool get forbiddenWhenCorrect => _forbiddenWhenCorrect;
  58 +
48 CourseProcessEntity? get entity => _entity; 59 CourseProcessEntity? get entity => _entity;
49 60
50 int get currentPage => _currentPage + 1; 61 int get currentPage => _currentPage + 1;
@@ -70,29 +81,43 @@ class TopicPictureBloc extends Bloc&lt;TopicPictureEvent, TopicPictureState&gt; { @@ -70,29 +81,43 @@ class TopicPictureBloc extends Bloc&lt;TopicPictureEvent, TopicPictureState&gt; {
70 on<RequestDataEvent>(_requestData); 81 on<RequestDataEvent>(_requestData);
71 on<XSVoiceTestEvent>(_voiceXsTest); 82 on<XSVoiceTestEvent>(_voiceXsTest);
72 on<XSVoiceStopEvent>(_voiceXsStop); 83 on<XSVoiceStopEvent>(_voiceXsStop);
73 - on<VoicePlayEvent>(_voicePlay); 84 + on<VoicePlayEvent>(_questionVoicePlay);
74 on<InitBlocEvent>((event, emit) { 85 on<InitBlocEvent>((event, emit) {
75 //音频播放器 86 //音频播放器
76 audioPlayer = AudioPlayer(); 87 audioPlayer = AudioPlayer();
77 audioPlayer.onPlayerStateChanged.listen((event) async { 88 audioPlayer.onPlayerStateChanged.listen((event) async {
78 - debugPrint('播放状态变化');  
79 - if (event == PlayerState.completed) {  
80 - debugPrint('播放完成');  
81 - _voicePlayState = VoicePlayState.completed;  
82 - }  
83 - if (event == PlayerState.stopped) {  
84 - debugPrint('播放结束');  
85 - _voicePlayState = VoicePlayState.stop;  
86 - } 89 + debugPrint('播放状态变化 _voicePlayState=$_voicePlayState event=$event _isResultSoundPlaying=$_isResultSoundPlaying _forbiddenWhenCorrect=$_forbiddenWhenCorrect');
  90 + if (_isResultSoundPlaying) {
  91 + if (event != PlayerState.playing) {
  92 + _isResultSoundPlaying = false;
  93 + if (_forbiddenWhenCorrect) {
  94 + _forbiddenWhenCorrect = false;
  95 + // 答对后自动翻页
  96 + pageController.nextPage(
  97 + duration: const Duration(milliseconds: 500),
  98 + curve: Curves.ease,
  99 + );
  100 + }
  101 + }
  102 + } else {
  103 + if (event == PlayerState.completed) {
  104 + debugPrint('播放完成');
  105 + _voicePlayState = VoicePlayState.completed;
  106 + }
  107 + if (event == PlayerState.stopped) {
  108 + debugPrint('播放结束');
  109 + _voicePlayState = VoicePlayState.stop;
  110 + }
87 111
88 - if (event == PlayerState.playing) {  
89 - debugPrint('正在播放中');  
90 - _voicePlayState = VoicePlayState.playing;  
91 - }  
92 - if(isClosed) {  
93 - return; 112 + if (event == PlayerState.playing) {
  113 + debugPrint('正在播放中');
  114 + _voicePlayState = VoicePlayState.playing;
  115 + }
  116 + if (isClosed) {
  117 + return;
  118 + }
  119 + add(VoicePlayStateChangeEvent());
94 } 120 }
95 - add(VoicePlayStateChangeEvent());  
96 }); 121 });
97 122
98 methodChannel = const MethodChannel('wow_english/sing_sound_method_channel'); 123 methodChannel = const MethodChannel('wow_english/sing_sound_method_channel');
@@ -129,6 +154,8 @@ class TopicPictureBloc extends Bloc&lt;TopicPictureEvent, TopicPictureState&gt; { @@ -129,6 +154,8 @@ class TopicPictureBloc extends Bloc&lt;TopicPictureEvent, TopicPictureState&gt; {
129 pageController.dispose(); 154 pageController.dispose();
130 audioPlayer.release(); 155 audioPlayer.release();
131 audioPlayer.dispose(); 156 audioPlayer.dispose();
  157 + _isResultSoundPlaying = false;
  158 + _forbiddenWhenCorrect = false;
132 _voiceXsCancel(); 159 _voiceXsCancel();
133 return super.close(); 160 return super.close();
134 } 161 }
@@ -149,10 +176,12 @@ class TopicPictureBloc extends Bloc&lt;TopicPictureEvent, TopicPictureState&gt; { @@ -149,10 +176,12 @@ class TopicPictureBloc extends Bloc&lt;TopicPictureEvent, TopicPictureState&gt; {
149 176
150 ///页面切换 177 ///页面切换
151 void _pageControllerChange(CurrentPageIndexChangeEvent event,Emitter<TopicPictureState> emitter) async { 178 void _pageControllerChange(CurrentPageIndexChangeEvent event,Emitter<TopicPictureState> emitter) async {
152 - _currentPage = event.pageIndex;  
153 - if (voicePlayState == VoicePlayState.playing) {  
154 - await audioPlayer.stop(); 179 + await closePlayerResource();
  180 + debugPrint('翻页 $_currentPage->${event.pageIndex}');
  181 + if (_currentPage == _entity?.topics?.length) {
  182 + return;
155 } 183 }
  184 + _currentPage = event.pageIndex;
156 final topics = _entity?.topics?[_currentPage]; 185 final topics = _entity?.topics?[_currentPage];
157 if (topics?.type != 3 && topics?.type != 4) { 186 if (topics?.type != 3 && topics?.type != 4) {
158 if (topics?.audioUrl != null) { 187 if (topics?.audioUrl != null) {
@@ -169,13 +198,18 @@ class TopicPictureBloc extends Bloc&lt;TopicPictureEvent, TopicPictureState&gt; { @@ -169,13 +198,18 @@ class TopicPictureBloc extends Bloc&lt;TopicPictureEvent, TopicPictureState&gt; {
169 198
170 ///选择 199 ///选择
171 void _selectItemLoad(SelectItemEvent event,Emitter<TopicPictureState> emitter) async { 200 void _selectItemLoad(SelectItemEvent event,Emitter<TopicPictureState> emitter) async {
  201 + if (_forbiddenWhenCorrect) {
  202 + return;
  203 + }
172 _selectItem = event.selectIndex; 204 _selectItem = event.selectIndex;
173 CourseProcessTopics? topics = _entity?.topics?[_currentPage]; 205 CourseProcessTopics? topics = _entity?.topics?[_currentPage];
174 CourseProcessTopicsTopicAnswerList? answerList = topics?.topicAnswerList?[_selectItem]; 206 CourseProcessTopicsTopicAnswerList? answerList = topics?.topicAnswerList?[_selectItem];
175 if (answerList?.correct == 0) { 207 if (answerList?.correct == 0) {
176 - showToast('继续加油哦',duration: const Duration(seconds: 2)); 208 + _playResultSound(false);
  209 + // showToast('继续加油哦',duration: const Duration(seconds: 2));
177 } else { 210 } else {
178 - showToast('恭喜你,答对啦!',duration: const Duration(seconds: 2)); 211 + _playResultSound(true);
  212 + // showToast('恭喜你,答对啦!',duration: const Duration(seconds: 2));
179 } 213 }
180 emitter(SelectItemChangeState()); 214 emitter(SelectItemChangeState());
181 } 215 }
@@ -228,17 +262,37 @@ class TopicPictureBloc extends Bloc&lt;TopicPictureEvent, TopicPictureState&gt; { @@ -228,17 +262,37 @@ class TopicPictureBloc extends Bloc&lt;TopicPictureEvent, TopicPictureState&gt; {
228 emitter(XSVoiceTestState()); 262 emitter(XSVoiceTestState());
229 } 263 }
230 264
  265 + // 暂时没用上
231 void _voicePlayStateChange(VoicePlayStateChangeEvent event,Emitter<TopicPictureState> emitter) async { 266 void _voicePlayStateChange(VoicePlayStateChangeEvent event,Emitter<TopicPictureState> emitter) async {
232 emitter(VoicePlayStateChange()); 267 emitter(VoicePlayStateChange());
233 } 268 }
234 269
235 - void _voicePlay(VoicePlayEvent event,Emitter<TopicPictureState> emitter) async {  
236 - if (voicePlayState == VoicePlayState.playing) {  
237 - await audioPlayer.stop(); 270 + // 题目音频播放
  271 + void _questionVoicePlay(VoicePlayEvent event,Emitter<TopicPictureState> emitter) async {
  272 + if (_forbiddenWhenCorrect) {
238 return; 273 return;
239 } 274 }
  275 + _forbiddenWhenCorrect = false;
  276 + await closePlayerResource();
240 final topics = _entity?.topics?[_currentPage]; 277 final topics = _entity?.topics?[_currentPage];
241 final urlStr = topics?.audioUrl??''; 278 final urlStr = topics?.audioUrl??'';
242 await audioPlayer.play(UrlSource(urlStr)); 279 await audioPlayer.play(UrlSource(urlStr));
243 } 280 }
  281 +
  282 + Future<void> closePlayerResource() async {
  283 + if (voicePlayState == VoicePlayState.playing || _isResultSoundPlaying) {
  284 + await audioPlayer.stop();
  285 + }
  286 + }
  287 +
  288 + void _playResultSound(bool isCorrect) async {
  289 + await audioPlayer.stop();
  290 + _isResultSoundPlaying = true;
  291 + _forbiddenWhenCorrect = isCorrect;
  292 + if (isCorrect) {
  293 + await audioPlayer.play(AssetSource('correct_voice'.assetMp3));
  294 + } else {
  295 + await audioPlayer.play(AssetSource('incorrect_voice'.assetMp3));
  296 + }
  297 + }
244 } 298 }
lib/pages/practice/bloc/topic_picture_event.dart
@@ -48,5 +48,5 @@ class SelectItemEvent extends TopicPictureEvent { @@ -48,5 +48,5 @@ class SelectItemEvent extends TopicPictureEvent {
48 ///音频播放事件 48 ///音频播放事件
49 class VoicePlayChangeEvent extends TopicPictureEvent {} 49 class VoicePlayChangeEvent extends TopicPictureEvent {}
50 50
51 -///播放音乐 51 +///播放(题目)音乐
52 class VoicePlayEvent extends TopicPictureEvent {} 52 class VoicePlayEvent extends TopicPictureEvent {}
53 \ No newline at end of file 53 \ No newline at end of file
lib/pages/practice/widgets/practice_header_widget.dart
@@ -14,46 +14,42 @@ class PracticeHeaderWidget extends StatelessWidget { @@ -14,46 +14,42 @@ class PracticeHeaderWidget extends StatelessWidget {
14 return Container( 14 return Container(
15 color: Colors.white, 15 color: Colors.white,
16 height: 60.h, 16 height: 60.h,
17 - child: Row(  
18 - mainAxisAlignment: MainAxisAlignment.spaceBetween,  
19 - children: [  
20 - Padding(  
21 - padding: EdgeInsets.only(  
22 - left: ScreenUtil().bottomBarHeight  
23 - ),  
24 - child: IconButton(  
25 - onPressed: (){  
26 - onTap();  
27 - },  
28 - icon: Image.asset(  
29 - 'back_around'.assetPng,  
30 - width: 40,  
31 - height: 40,  
32 - )), 17 + child: AppBar(
  18 + leading: IconButton(
  19 + icon: Image.asset(
  20 + 'back_around'.assetPng,
  21 + width: 40,
  22 + height: 40,
33 ), 23 ),
34 - Container(  
35 - height: 40.h,  
36 - padding: EdgeInsets.symmetric(horizontal: 27.w),  
37 - decoration: BoxDecoration(  
38 - color: const Color(0xFF00B6F1),  
39 - borderRadius: BorderRadius.circular(20.r),  
40 - border: Border.all(  
41 - width: 1.0,  
42 - color: const Color(0xFF333333),  
43 - ),  
44 - ),  
45 - alignment: Alignment.center,  
46 - child: Text(  
47 - title,  
48 - style: TextStyle(  
49 - fontSize: 20.sp,  
50 - color: Colors.white 24 + onPressed: () {
  25 + onTap();
  26 + },
  27 + ),
  28 + centerTitle: true,
  29 + title: IntrinsicWidth(
  30 + child: Container(
  31 + height: 40.h,
  32 + padding: EdgeInsets.symmetric(horizontal: 27.w),
  33 + decoration: BoxDecoration(
  34 + color: const Color(0xFF00B6F1),
  35 + borderRadius: BorderRadius.circular(20.r),
  36 + border: Border.all(
  37 + width: 1.0,
  38 + color: const Color(0xFF333333),
  39 + ),
51 ), 40 ),
52 - ), 41 + child: Center(
  42 + child: Text(
  43 + title,
  44 + style: TextStyle(
  45 + fontSize: 15.sp,
  46 + color: Colors.white
  47 + ),
  48 + ),
  49 + )
53 ), 50 ),
54 - ScreenUtil().bottomBarHeight.horizontalSpace,  
55 - ],  
56 - ), 51 + )
  52 + )
57 ); 53 );
58 } 54 }
59 } 55 }
60 \ No newline at end of file 56 \ No newline at end of file
lib/pages/reading/bloc/reading_bloc.dart
@@ -309,12 +309,12 @@ class ReadingPageBloc extends Bloc&lt;ReadingPageEvent, ReadingPageState&gt; { @@ -309,12 +309,12 @@ class ReadingPageBloc extends Bloc&lt;ReadingPageEvent, ReadingPageState&gt; {
309 Log.d("_voiceXsResult result=$result"); 309 Log.d("_voiceXsResult result=$result");
310 final overall = result['overall'].toString(); 310 final overall = result['overall'].toString();
311 EasyLoading.showToast('测评成功,分数是$overall', 311 EasyLoading.showToast('测评成功,分数是$overall',
312 - duration: const Duration(seconds: 10)); 312 + duration: const Duration(seconds: 2));
313 currentPageData()?.recordScore = overall; 313 currentPageData()?.recordScore = overall;
314 currentPageData()?.recordUrl = args['audioUrl'] + '.mp3'; 314 currentPageData()?.recordUrl = args['audioUrl'] + '.mp3';
315 ///完成录音后紧接着播放录音 315 ///完成录音后紧接着播放录音
316 _playRecordAudioInner(); 316 _playRecordAudioInner();
317 - emitter(FeedbackState()); 317 + // emitter(FeedbackState());
318 } 318 }
319 319
320 ///终止评测 320 ///终止评测
lib/pages/section/section_page.dart
@@ -183,46 +183,46 @@ class _SectionPageView extends StatelessWidget { @@ -183,46 +183,46 @@ class _SectionPageView extends StatelessWidget {
183 ); 183 );
184 } 184 }
185 })), 185 })),
186 - SafeArea(  
187 - child: Padding(  
188 - padding: EdgeInsets.symmetric(horizontal: 13.w),  
189 - child: Row(  
190 - mainAxisAlignment: MainAxisAlignment.spaceBetween,  
191 - children: [  
192 - SizedBox(  
193 - height: 47.h,  
194 - width: 80.w,  
195 - ),  
196 - Container(  
197 - decoration: BoxDecoration(  
198 - color: CourseModuleModel(  
199 - bloc.courseUnitEntity.courseModuleCode ??  
200 - 'Phase-1')  
201 - .color,  
202 - borderRadius: BorderRadius.circular(14.5.r),  
203 - ),  
204 - padding: EdgeInsets.symmetric(  
205 - vertical: 8.h, horizontal: 24.w),  
206 - child: Text(  
207 - '${(bloc.courseUnitEntity.nowStep ?? 0)}/${bloc.courseUnitEntity.total ?? 0}',  
208 - style: TextStyle(  
209 - color: Colors.white, fontSize: 12.sp),  
210 - ),  
211 - ),  
212 - Image.asset(  
213 - CourseModuleModel(  
214 - bloc.courseUnitEntity.courseModuleCode ??  
215 - 'Phase-1')  
216 - .courseModuleLogo  
217 - .assetPng,  
218 - height: 47.h,  
219 - width: 80.w,  
220 - // color: Colors.red,  
221 - ),  
222 - ],  
223 - ),  
224 - ),  
225 - ) 186 + // SafeArea(
  187 + // child: Padding(
  188 + // padding: EdgeInsets.symmetric(horizontal: 13.w),
  189 + // child: Row(
  190 + // mainAxisAlignment: MainAxisAlignment.spaceBetween,
  191 + // children: [
  192 + // SizedBox(
  193 + // height: 47.h,
  194 + // width: 80.w,
  195 + // ),
  196 + // Container(
  197 + // decoration: BoxDecoration(
  198 + // color: CourseModuleModel(
  199 + // bloc.courseUnitEntity.courseModuleCode ??
  200 + // 'Phase-1')
  201 + // .color,
  202 + // borderRadius: BorderRadius.circular(14.5.r),
  203 + // ),
  204 + // padding: EdgeInsets.symmetric(
  205 + // vertical: 8.h, horizontal: 24.w),
  206 + // child: Text(
  207 + // '${(bloc.courseUnitEntity.nowStep ?? 0)}/${bloc.courseUnitEntity.total ?? 0}',
  208 + // style: TextStyle(
  209 + // color: Colors.white, fontSize: 12.sp),
  210 + // ),
  211 + // ),
  212 + // Image.asset(
  213 + // CourseModuleModel(
  214 + // bloc.courseUnitEntity.courseModuleCode ??
  215 + // 'Phase-1')
  216 + // .courseModuleLogo
  217 + // .assetPng,
  218 + // height: 47.h,
  219 + // width: 80.w,
  220 + // // color: Colors.red,
  221 + // ),
  222 + // ],
  223 + // ),
  224 + // ),
  225 + // )
226 ], 226 ],
227 ), 227 ),
228 ), 228 ),
lib/pages/shop/home/shop_home_page.dart
@@ -62,14 +62,14 @@ class _ShopHomeView extends StatelessWidget { @@ -62,14 +62,14 @@ class _ShopHomeView extends StatelessWidget {
62 ), 62 ),
63 body: Center( 63 body: Center(
64 child: Padding( 64 child: Padding(
65 - padding: EdgeInsets.symmetric(vertical: 25.h, horizontal: 25.w), 65 + padding: EdgeInsets.symmetric(vertical: 24.h, horizontal: 24.w),
66 child: GridView.builder( 66 child: GridView.builder(
67 itemCount: bloc.productDatas.length, 67 itemCount: bloc.productDatas.length,
68 gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( 68 gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
69 crossAxisCount: 2, 69 crossAxisCount: 2,
70 childAspectRatio: 2, 70 childAspectRatio: 2,
71 mainAxisSpacing: 14.h, 71 mainAxisSpacing: 14.h,
72 - crossAxisSpacing: 4.5.w, 72 + crossAxisSpacing: 6.w,
73 ), 73 ),
74 itemBuilder: (BuildContext context, int index) { 74 itemBuilder: (BuildContext context, int index) {
75 final productEntity = bloc.productDatas[index]; 75 final productEntity = bloc.productDatas[index];
pubspec.yaml
@@ -98,11 +98,11 @@ dependencies: @@ -98,11 +98,11 @@ dependencies:
98 # 语音录制 https://pub.dev/packages/flutter_sound 98 # 语音录制 https://pub.dev/packages/flutter_sound
99 flutter_sound: ^9.2.13 99 flutter_sound: ^9.2.13
100 # 音频播放 https://pub.dev/packages/audio_session 100 # 音频播放 https://pub.dev/packages/audio_session
101 - audio_session: ^0.1.16 101 + audio_session: ^0.1.19
102 # 文件管理 https://pub.dev/packages/path_provider 102 # 文件管理 https://pub.dev/packages/path_provider
103 path_provider: ^2.0.15 103 path_provider: ^2.0.15
104 # 阿里云oss https://pub.dev/packages/flutter_oss_aliyun 104 # 阿里云oss https://pub.dev/packages/flutter_oss_aliyun
105 - flutter_oss_aliyun: ^6.2.7 105 + flutter_oss_aliyun: ^6.4.2
106 # App信息 https://pub.dev/packages/package_info_plus 106 # App信息 https://pub.dev/packages/package_info_plus
107 package_info_plus: ^4.2.0 107 package_info_plus: ^4.2.0
108 # 应用内更新 https://pub-web.flutter-io.cn/packages/flutter_app_update 108 # 应用内更新 https://pub-web.flutter-io.cn/packages/flutter_app_update
@@ -135,6 +135,7 @@ flutter: @@ -135,6 +135,7 @@ flutter:
135 assets: 135 assets:
136 - assets/images/ 136 - assets/images/
137 - assets/fonts/ 137 - assets/fonts/
  138 + - assets/sounds/
138 fonts: 139 fonts:
139 - family: HannotateSC 140 - family: HannotateSC
140 fonts: 141 fonts: