提交 5b74b194 authored 作者: 岳维路's avatar 岳维路

合并分支 'test' 到 'sim'

Test 查看合并请求 kiwitap/zijing-app!2
...@@ -14,6 +14,7 @@ abstract class CourseAPI { ...@@ -14,6 +14,7 @@ abstract class CourseAPI {
'page': page, 'page': page,
'page_size': limit, 'page_size': limit,
}, },
showLoading: true
); );
if (result.data is! Map && result.data['list'] is! List) return []; if (result.data is! Map && result.data['list'] is! List) return [];
return List.generate(result.data['list'].length, (index){ return List.generate(result.data['list'].length, (index){
......
...@@ -156,6 +156,7 @@ abstract class LibraryAPI { ...@@ -156,6 +156,7 @@ abstract class LibraryAPI {
'book_id': bookId, 'book_id': bookId,
'chapter_id': chapterId 'chapter_id': chapterId
}, },
showLoading: true
); );
if (result.data is! Map && result.data['list'] is! List) return []; if (result.data is! Map && result.data['list'] is! List) return [];
return List.generate(result.data['list'].length, (index) { return List.generate(result.data['list'].length, (index) {
...@@ -178,6 +179,7 @@ abstract class LibraryAPI { ...@@ -178,6 +179,7 @@ abstract class LibraryAPI {
'book_id': bookId, 'book_id': bookId,
'chapter_id': chapterId 'chapter_id': chapterId
}, },
showLoading: true,
); );
if (result.data is! Map && result.data['list'] is! List) return []; if (result.data is! Map && result.data['list'] is! List) return [];
return List.generate(result.data['list'].length, (index) { return List.generate(result.data['list'].length, (index) {
......
...@@ -366,7 +366,9 @@ class NoteModel { ...@@ -366,7 +366,9 @@ class NoteModel {
content = json['content']; content = json['content'];
positioning = json['positioning']; positioning = json['positioning'];
// noteContent = json['note_content']; // noteContent = json['note_content'];
if (types ==3){
noteContent = json['note_content'] != null ? NoteContentModel.fromJson(json['note_content']) : null; noteContent = json['note_content'] != null ? NoteContentModel.fromJson(json['note_content']) : null;
}
color = json['color']; color = json['color'];
chapterName = json['chapter_name']; chapterName = json['chapter_name'];
isMy = json['is_my']; isMy = json['is_my'];
......
...@@ -144,7 +144,8 @@ class _BookDetailPageState extends State<BookDetailPage> with SingleTickerProvid ...@@ -144,7 +144,8 @@ class _BookDetailPageState extends State<BookDetailPage> with SingleTickerProvid
*{ margin: 0; padding: 5px;} *{ margin: 0; padding: 5px;}
html{ font-size: 10px;} html{ font-size: 10px;}
body p{ font-size: 1.5rem; line-height:2.4rem;color: #999} body p{ font-size: 1.5rem; line-height:2.4rem;color: #999}
img{ max-width:100%} img,video,pre,code{ max-width:100%}
pre{white-space: pre-wrap;word-wrap: break-word;word-break: break-all}
</style> </style>
</head> </head>
<body> <body>
......
...@@ -19,7 +19,18 @@ class _BookShopPageState extends State<BookShopPage> { ...@@ -19,7 +19,18 @@ class _BookShopPageState extends State<BookShopPage> {
body: Column( body: Column(
children: [ children: [
Expanded( Expanded(
child: ListView.builder( child: controller.carts.isEmpty?Container(
padding: EdgeInsets.only(top: 110.w),
alignment: Alignment.center,
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
SizedBox(height: 152.w, width: 195.w,
child: Image.asset( 'assets/images/none.png',),),
SizedBox(height: 13.w,),
],
),
):ListView.builder(
itemBuilder: (BuildContext context,int index){ itemBuilder: (BuildContext context,int index){
CourseModel model = controller.carts[index]; CourseModel model = controller.carts[index];
return GestureDetector( return GestureDetector(
......
...@@ -24,6 +24,7 @@ class CourseController extends GetxController { ...@@ -24,6 +24,7 @@ class CourseController extends GetxController {
void onReady() { void onReady() {
_getAds(); _getAds();
getNums(); getNums();
onRefresh();
super.onReady(); super.onReady();
} }
......
...@@ -84,7 +84,19 @@ class _CoursePageState extends State<CoursePage> { ...@@ -84,7 +84,19 @@ class _CoursePageState extends State<CoursePage> {
controller: controller.refreshController, controller: controller.refreshController,
onRefresh: controller.onRefresh, onRefresh: controller.onRefresh,
onLoading: controller.onLoading, onLoading: controller.onLoading,
child: GridView.builder( child: controller.courses.isEmpty?Container(
padding: EdgeInsets.only(top: 110.w),
alignment: Alignment.center,
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
SizedBox(height: 152.w, width: 195.w,
child: Image.asset( 'assets/images/none.png',),),
SizedBox(height: 13.w,),
Text('暂无课程',style: TextStyle(fontSize: 14.w,color: Colours.c9),),
],
),
):GridView.builder(
padding: EdgeInsets.only(left: 13.w,top: 10.w), padding: EdgeInsets.only(left: 13.w,top: 10.w),
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2, crossAxisCount: 2,
......
...@@ -26,6 +26,7 @@ class _HelpCenterPageState extends State<HelpCenterPage> { ...@@ -26,6 +26,7 @@ class _HelpCenterPageState extends State<HelpCenterPage> {
itemCount: controller.helpCenters.length, itemCount: controller.helpCenters.length,
itemBuilder: (BuildContext context, int index){ itemBuilder: (BuildContext context, int index){
HelpCenterModel model = controller.helpCenters[index]; HelpCenterModel model = controller.helpCenters[index];
model.id = index +1;
return GestureDetector( return GestureDetector(
child: BuildItem(model: model,), child: BuildItem(model: model,),
onTap: (){ onTap: (){
......
...@@ -17,7 +17,29 @@ class HelpCenterContentController extends GetxController { ...@@ -17,7 +17,29 @@ class HelpCenterContentController extends GetxController {
/// 获取帮助中心内容 /// 获取帮助中心内容
void _getHelpCenterContent(String id) async { void _getHelpCenterContent(String id) async {
helpCenterContentModel = await MineAPI.helpCenterContent(id); helpCenterContentModel = await MineAPI.helpCenterContent(id);
webViewController.loadData(data: helpCenterContentModel.helpContent??'');
webViewController.loadData(data: """
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no" />
<meta http-equiv="Cache-Control" content="no-transform" />
<meta http-equiv="Cache-Control" content="no-siteapp" />
<style>
*{ margin: 0; padding: 5px;}
html{ font-size: 10px;}
body p{ font-size: 1.5rem; line-height:2.4rem;color: #999}
img,video,pre,code{ max-width:100%}
pre{white-space: pre-wrap;word-wrap: break-word;word-break: break-all}
</style>
</head>
<body>
${helpCenterContentModel.helpContent??''}
</body>
</html>
""",);
update(); update();
} }
} }
...@@ -132,12 +132,10 @@ class LibraryController extends GetxController with GetTickerProviderStateMixin{ ...@@ -132,12 +132,10 @@ class LibraryController extends GetxController with GetTickerProviderStateMixin{
for(FilterModel model in filterFree){ for(FilterModel model in filterFree){
model.selected = false; model.selected = false;
} }
selectedFree.id = '';
for(FilterModel model in filterDown){ for(FilterModel model in filterDown){
model.selected = false; model.selected = false;
} }
selectedDown.id ='';
update(); update();
} }
...@@ -309,8 +307,7 @@ class LibraryController extends GetxController with GetTickerProviderStateMixin{ ...@@ -309,8 +307,7 @@ class LibraryController extends GetxController with GetTickerProviderStateMixin{
_getAds(); _getAds();
String sort = ''; String sort = '';
if (selectedDown.id !=null){ if (selectedDown.selected == true){
if (selectedDown.id!.isNotEmpty){
if(selectedDown.up){ if(selectedDown.up){
sort = 'desc'; sort = 'desc';
} }
...@@ -318,6 +315,10 @@ class LibraryController extends GetxController with GetTickerProviderStateMixin{ ...@@ -318,6 +315,10 @@ class LibraryController extends GetxController with GetTickerProviderStateMixin{
sort = 'asc'; sort = 'asc';
} }
} }
String sortField = '';
if (selectedDown.selected == true){
sortField = selectedDown.id ??'';
} }
if (isRefresh) _page = 1; if (isRefresh) _page = 1;
...@@ -328,7 +329,7 @@ class LibraryController extends GetxController with GetTickerProviderStateMixin{ ...@@ -328,7 +329,7 @@ class LibraryController extends GetxController with GetTickerProviderStateMixin{
categoryId: selectedCategory.id??'', categoryId: selectedCategory.id??'',
labelId: selectedLabel.id??'', labelId: selectedLabel.id??'',
isFree: selectedFree.id??'', isFree: selectedFree.id??'',
sortField: selectedDown.id??'', sortField: sortField,
sort :sort sort :sort
// sort:selectedDown.id!.isEmpty?'':selectedDown.up ==true?'desc':'asc' // sort:selectedDown.id!.isEmpty?'':selectedDown.up ==true?'desc':'asc'
); );
......
...@@ -16,7 +16,18 @@ class LibraryContentPage extends StatefulWidget { ...@@ -16,7 +16,18 @@ class LibraryContentPage extends StatefulWidget {
class _LibraryContentPageState extends State<LibraryContentPage> with AutomaticKeepAliveClientMixin { class _LibraryContentPageState extends State<LibraryContentPage> with AutomaticKeepAliveClientMixin {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return ListView.builder( return widget.controller.books.isEmpty?Container(
padding: EdgeInsets.only(top: 110.w),
alignment: Alignment.center,
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
SizedBox(height: 152.w, width: 195.w,
child: Image.asset( 'assets/images/none.png',),),
SizedBox(height: 13.w,),
],
),
):ListView.builder(
shrinkWrap: true, shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(), physics: const NeverScrollableScrollPhysics(),
itemCount: widget.controller.books.length, itemCount: widget.controller.books.length,
......
...@@ -102,7 +102,7 @@ class ReadController extends FullLifeCycleController with GetSingleTickerProvide ...@@ -102,7 +102,7 @@ class ReadController extends FullLifeCycleController with GetSingleTickerProvide
netStatus = await Tools.checkCurrentNetStatus(); netStatus = await Tools.checkCurrentNetStatus();
final exist = await _isExistFile(bookId); final exist = await _isExistFile(bookId);
if (netStatus && exist){ if (!netStatus && exist){
// 1、从数据库中获取读到那个章节 // 1、从数据库中获取读到那个章节
chapterId = await SqlManager.queryReadHistoryByBookId(int.parse(bookId)); chapterId = await SqlManager.queryReadHistoryByBookId(int.parse(bookId));
chapterName = getChapterName(chapterId); chapterName = getChapterName(chapterId);
...@@ -322,7 +322,7 @@ class ReadController extends FullLifeCycleController with GetSingleTickerProvide ...@@ -322,7 +322,7 @@ class ReadController extends FullLifeCycleController with GetSingleTickerProvide
final path = await _mRecorder.stopRecorder(); final path = await _mRecorder.stopRecorder();
var duration = await audioPlayer.setFilePath(path!); var duration = await audioPlayer.setFilePath(path!);
Console.log('-----duration---------------------$duration------'); Console.log('-----duration---------------------$duration------');
AudioModel audioModel = AudioModel(path: path,duration: Tools.formatDuration(duration!)); AudioModel audioModel = AudioModel(path: path,duration: Tools.formatDuration(duration!),currentDuration: '0:00:00');
discussInputAudios.add(audioModel); discussInputAudios.add(audioModel);
update(); update();
} }
...@@ -357,6 +357,8 @@ class ReadController extends FullLifeCycleController with GetSingleTickerProvide ...@@ -357,6 +357,8 @@ class ReadController extends FullLifeCycleController with GetSingleTickerProvide
// 播放音频 // 播放音频
void playAudio(AudioModel audioModel){ void playAudio(AudioModel audioModel){
Console.log('-------------播放开始-------------------');
if(audioPlayer.playerState.playing){ if(audioPlayer.playerState.playing){
audioPlayer.stop(); audioPlayer.stop();
audioModel.currentDuration = '0:00:00'; audioModel.currentDuration = '0:00:00';
...@@ -366,12 +368,16 @@ class ReadController extends FullLifeCycleController with GetSingleTickerProvide ...@@ -366,12 +368,16 @@ class ReadController extends FullLifeCycleController with GetSingleTickerProvide
} }
// 本地音频 // 本地音频
audioPlayer.setFilePath(audioModel.path); audioPlayer.setFilePath(audioModel.path);
audioPlayer.play(); audioPlayer.play();
audioPlayer.positionStream.listen((position) { StreamSubscription? positionSubscription;
positionSubscription =audioPlayer.positionStream.listen((position) {
String temp = Tools.formatDuration(position); String temp = Tools.formatDuration(position);
Console.log('播放时间---------------------$temp'); Console.log('播放时间---------------------$temp------id-------------${audioModel.path}');
audioModel.currentDuration = temp; audioModel.currentDuration = temp;
if(position >= audioPlayer.duration!){
Console.log('---------播放结束-----------');
positionSubscription?.cancel();
}
update(); update();
}); });
// currentPlayMediaModel = mediaModel; // currentPlayMediaModel = mediaModel;
...@@ -410,6 +416,11 @@ class ReadController extends FullLifeCycleController with GetSingleTickerProvide ...@@ -410,6 +416,11 @@ class ReadController extends FullLifeCycleController with GetSingleTickerProvide
Console.log('clearAllDiscussInput--------------------------------'); Console.log('clearAllDiscussInput--------------------------------');
update(); update();
} }
// 删除音频
void delAudio(AudioModel audioModel){
discussInputAudios.remove(audioModel);
update();
}
// 上传文件 // 上传文件
...@@ -893,8 +904,8 @@ class ToolModel { ...@@ -893,8 +904,8 @@ class ToolModel {
} }
class AudioModel { class AudioModel {
AudioModel({required this.path, required this.duration}); AudioModel({required this.path, required this.duration,required this.currentDuration});
String path; String path;
String duration; String duration;
late String currentDuration; String currentDuration;
} }
...@@ -14,6 +14,8 @@ class NoteController extends GetxController { ...@@ -14,6 +14,8 @@ class NoteController extends GetxController {
late TextEditingController searchInput = TextEditingController(); late TextEditingController searchInput = TextEditingController();
just_audio.AudioPlayer audioPlayer = just_audio.AudioPlayer();
final int _limit = 10; final int _limit = 10;
int _page = 1; int _page = 1;
bool _noMore = false; bool _noMore = false;
...@@ -39,6 +41,7 @@ class NoteController extends GetxController { ...@@ -39,6 +41,7 @@ class NoteController extends GetxController {
void onClose() { void onClose() {
refreshController.dispose(); refreshController.dispose();
searchInput.dispose(); searchInput.dispose();
audioPlayer.dispose();
super.onClose(); super.onClose();
} }
...@@ -47,6 +50,47 @@ class NoteController extends GetxController { ...@@ -47,6 +50,47 @@ class NoteController extends GetxController {
update(); update();
} }
void delNotes({required String notesId,required String bookId}) async {
final result = await MineAPI.delNotes(notesId: notesId, bookId: bookId);
if (result){
Toast.show('删除笔记成功');
onRefresh();
}
}
// 播放音频
void playAudio(MediaModel mediaModel){
if(audioPlayer.playerState.playing){
audioPlayer.stop();
mediaModel.currentDuration = '0:00:00';
// if(currentPlayMediaModel.id == mediaModel.id){
// return;
// }
}
// 本地音频
if (mediaModel.id == 0){
audioPlayer.setFilePath(mediaModel.path);
}
// 远程音频
else {
audioPlayer.setUrl(mediaModel.content??'');
}
audioPlayer.play();
StreamSubscription? positionSubscription;
positionSubscription =audioPlayer.positionStream.listen((position) {
String temp = Tools.formatDuration(position);
Console.log('播放时间---------------------$temp------id-------------${mediaModel.id}');
mediaModel.currentDuration = temp;
if(position >= audioPlayer.duration!){
Console.log('---------播放结束-----------');
positionSubscription?.cancel();
}
update();
});
// currentPlayMediaModel = mediaModel;
}
/// 搜全文 /// 搜全文
Future<void> searchAll([bool isRefresh = false]) async { Future<void> searchAll([bool isRefresh = false]) async {
if (isRefresh) _searchPage = 1; if (isRefresh) _searchPage = 1;
...@@ -103,11 +147,13 @@ class NoteController extends GetxController { ...@@ -103,11 +147,13 @@ class NoteController extends GetxController {
); );
for(NoteModel noteModel in result){ for(NoteModel noteModel in result){
if(noteModel.noteContent!=null && noteModel.noteContent!.audio != null){
if(noteModel.noteContent!.audio!.isNotEmpty){ if(noteModel.noteContent!.audio!.isNotEmpty){
for(MediaModel mediaModel in noteModel.noteContent!.audio!){ for(MediaModel? mediaModel in noteModel.noteContent!.audio!){
Duration? duration = await just_audio.AudioPlayer().setUrl(mediaModel.content??''); Duration? duration = await just_audio.AudioPlayer().setUrl(mediaModel?.content??'');
mediaModel.duration = Tools.formatDuration(duration!); mediaModel?.duration = Tools.formatDuration(duration!);
}
} }
} }
} }
...@@ -127,6 +173,7 @@ class NoteController extends GetxController { ...@@ -127,6 +173,7 @@ class NoteController extends GetxController {
refreshController.resetFooter(); refreshController.resetFooter();
} catch (error) { } catch (error) {
refreshController.finishRefresh(IndicatorResult.fail); refreshController.finishRefresh(IndicatorResult.fail);
Console.log('error-----------------------$error');
} }
} }
...@@ -139,6 +186,7 @@ class NoteController extends GetxController { ...@@ -139,6 +186,7 @@ class NoteController extends GetxController {
await _getNotes(); await _getNotes();
refreshController.finishLoad(); refreshController.finishLoad();
} catch (error) { } catch (error) {
Console.log('error-----------------------$error');
refreshController.finishLoad(IndicatorResult.fail); refreshController.finishLoad(IndicatorResult.fail);
} }
} }
......
...@@ -89,6 +89,7 @@ class _ReadPageState extends State<ReadPage> { ...@@ -89,6 +89,7 @@ class _ReadPageState extends State<ReadPage> {
) )
), ),
onWebViewCreated: (InAppWebViewController controller){ onWebViewCreated: (InAppWebViewController controller){
CustomToast.loading();
readController.webViewController = controller; readController.webViewController = controller;
}, },
onConsoleMessage: (controller, consoleMessage) { onConsoleMessage: (controller, consoleMessage) {
...@@ -96,6 +97,7 @@ class _ReadPageState extends State<ReadPage> { ...@@ -96,6 +97,7 @@ class _ReadPageState extends State<ReadPage> {
Console.log("Received message from WebView-----------------------------: ${consoleMessage.message}"); Console.log("Received message from WebView-----------------------------: ${consoleMessage.message}");
}, },
onLoadStop: (controller, url) { onLoadStop: (controller, url) {
CustomToast.dismiss();
// flutter 主动给 js 传参数 // flutter 主动给 js 传参数
Map<String, dynamic> param = { Map<String, dynamic> param = {
'book_id': readController.bookId, 'book_id': readController.bookId,
......
...@@ -126,29 +126,44 @@ class _ReadInputDiscussState extends State<ReadInputDiscuss> { ...@@ -126,29 +126,44 @@ class _ReadInputDiscussState extends State<ReadInputDiscuss> {
shrinkWrap: true, shrinkWrap: true,
itemBuilder: (BuildContext context, int index){ itemBuilder: (BuildContext context, int index){
AudioModel audioModel= widget.controller.discussInputAudios[index]; AudioModel audioModel= widget.controller.discussInputAudios[index];
return GestureDetector( return Container(
onTap: (){ // height: 20.w,
widget.controller.playAudio(audioModel); margin: EdgeInsets.only(right: 130.w,),
}, child: Stack(
child: Container( children: [
height: 20.w, Container(
margin: EdgeInsets.only(right: 130.w),
child: Container(
margin: EdgeInsets.only(top: 5.w),
padding: EdgeInsets.only(right:20.w,left: 10.w),
decoration: BoxDecoration( decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10.w), borderRadius: BorderRadius.circular(10.w),
color: Colours.cF9, color: Colors.white,
), ),
padding: EdgeInsets.only(right:20.w,left: 10.w),
margin: EdgeInsets.only(top: 10.w,right: 10.w),
height: 20,
child: Row( child: Row(
// mainAxisSize: MainAxisSize.min, // mainAxisSize: MainAxisSize.min,
mainAxisAlignment:MainAxisAlignment.spaceBetween, mainAxisAlignment:MainAxisAlignment.spaceBetween,
children: [ children: [
Image.asset('assets/images/audio.png'), GestureDetector(
// Text('0:00/1:52',style: TextStyle(fontSize: 10.w,height: 1.4,color: Colours.c9),) onTap:(){
widget.controller.playAudio(audioModel);
},
child: Image.asset('assets/images/audio.png')
),
Text('${audioModel.currentDuration}/${audioModel.duration}',style: TextStyle(fontSize: 10.w,height: 1.4,color: Colours.c9),)
], ],
), ),
), ),
Positioned(
right: 6,
top: 6,
child: GestureDetector(
onTap: (){
widget.controller.delAudio(audioModel);
},
child: Image.asset('assets/images/media_del.png',width: 12.w,height: 12.w,)
)
)
],
), ),
); );
}, },
......
...@@ -98,7 +98,7 @@ class _ReadNotePageState extends State<ReadNotePage> { ...@@ -98,7 +98,7 @@ class _ReadNotePageState extends State<ReadNotePage> {
child: MediaQuery.removePadding( child: MediaQuery.removePadding(
context: context, context: context,
removeTop: true, removeTop: true,
child: ListView.builder( child:ListView.builder(
itemBuilder: (BuildContext context,int index){ itemBuilder: (BuildContext context,int index){
NoteModel model = controller.notes[index]; NoteModel model = controller.notes[index];
// 划线 // 划线
...@@ -111,7 +111,15 @@ class _ReadNotePageState extends State<ReadNotePage> { ...@@ -111,7 +111,15 @@ class _ReadNotePageState extends State<ReadNotePage> {
} }
// 笔记 // 笔记
else if(model.types == 3){ else if(model.types == 3){
return BuildNote(model: model,); return BuildNote(
model: model,
onTapAudio: (MediaModel mediaModel){
controller.playAudio(mediaModel);
},
onTapDel: (){
controller.delNotes(notesId: model.notesId.toString(), bookId:widget.bookDetailModel.bookId.toString());
},
);
} }
}, },
itemCount: controller.notes.length, itemCount: controller.notes.length,
......
...@@ -157,10 +157,15 @@ class UserEditNoteController extends GetxController { ...@@ -157,10 +157,15 @@ class UserEditNoteController extends GetxController {
audioPlayer.setUrl(mediaModel.content??''); audioPlayer.setUrl(mediaModel.content??'');
} }
audioPlayer.play(); audioPlayer.play();
audioPlayer.positionStream.listen((position) { StreamSubscription? positionSubscription;
positionSubscription =audioPlayer.positionStream.listen((position) {
String temp = Tools.formatDuration(position); String temp = Tools.formatDuration(position);
Console.log('播放时间---------------------$temp'); Console.log('播放时间---------------------$temp------id-------------${mediaModel.id}');
mediaModel.currentDuration = temp; mediaModel.currentDuration = temp;
if(position >= audioPlayer.duration!){
Console.log('---------播放结束-----------');
positionSubscription?.cancel();
}
update(); update();
}); });
// currentPlayMediaModel = mediaModel; // currentPlayMediaModel = mediaModel;
......
...@@ -59,7 +59,24 @@ class MsgPage extends StatelessWidget { ...@@ -59,7 +59,24 @@ class MsgPage extends StatelessWidget {
} }
} }
// 已支付 // 已取消
else if (orderInfo.status ==2){
if (orderInfo.types == 1){
final result = await context.pushNamed(Routes.orderCancel,
queryParameters: {'orderNum': model.urlId?.orderNum.toString()});
if (result == true){
controller.onRefresh();
}
}
else {
final result = await context.pushNamed(Routes.orderCoinCancel,
queryParameters: {'orderNum': model.urlId?.orderNum.toString()});
if (result == true){
controller.onRefresh();
}
}
}
// 已完成
else if (orderInfo.status ==3){ else if (orderInfo.status ==3){
if (orderInfo.types == 1){ if (orderInfo.types == 1){
final result = await context.pushNamed(Routes.orderCompleted, final result = await context.pushNamed(Routes.orderCompleted,
...@@ -68,6 +85,13 @@ class MsgPage extends StatelessWidget { ...@@ -68,6 +85,13 @@ class MsgPage extends StatelessWidget {
controller.onRefresh(); controller.onRefresh();
} }
} }
else {
final result = await context.pushNamed(Routes.orderCoinCompleted,
queryParameters: {'orderNum': model.urlId?.orderNum.toString()});
if (result == true){
controller.onRefresh();
}
}
} }
// 已退款 // 已退款
else if (orderInfo.status == 4){ else if (orderInfo.status == 4){
...@@ -83,6 +107,11 @@ class MsgPage extends StatelessWidget { ...@@ -83,6 +107,11 @@ class MsgPage extends StatelessWidget {
///TODO: ///TODO:
}else if (model.type == 2){ }else if (model.type == 2){
// 2 购买完成三天未评价(跳转订单列表--已完成) // 2 购买完成三天未评价(跳转订单列表--已完成)
// final orderInfo = await controller.getOrderInfo(model.urlId?.orderNum??'');
//
// final result = await context.pushNamed(Routes.orderEvaluate,extra:orderInfo,
// queryParameters: {'orderNum':orderInfo.ordersnum});
//
final result = await context.pushNamed(Routes.order); final result = await context.pushNamed(Routes.order);
if (result == true){ if (result == true){
controller.onRefresh(); controller.onRefresh();
......
...@@ -49,10 +49,15 @@ class UserNotesDesController extends GetxController { ...@@ -49,10 +49,15 @@ class UserNotesDesController extends GetxController {
audioPlayer.setUrl(mediaModel.content??''); audioPlayer.setUrl(mediaModel.content??'');
} }
audioPlayer.play(); audioPlayer.play();
audioPlayer.positionStream.listen((position) { StreamSubscription? positionSubscription;
positionSubscription =audioPlayer.positionStream.listen((position) {
String temp = Tools.formatDuration(position); String temp = Tools.formatDuration(position);
Console.log('播放时间---------------------$temp'); Console.log('播放时间---------------------$temp------id-------------${mediaModel.id}');
mediaModel.currentDuration = temp; mediaModel.currentDuration = temp;
if(position >= audioPlayer.duration!){
Console.log('---------播放结束-----------');
positionSubscription?.cancel();
}
update(); update();
}); });
// currentPlayMediaModel = mediaModel; // currentPlayMediaModel = mediaModel;
...@@ -77,11 +82,13 @@ class UserNotesDesController extends GetxController { ...@@ -77,11 +82,13 @@ class UserNotesDesController extends GetxController {
types: tag types: tag
); );
for(NoteModel noteModel in result){ for(NoteModel noteModel in result){
if(noteModel.noteContent!=null && noteModel.noteContent!.audio != null){
if(noteModel.noteContent!.audio!.isNotEmpty){ if(noteModel.noteContent!.audio!.isNotEmpty){
for(MediaModel mediaModel in noteModel.noteContent!.audio!){ for(MediaModel? mediaModel in noteModel.noteContent!.audio!){
Duration? duration = await just_audio.AudioPlayer().setUrl(mediaModel.content??''); Duration? duration = await just_audio.AudioPlayer().setUrl(mediaModel?.content??'');
mediaModel.duration = Tools.formatDuration(duration!); mediaModel?.duration = Tools.formatDuration(duration!);
}
} }
} }
} }
......
library user_notes_des; library user_notes_des;
import 'dart:async';
import 'package:easy_refresh/easy_refresh.dart'; import 'package:easy_refresh/easy_refresh.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_book/widgets/index.dart'; import 'package:flutter_book/widgets/index.dart';
......
...@@ -26,6 +26,7 @@ class BuildHigh extends StatelessWidget { ...@@ -26,6 +26,7 @@ class BuildHigh extends StatelessWidget {
], ],
), ),
child: Slidable( child: Slidable(
enabled: model.isMy == 1 ? true : false,
endActionPane: ActionPane( endActionPane: ActionPane(
motion: const ScrollMotion(), motion: const ScrollMotion(),
children: [ children: [
......
...@@ -26,6 +26,7 @@ class BuildLine extends StatelessWidget { ...@@ -26,6 +26,7 @@ class BuildLine extends StatelessWidget {
], ],
), ),
child: Slidable( child: Slidable(
enabled: model.isMy == 1 ? true : false,
endActionPane: ActionPane( endActionPane: ActionPane(
motion: const ScrollMotion(), motion: const ScrollMotion(),
children: [ children: [
......
...@@ -31,6 +31,7 @@ class BuildNote extends StatelessWidget { ...@@ -31,6 +31,7 @@ class BuildNote extends StatelessWidget {
], ],
), ),
child: Slidable( child: Slidable(
enabled: model.isMy == 1 ? true : false,
endActionPane: ActionPane( endActionPane: ActionPane(
motion: const ScrollMotion(), motion: const ScrollMotion(),
children: [ children: [
...@@ -198,11 +199,18 @@ class BuildNote extends StatelessWidget { ...@@ -198,11 +199,18 @@ class BuildNote extends StatelessWidget {
children: [ children: [
GestureDetector( GestureDetector(
onTap: (){ onTap: (){
// 我的录音 或者 已经审核通过的录音才可以播放
if(model.isMy == 1 || mediaModel.privacyStatus == 1){
if (onTapAudio !=null) onTapAudio!(mediaModel); if (onTapAudio !=null) onTapAudio!(mediaModel);
}
else{
Toast.show('当前音频处于审核中');
}
}, },
child: Image.asset('assets/images/audio.png') child: Image.asset('assets/images/audio.png')
), ),
Text('0:00/${mediaModel.duration}',style: TextStyle(fontSize: 10.w,height: 1.4,color: Colours.c9),) Text('${mediaModel.currentDuration}/${mediaModel.duration}',style: TextStyle(fontSize: 10.w,height: 1.4,color: Colours.c9),)
], ],
), ),
), ),
......
...@@ -24,6 +24,20 @@ class BuiltCoin extends StatelessWidget { ...@@ -24,6 +24,20 @@ class BuiltCoin extends StatelessWidget {
controller.onRefresh(); controller.onRefresh();
} }
} }
else if(model.status == 2){
final result = await context.pushNamed(Routes.orderCoinCancel,
queryParameters: {'orderNum': model.ordersnum});
if(result==true){
controller.onRefresh();
}
}
else if(model.status == 3){
final result = await context.pushNamed(Routes.orderCoinCompleted,
queryParameters: {'orderNum': model.ordersnum});
if(result==true){
controller.onRefresh();
}
}
}, },
child: Container( child: Container(
margin: EdgeInsets.only(left: 10.w, right: 10.w, top: 10.w), margin: EdgeInsets.only(left: 10.w, right: 10.w, top: 10.w),
......
part of user_order_coin_cancel;
/// 紫荆币等待付款订单
class UserOrderCoinCancelController extends GetxController {
late String _orderNum;
final BuildContext context;
String get orderNum => _orderNum; // 获取订单编号的方法
UserOrderCoinCancelController(this.context);
// 更新订单编号的方法
void updateOrderNum(String newOrderNum) {
_orderNum = newOrderNum;
}
late OrderInfoModel model;
// 应付款、订单编号等
List<OrderCompletedModel> orderAwaitings = [];
// 支付宝
Tobias tobias = Tobias();
// 微信
Fluwx fluwx = Fluwx();
late PayOrderModel payOrderModel;
dynamic _purchaseUpdatedSubscription;
dynamic _purchaseErrorSubscription;
dynamic _connectionSubscription;
PurchasedItem? _resultItem;
List<IAPItem> _items = [];
List<PurchasedItem> _purchases = [];
///未完成的订单
List<PurchasedItem> _pendingPurchases = [];
List<CoinModel> data = [];
@override
void onInit() {
if(Platform.isIOS){
_getProduct();
initPlatformState();
_getPendingPurchase();
}
super.onInit();
}
@override
void onReady() {
getOrderInfo();
super.onReady();
}
@override
void onClose() {
// controller.onRefresh();
if (_connectionSubscription != null) {
_connectionSubscription.cancel();
_connectionSubscription = null;
}
if (_purchaseUpdatedSubscription != null) {
_purchaseUpdatedSubscription.cancel();
_purchaseUpdatedSubscription = null;
}
if (_purchaseErrorSubscription != null) {
_purchaseErrorSubscription.cancel();
_purchaseErrorSubscription = null;
}
super.onClose();
}
Future<void> initPlatformState() async{
var result = await FlutterInappPurchase.instance.initialize();
print('--------------initPlatformState-------------------------$result');
_connectionSubscription = FlutterInappPurchase.connectionUpdated.listen((connected) {
print('connected: $connected');
});
_purchaseUpdatedSubscription = FlutterInappPurchase.purchaseUpdated.listen((productItem) {
CustomToast.dismiss();
if(productItem != null){
_resultItem = productItem;
requestOrderStatus();
}
});
_purchaseErrorSubscription = FlutterInappPurchase.purchaseError.listen((purchaseError) {
CustomToast.dismiss();
Toast.show(purchaseError!.message.toString());
});
}
/// 取消订单
Future<bool> cancelPay() async {
final result = await MineAPI.cancelPay(ordersnum: orderNum);
if (result) {
Toast.show('取消成功');
}
return result;
}
/// 获取订单信息
Future<void> getOrderInfo() async {
data.clear();
model = await MineAPI.getOrderInfo(orderNum: orderNum);
String payWay ='';
if(model.payType==1){
payWay='微信';
}else if(model.payType==2){
payWay='支付宝';
}else if(model.payType==3){
payWay='紫荆币';
}
orderAwaitings = [
OrderCompletedModel(name: '订单编号',value: model.ordersnum.toString()),
OrderCompletedModel(name: '支付方式',value: payWay),
OrderCompletedModel(name: '下单时间',value: model.createTime.toString()),
];
data.add(CoinModel(identifying:model.goodsId));
update();
}
/// 获取商品列表
Future _getProduct() async {
List<String> productList = data
.where((coinModel) => coinModel.identifying != null)
.map((coinModel) => coinModel.identifying!)
.toList();
print('-------------productList-------------------$productList');
List<IAPItem> items = await FlutterInappPurchase.instance.getProducts(productList);
for (var item in items) {
_items.add(item);
}
print('-------------_items-------------------$items');
_items = items;
_purchases = [];
// update();
}
Future<void> payOrder() async {
// 苹果支付
if (model.payType ==3){
// 发起苹果支付
IAPItem targetItem = _items.firstWhere(
(item) => item.productId == model.goodsId,
);
_requestPurchase(targetItem);
}
else{
payOrderModel = await MineAPI.getPayInfo(ordersNum: orderNum);
// 支付宝
if (model.payType == 2){
final result = await tobias.isAliPayInstalled;
if(!result){
Toast.show('请先安装支付宝');
}
else{
requestAliPay();
}
}
// 微信
else if (model.payType ==1){
final result = await fluwx.isWeChatInstalled;
if(!result){
Toast.show('请先安装微信');
}
else{
requestWechat();
}
}
}
}
// 苹果支付
void _requestPurchase(IAPItem item) {
CustomToast.loading();
FlutterInappPurchase.instance
.requestPurchase(item.productId!);
}
// 支付宝支付
void requestAliPay(){
Console.log('================================================================${payOrderModel.encryptionOrder!}');
tobias.pay(payOrderModel.encryptionOrder!).then((payResult){
if (payResult['resultStatus'] == '9000') {
requestOrderStatus();
} else {
Toast.show(payResult['memo'].toString());
}
});
}
// 微信支付
void requestWechat(){
Payment payment = Payment(
appId: payOrderModel.appid??'',
partnerId: payOrderModel.partnerid??'',
prepayId: payOrderModel.prepayid??'',
packageValue: payOrderModel.package??'',
nonceStr: payOrderModel.noncestr??'',
timestamp: payOrderModel.timestamp!.toInt(),
sign: payOrderModel.sign??''
);
fluwx.pay(which: payment);
fluwx.addSubscriber((response) {
if (response.errCode == 0) {
requestOrderStatus();
}
else{
Toast.show('${response.errStr}');
}
});
}
void requestOrderStatus() async {
final result = await ShopAPI.orderStatus(orderNumber: model.ordersnum??'',receipt:_resultItem != null?_resultItem!.transactionReceipt.toString():'');
if (result.paySuccess == 1){
Toast.show('订单支付完成');
if(context.mounted){
context.pop(true);
}
if (model.payType == 3){
// 清除
if (StorageService.to.getObject(kFailOrder) != null){
List<Map<String,String>> failOrderList = StorageService.to.getObject(kFailOrder) as List<Map<String, String>>;
List<Map<String,String>> temp = [];
temp.addAll(failOrderList);
for (var element in failOrderList) {
if(element['orderNum'] == result.ordersnum){
temp.remove(element);
}
}
StorageService.to.setObject(kFailOrder, temp);
}
FlutterInappPurchase.instance.finishTransactionIOS(_resultItem!.transactionId!);
}
}
else{
Toast.show('支付失败');
if (model.payType == 3){
// 保存未支付的订单
Map<String,String> failOrder = {
'orderNum':payOrderModel.ordersnum??'',
'transactionReceipt':_resultItem!.transactionReceipt.toString(),
'transactionId':_resultItem!.transactionId.toString()
};
List<Map> failOrderList = [];
failOrderList.add(failOrder);
StorageService.to.setObject(kFailOrder, failOrderList);
}
}
}
///获取未完成的购买
Future _getPendingPurchase() async {
List<PurchasedItem>? items = await FlutterInappPurchase.instance.getPurchaseHistory();
for (var item in items!) {
_pendingPurchases.add(item);
}
if(StorageService.to.getObject(kFailOrder) !=null){
List<Map<String,String>> failOrderList = StorageService.to.getObject(kFailOrder) as List<Map<String, String>>;
for (var item in _pendingPurchases) {
for (var element in failOrderList) {
if(element['transactionId'] == item.transactionId){
requestOrderStatus();
}
}
}
}
}
}
library user_order_coin_cancel;
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter_book/theme.dart';
import 'package:flutter_book/utils/index.dart';
import 'package:flutter_book/widgets/index.dart';
import 'package:flutter_inapp_purchase/flutter_inapp_purchase.dart';
import 'package:flutter_inapp_purchase/modules.dart';
import 'package:fluwx/fluwx.dart';
import 'package:get/get.dart';
import 'package:get/get_state_manager/src/simple/get_controllers.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get_state_manager/src/simple/get_state.dart';
import 'package:go_router/go_router.dart';
import 'package:tobias/tobias.dart';
import '../../apis/index.dart';
import '../../models/index.dart';
import '../../services/index.dart';
import '../user_order/index.dart';
part 'view.dart';
part 'controller.dart';
\ No newline at end of file
part of user_order_coin_cancel;
/// 紫荆币待支付
class UserOrderCoinCancelPage extends StatefulWidget {
final String orderNum; // 订单编号
const UserOrderCoinCancelPage({Key? key, required this.orderNum})
: super(key: key);
@override
State<UserOrderCoinCancelPage> createState() =>
_UserOrderCoinAwaitingState();
}
class _UserOrderCoinAwaitingState extends State<UserOrderCoinCancelPage> {
late UserOrderCoinCancelController myController;
@override
void initState() {
myController = Get.put(UserOrderCoinCancelController(context));
myController.updateOrderNum(widget.orderNum);
super.initState();
}
@override
Widget build(BuildContext context) {
return WillPopScope(
onWillPop: () async {
context.pop(true);
return false;
},
child: FutureBuilder(
future: myController.getOrderInfo(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return Scaffold(
appBar: AppBar(
centerTitle: true,
title: const Text('已取消'),
),
);
} else {
return WillPopScope(
onWillPop: () async {
context.pop(true);
return false;
},
child: Scaffold(
appBar: CustomAppBar(
title: const Text('已取消'),
actions: [],
),
body: Column(
children: [
Container(
margin: EdgeInsets.symmetric(
horizontal: AppTheme.margin,
vertical: AppTheme.margin),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8.w),
color: Colors.white,
boxShadow: [
BoxShadow(
color: Colours.cC7.withOpacity(0.5),
offset: Offset(3.w, 0),
blurRadius: 10.w,
spreadRadius: 0.w,
),
],
),
child: ClipRRect(
borderRadius: BorderRadius.circular(8.w),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
Padding(
padding: EdgeInsets.only(
left: 12.0.w,
top: 17.5.w,
bottom: 12.0.w),
child: Row(
mainAxisAlignment:
MainAxisAlignment.start,
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
Image.asset(
'assets/images/coin.png',
// fit: BoxFit.cover, // 设置适应方式为充满
width: 42.0.w,
height: 42.0.w,
),
Expanded(
child: Padding(
padding:
EdgeInsets.only(right: 16.5.w),
child: Column(
mainAxisAlignment:
MainAxisAlignment
.spaceBetween,
crossAxisAlignment:
CrossAxisAlignment.end,
// 下面的Text靠左
children: [
Text(
'充值${myController.model.bean}紫荆币',
style: TextStyle(
color: Colours.c3,
fontWeight: Fonts.bold,
fontSize: 13.w,
),
maxLines: 2,
overflow: TextOverflow
.ellipsis, // 超过部分显示省略号
),
SizedBox(height: 9.w),
// Text(
// "需付款 ¥${myController.model.finalTotalPrice}",
// style: TextStyle(
// color: Colours.cAB1941,
// fontWeight: Fonts.bold,
// fontSize: 14.w,
// ),
// ),
],
),
),
),
],
),
),
Container(
color: Colours.cLine,
margin: EdgeInsets.only(
left: 10.w, right: 10.w, bottom: 12.w),
height: 1.w,
),
Container(
padding: EdgeInsets.only(
left: 11.5.w,
bottom: 8.w,
right: 23.5.w),
child: Column(
mainAxisAlignment:
MainAxisAlignment.spaceEvenly,
children: myController.orderAwaitings
.map((model) {
return Padding(
padding: EdgeInsets.only(top: 12.w),
child: Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
Text(
model.name,
style: TextStyle(
fontSize: 13.w,
height: 1.6.w,
color: Colours.c9),
),
Text(
model.value.toString(),
style: TextStyle(
fontSize: 13.w,
height: 1.6.w,
color: Colours.c3),
),
],
),
);
}).toList(),
),
),
SizedBox(
height: 13.5.w,
),
],
),
),
),
SizedBox(
height: 11.5.w,
),
],
),
),
);
}
},
),
);
}
}
part of user_order_coin_completed;
/// 紫荆币等待付款订单
class UserOrderCoinCompletedController extends GetxController {
late String _orderNum;
final BuildContext context;
String get orderNum => _orderNum; // 获取订单编号的方法
UserOrderCoinCompletedController(this.context);
// 更新订单编号的方法
void updateOrderNum(String newOrderNum) {
_orderNum = newOrderNum;
}
late OrderInfoModel model;
// 应付款、订单编号等
List<OrderCompletedModel> orderAwaitings = [];
// 支付宝
Tobias tobias = Tobias();
// 微信
Fluwx fluwx = Fluwx();
late PayOrderModel payOrderModel;
dynamic _purchaseUpdatedSubscription;
dynamic _purchaseErrorSubscription;
dynamic _connectionSubscription;
PurchasedItem? _resultItem;
List<IAPItem> _items = [];
List<PurchasedItem> _purchases = [];
///未完成的订单
List<PurchasedItem> _pendingPurchases = [];
List<CoinModel> data = [];
@override
void onInit() {
if(Platform.isIOS){
_getProduct();
initPlatformState();
_getPendingPurchase();
}
super.onInit();
}
@override
void onReady() {
getOrderInfo();
super.onReady();
}
@override
void onClose() {
// controller.onRefresh();
if (_connectionSubscription != null) {
_connectionSubscription.cancel();
_connectionSubscription = null;
}
if (_purchaseUpdatedSubscription != null) {
_purchaseUpdatedSubscription.cancel();
_purchaseUpdatedSubscription = null;
}
if (_purchaseErrorSubscription != null) {
_purchaseErrorSubscription.cancel();
_purchaseErrorSubscription = null;
}
super.onClose();
}
Future<void> initPlatformState() async{
var result = await FlutterInappPurchase.instance.initialize();
print('--------------initPlatformState-------------------------$result');
_connectionSubscription = FlutterInappPurchase.connectionUpdated.listen((connected) {
print('connected: $connected');
});
_purchaseUpdatedSubscription = FlutterInappPurchase.purchaseUpdated.listen((productItem) {
CustomToast.dismiss();
if(productItem != null){
_resultItem = productItem;
requestOrderStatus();
}
});
_purchaseErrorSubscription = FlutterInappPurchase.purchaseError.listen((purchaseError) {
CustomToast.dismiss();
Toast.show(purchaseError!.message.toString());
});
}
/// 取消订单
Future<bool> cancelPay() async {
final result = await MineAPI.cancelPay(ordersnum: orderNum);
if (result) {
Toast.show('取消成功');
}
return result;
}
/// 获取订单信息
Future<void> getOrderInfo() async {
data.clear();
model = await MineAPI.getOrderInfo(orderNum: orderNum);
String payWay ='';
if(model.payType==1){
payWay='微信';
}else if(model.payType==2){
payWay='支付宝';
}else if(model.payType==3){
payWay='紫荆币';
}
orderAwaitings = [
OrderCompletedModel(name: '订单编号',value: model.ordersnum.toString()),
OrderCompletedModel(name: '支付方式',value: payWay),
OrderCompletedModel(name: '支付时间',value: model.payTime.toString()),
OrderCompletedModel(name: '下单时间',value: model.createTime.toString()),
];
data.add(CoinModel(identifying:model.goodsId));
update();
}
/// 获取商品列表
Future _getProduct() async {
List<String> productList = data
.where((coinModel) => coinModel.identifying != null)
.map((coinModel) => coinModel.identifying!)
.toList();
print('-------------productList-------------------$productList');
List<IAPItem> items = await FlutterInappPurchase.instance.getProducts(productList);
for (var item in items) {
_items.add(item);
}
print('-------------_items-------------------$items');
_items = items;
_purchases = [];
// update();
}
Future<void> payOrder() async {
// 苹果支付
if (model.payType ==3){
// 发起苹果支付
IAPItem targetItem = _items.firstWhere(
(item) => item.productId == model.goodsId,
);
_requestPurchase(targetItem);
}
else{
payOrderModel = await MineAPI.getPayInfo(ordersNum: orderNum);
// 支付宝
if (model.payType == 2){
final result = await tobias.isAliPayInstalled;
if(!result){
Toast.show('请先安装支付宝');
}
else{
requestAliPay();
}
}
// 微信
else if (model.payType ==1){
final result = await fluwx.isWeChatInstalled;
if(!result){
Toast.show('请先安装微信');
}
else{
requestWechat();
}
}
}
}
// 苹果支付
void _requestPurchase(IAPItem item) {
CustomToast.loading();
FlutterInappPurchase.instance
.requestPurchase(item.productId!);
}
// 支付宝支付
void requestAliPay(){
Console.log('================================================================${payOrderModel.encryptionOrder!}');
tobias.pay(payOrderModel.encryptionOrder!).then((payResult){
if (payResult['resultStatus'] == '9000') {
requestOrderStatus();
} else {
Toast.show(payResult['memo'].toString());
}
});
}
// 微信支付
void requestWechat(){
Payment payment = Payment(
appId: payOrderModel.appid??'',
partnerId: payOrderModel.partnerid??'',
prepayId: payOrderModel.prepayid??'',
packageValue: payOrderModel.package??'',
nonceStr: payOrderModel.noncestr??'',
timestamp: payOrderModel.timestamp!.toInt(),
sign: payOrderModel.sign??''
);
fluwx.pay(which: payment);
fluwx.addSubscriber((response) {
if (response.errCode == 0) {
requestOrderStatus();
}
else{
Toast.show('${response.errStr}');
}
});
}
void requestOrderStatus() async {
final result = await ShopAPI.orderStatus(orderNumber: model.ordersnum??'',receipt:_resultItem != null?_resultItem!.transactionReceipt.toString():'');
if (result.paySuccess == 1){
Toast.show('订单支付完成');
if(context.mounted){
context.pop(true);
}
if (model.payType == 3){
// 清除
if (StorageService.to.getObject(kFailOrder) != null){
List<Map<String,String>> failOrderList = StorageService.to.getObject(kFailOrder) as List<Map<String, String>>;
List<Map<String,String>> temp = [];
temp.addAll(failOrderList);
for (var element in failOrderList) {
if(element['orderNum'] == result.ordersnum){
temp.remove(element);
}
}
StorageService.to.setObject(kFailOrder, temp);
}
FlutterInappPurchase.instance.finishTransactionIOS(_resultItem!.transactionId!);
}
}
else{
Toast.show('支付失败');
if (model.payType == 3){
// 保存未支付的订单
Map<String,String> failOrder = {
'orderNum':payOrderModel.ordersnum??'',
'transactionReceipt':_resultItem!.transactionReceipt.toString(),
'transactionId':_resultItem!.transactionId.toString()
};
List<Map> failOrderList = [];
failOrderList.add(failOrder);
StorageService.to.setObject(kFailOrder, failOrderList);
}
}
}
///获取未完成的购买
Future _getPendingPurchase() async {
List<PurchasedItem>? items = await FlutterInappPurchase.instance.getPurchaseHistory();
for (var item in items!) {
_pendingPurchases.add(item);
}
if(StorageService.to.getObject(kFailOrder) !=null){
List<Map<String,String>> failOrderList = StorageService.to.getObject(kFailOrder) as List<Map<String, String>>;
for (var item in _pendingPurchases) {
for (var element in failOrderList) {
if(element['transactionId'] == item.transactionId){
requestOrderStatus();
}
}
}
}
}
}
library user_order_coin_completed;
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter_book/theme.dart';
import 'package:flutter_book/utils/index.dart';
import 'package:flutter_book/widgets/index.dart';
import 'package:flutter_inapp_purchase/flutter_inapp_purchase.dart';
import 'package:flutter_inapp_purchase/modules.dart';
import 'package:fluwx/fluwx.dart';
import 'package:get/get.dart';
import 'package:get/get_state_manager/src/simple/get_controllers.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get_state_manager/src/simple/get_state.dart';
import 'package:go_router/go_router.dart';
import 'package:tobias/tobias.dart';
import '../../apis/index.dart';
import '../../models/index.dart';
import '../../services/index.dart';
import '../user_order/index.dart';
part 'view.dart';
part 'controller.dart';
\ No newline at end of file
part of user_order_coin_completed;
/// 紫荆币待支付
class UserOrderCoinCompletedPage extends StatefulWidget {
final String orderNum; // 订单编号
const UserOrderCoinCompletedPage({Key? key, required this.orderNum})
: super(key: key);
@override
State<UserOrderCoinCompletedPage> createState() =>
_UserOrderCoinAwaitingState();
}
class _UserOrderCoinAwaitingState extends State<UserOrderCoinCompletedPage> {
late UserOrderCoinCompletedController myController;
@override
void initState() {
myController = Get.put(UserOrderCoinCompletedController(context));
myController.updateOrderNum(widget.orderNum);
super.initState();
}
@override
Widget build(BuildContext context) {
return WillPopScope(
onWillPop: () async {
context.pop(true);
return false;
},
child: FutureBuilder(
future: myController.getOrderInfo(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return Scaffold(
appBar: AppBar(
centerTitle: true,
title: const Text('已完成'),
),
);
} else {
return WillPopScope(
onWillPop: () async {
context.pop(true);
return false;
},
child: Scaffold(
appBar: CustomAppBar(
title: const Text('已完成'),
actions: [],
),
body: Column(
children: [
Container(
margin: EdgeInsets.symmetric(
horizontal: AppTheme.margin,
vertical: AppTheme.margin),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8.w),
color: Colors.white,
boxShadow: [
BoxShadow(
color: Colours.cC7.withOpacity(0.5),
offset: Offset(3.w, 0),
blurRadius: 10.w,
spreadRadius: 0.w,
),
],
),
child: ClipRRect(
borderRadius: BorderRadius.circular(8.w),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
Padding(
padding: EdgeInsets.only(
left: 12.0.w,
top: 17.5.w,
bottom: 12.0.w),
child: Row(
mainAxisAlignment:
MainAxisAlignment.start,
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
Image.asset(
'assets/images/coin.png',
// fit: BoxFit.cover, // 设置适应方式为充满
width: 42.0.w,
height: 42.0.w,
),
Expanded(
child: Padding(
padding:
EdgeInsets.only(right: 16.5.w),
child: Column(
mainAxisAlignment:
MainAxisAlignment
.spaceBetween,
crossAxisAlignment:
CrossAxisAlignment.end,
// 下面的Text靠左
children: [
Text(
'充值${myController.model.bean}紫荆币',
style: TextStyle(
color: Colours.c3,
fontWeight: Fonts.bold,
fontSize: 13.w,
),
maxLines: 2,
overflow: TextOverflow
.ellipsis, // 超过部分显示省略号
),
SizedBox(height: 9.w),
// Text(
// "需付款 ¥${myController.model.finalTotalPrice}",
// style: TextStyle(
// color: Colours.cAB1941,
// fontWeight: Fonts.bold,
// fontSize: 14.w,
// ),
// ),
],
),
),
),
],
),
),
Container(
color: Colours.cLine,
margin: EdgeInsets.only(
left: 10.w, right: 10.w, bottom: 12.w),
height: 1.w,
),
Container(
padding: EdgeInsets.only(
left: 11.5.w,
bottom: 8.w,
right: 23.5.w),
child: Column(
mainAxisAlignment:
MainAxisAlignment.spaceEvenly,
children: myController.orderAwaitings
.map((model) {
return Padding(
padding: EdgeInsets.only(top: 12.w),
child: Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
Text(
model.name,
style: TextStyle(
fontSize: 13.w,
height: 1.6.w,
color: Colours.c9),
),
Text(
model.value.toString(),
style: TextStyle(
fontSize: 13.w,
height: 1.6.w,
color: Colours.c3),
),
],
),
);
}).toList(),
),
),
SizedBox(
height: 13.5.w,
),
],
),
),
),
SizedBox(
height: 11.5.w,
),
],
),
),
);
}
},
),
);
}
}
...@@ -36,6 +36,8 @@ import 'package:flutter_book/pages/user_notes/index.dart'; ...@@ -36,6 +36,8 @@ import 'package:flutter_book/pages/user_notes/index.dart';
import 'package:flutter_book/pages/user_notes_des/index.dart'; import 'package:flutter_book/pages/user_notes_des/index.dart';
import 'package:flutter_book/pages/user_order_awaiting/index.dart'; import 'package:flutter_book/pages/user_order_awaiting/index.dart';
import 'package:flutter_book/pages/user_order_coin_awaiting/index.dart'; import 'package:flutter_book/pages/user_order_coin_awaiting/index.dart';
import 'package:flutter_book/pages/user_order_coin_cancel/index.dart';
import 'package:flutter_book/pages/user_order_coin_completed/index.dart';
import 'package:flutter_book/pages/user_order_completed/index.dart'; import 'package:flutter_book/pages/user_order_completed/index.dart';
import 'package:flutter_book/pages/user_order_refunded/index.dart'; import 'package:flutter_book/pages/user_order_refunded/index.dart';
import 'package:flutter_book/pages/user_point/index.dart'; import 'package:flutter_book/pages/user_point/index.dart';
......
...@@ -122,6 +122,10 @@ abstract class Routes { ...@@ -122,6 +122,10 @@ abstract class Routes {
static const orderCancel= 'order_cancel'; static const orderCancel= 'order_cancel';
// 紫荆币待付款订单 // 紫荆币待付款订单
static const orderCoinAwaiting= 'order_coin_awaiting'; static const orderCoinAwaiting= 'order_coin_awaiting';
// 紫荆币已取消订单
static const orderCoinCancel= 'order_coin_cancel';
// 紫荆币已完成订单
static const orderCoinCompleted= 'order_coin_completed';
// 已退款订单 // 已退款订单
static const orderRefunded= 'order_refunded'; static const orderRefunded= 'order_refunded';
// 搜索订单 // 搜索订单
...@@ -587,6 +591,24 @@ abstract class Routes { ...@@ -587,6 +591,24 @@ abstract class Routes {
child: UserOrderCoinAwaitingPage(orderNum: state.uri.queryParameters['orderNum'].toString()) child: UserOrderCoinAwaitingPage(orderNum: state.uri.queryParameters['orderNum'].toString())
) )
), ),
GoRoute( // 紫荆币已取消订单
path: '/$orderCoinCancel',
name: orderCoinCancel,
pageBuilder: (context, state) =>CupertinoPage(
name: state.uri.toString(),
key: state.pageKey,
child: UserOrderCoinCancelPage(orderNum: state.uri.queryParameters['orderNum'].toString())
)
),
GoRoute( // 紫荆币已完成订单
path: '/$orderCoinCompleted',
name: orderCoinCompleted,
pageBuilder: (context, state) =>CupertinoPage(
name: state.uri.toString(),
key: state.pageKey,
child: UserOrderCoinCompletedPage(orderNum: state.uri.queryParameters['orderNum'].toString())
)
),
GoRoute( // 已退款订单 GoRoute( // 已退款订单
path: '/$orderRefunded', path: '/$orderRefunded',
name: orderRefunded, name: orderRefunded,
......
...@@ -38,9 +38,11 @@ class HttpService extends GetxService { ...@@ -38,9 +38,11 @@ class HttpService extends GetxService {
} else{ } else{
headers['Authorization'] = ''; headers['Authorization'] = '';
} }
Map<String,dynamic>? tempParams = {};
if (params != null) { if (params != null) {
params.addAll(headers); tempParams.addAll(params);
headers['Sign'] = SignTool.createSign(params!); tempParams.addAll(headers);
headers['Sign'] = SignTool.createSign(tempParams);
} }
else { else {
headers['Sign'] = SignTool.createSign(headers); headers['Sign'] = SignTool.createSign(headers);
...@@ -57,7 +59,7 @@ class HttpService extends GetxService { ...@@ -57,7 +59,7 @@ class HttpService extends GetxService {
CancelToken? cancelToken, CancelToken? cancelToken,
bool excludeToken = false, bool excludeToken = false,
bool showLoading = false, bool showLoading = false,
bool cacheEnabled = false, bool cacheEnabled = true,
}) async { }) async {
if (showLoading) CustomToast.loading(); if (showLoading) CustomToast.loading();
try { try {
...@@ -235,13 +237,13 @@ class _RequestInterceptor extends Interceptor { ...@@ -235,13 +237,13 @@ class _RequestInterceptor extends Interceptor {
case DioExceptionType.badResponse: case DioExceptionType.badResponse:
final response = err.response; final response = err.response;
final statusCode = response?.statusCode; final statusCode = response?.statusCode;
print('************* ${response?.data}'); Console.log('************* ${response?.data}');
print('******statusCode******* $statusCode'); Console.log('******statusCode******* $statusCode');
// Console.log(response?.data); // Console.log(response?.data);
var msg = '服务器错误'; var msg = '服务器错误';
switch (statusCode) { switch (statusCode) {
case 403: case 403:
print('----------403---------access_token-------------------------${UserStore.to.accessToken}--------------------'); Console.log('----------403---------access_token-------------------------${UserStore.to.accessToken}--------------------');
msg = '$statusCode - Unauthorized'; msg = '$statusCode - Unauthorized';
final newToken = await refreshToken(); final newToken = await refreshToken();
if (newToken != null) { if (newToken != null) {
...@@ -269,7 +271,7 @@ class _RequestInterceptor extends Interceptor { ...@@ -269,7 +271,7 @@ class _RequestInterceptor extends Interceptor {
} else { } else {
UserStore.to.logout(); UserStore.to.logout();
CustomToast.fail('登录已失效,请重新登录'); CustomToast.fail('登录已失效,请重新登录');
print('-------------------access_token-------------------------${UserStore.to.accessToken}--------------------'); Console.log('-------------------access_token-------------------------${UserStore.to.accessToken}--------------------');
} }
break; break;
...@@ -337,13 +339,14 @@ class _CacheInterceptor extends Interceptor { ...@@ -337,13 +339,14 @@ class _CacheInterceptor extends Interceptor {
@override @override
void onRequest(RequestOptions options, RequestInterceptorHandler handler) async { void onRequest(RequestOptions options, RequestInterceptorHandler handler) async {
final cacheEnabled = options.extra?['cacheEnabled'] ?? false; final cacheEnabled = options.extra['cacheEnabled'] ?? false;
final status = await Tools.checkCurrentNetStatus(); final status = await Tools.checkCurrentNetStatus();
if (cacheEnabled && !status) { if (cacheEnabled && !status) {
// 在发起请求之前,检查缓存是否存在有效数据 // 在发起请求之前,检查缓存是否存在有效数据
final cachedFile = await DefaultCacheManager().getFileFromCache(options.uri.toString()); String cacheKey = options.data.isEmpty ? options.uri.toString() : '${options.uri.toString()}?${options.data}';
final cachedFile = await DefaultCacheManager().getFileFromCache(cacheKey);
if (cachedFile != null && cachedFile.validTill.isAfter(DateTime.now())) { if (cachedFile != null && cachedFile.validTill.isAfter(DateTime.now())) {
Console.log('--------------使用缓存数据------------------'); Console.log('-获取数据cachedFile------------------------------$cachedFile-');
// 如果缓存有效,直接返回缓存数据 // 如果缓存有效,直接返回缓存数据
final cachedData = await cachedFile.file.readAsBytes(); final cachedData = await cachedFile.file.readAsBytes();
final decodedData = utf8.decode(cachedData); // 将字节列表解码为字符串 final decodedData = utf8.decode(cachedData); // 将字节列表解码为字符串
...@@ -371,7 +374,7 @@ class _CacheInterceptor extends Interceptor { ...@@ -371,7 +374,7 @@ class _CacheInterceptor extends Interceptor {
final requestBody = response.requestOptions.data.toString(); final requestBody = response.requestOptions.data.toString();
// 将 GET 请求的参数和请求体参数拼接成缓存的键 // 将 GET 请求的参数和请求体参数拼接成缓存的键
final cacheKey = requestBody.isEmpty ? url : '$url?$requestBody'; final cacheKey = requestBody.isEmpty ? url : '$url?$requestBody';
// Console.log('----------cacheKey-----------------------$cacheKey'); Console.log('----------cacheKey-----------------------$cacheKey');
// 将响应数据转换为字符串,并将其编码为字节列表 // 将响应数据转换为字符串,并将其编码为字节列表
List<int> bytes = utf8.encode(jsonEncode(response.data)); List<int> bytes = utf8.encode(jsonEncode(response.data));
Uint8List uint8List = Uint8List.fromList(bytes); Uint8List uint8List = Uint8List.fromList(bytes);
......
...@@ -3,8 +3,8 @@ part of utils; ...@@ -3,8 +3,8 @@ part of utils;
// 服务器地址 // 服务器地址
// const String kServerUrl = 'https://app.vning.com'; // const String kServerUrl = 'https://app.vning.com';
// const String kServerUrl = 'http://192.168.11.88:81'; // const String kServerUrl = 'http://192.168.11.88:81';
const String kServerUrl = 'http://8.141.148.247:7421'; // const String kServerUrl = 'http://8.141.148.247:7421';
// const String kServerUrl = 'http://1507.superge.cn:81'; const String kServerUrl = 'http://1507.superge.cn:81';
const String kLocalToken = 'local_token'; const String kLocalToken = 'local_token';
const String kLocalAccessToken = 'local_access_token'; const String kLocalAccessToken = 'local_access_token';
const String kLocalAccount = 'local_account'; const String kLocalAccount = 'local_account';
...@@ -19,13 +19,13 @@ const String kUserPriAgreement = '/html/agreement/pri_agreement.html'; ...@@ -19,13 +19,13 @@ const String kUserPriAgreement = '/html/agreement/pri_agreement.html';
const String kUserRechargeAgreement = '/html/agreement/rec_agreement.html'; const String kUserRechargeAgreement = '/html/agreement/rec_agreement.html';
// 错题详情页 html // 错题详情页 html
const String kUserWrongDes = '$kServerUrl/html/app/evaluating_wrong.html'; const String kUserWrongDes = 'http://150.158.138.40:9200/evaluating_wrong.html';
// 阅读页 html // 阅读页 html
const String kReadBook = '$kServerUrl/html/app/read.html'; const String kReadBook = 'http://150.158.138.40:9200/read.html';
// 答题页 // 答题页
const String kAnswer = '$kServerUrl/html/app/evaluating.html'; const String kAnswer = 'http://150.158.138.40:9200/evaluating.html';
// 答题结果页 // 答题结果页
const String kAnswerResult = '$kServerUrl/html/app/evaluating_result.html'; const String kAnswerResult = 'http://150.158.138.40:9200/evaluating_result.html';
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论