diff --git a/assets/image/2x/home_coupon.png b/assets/image/2x/home_coupon.png new file mode 100644 index 00000000..ae9a63ca Binary files /dev/null and b/assets/image/2x/home_coupon.png differ diff --git a/assets/image/2x/home_order.png b/assets/image/2x/home_order.png new file mode 100644 index 00000000..33612170 Binary files /dev/null and b/assets/image/2x/home_order.png differ diff --git a/assets/image/2x/home_recharge.png b/assets/image/2x/home_recharge.png new file mode 100644 index 00000000..9f8380c8 Binary files /dev/null and b/assets/image/2x/home_recharge.png differ diff --git a/assets/image/3x/home_coupon.png b/assets/image/3x/home_coupon.png new file mode 100644 index 00000000..7e2d35e6 Binary files /dev/null and b/assets/image/3x/home_coupon.png differ diff --git a/assets/image/3x/home_order.png b/assets/image/3x/home_order.png new file mode 100644 index 00000000..715c6bb0 Binary files /dev/null and b/assets/image/3x/home_order.png differ diff --git a/assets/image/3x/home_recharge.png b/assets/image/3x/home_recharge.png new file mode 100644 index 00000000..fe963e61 Binary files /dev/null and b/assets/image/3x/home_recharge.png differ diff --git a/assets/image/home_coupon.png b/assets/image/home_coupon.png new file mode 100644 index 00000000..e19036ef Binary files /dev/null and b/assets/image/home_coupon.png differ diff --git a/assets/image/home_order.png b/assets/image/home_order.png new file mode 100644 index 00000000..861a96f7 Binary files /dev/null and b/assets/image/home_order.png differ diff --git a/assets/image/home_recharge.png b/assets/image/home_recharge.png new file mode 100644 index 00000000..a86370de Binary files /dev/null and b/assets/image/home_recharge.png differ diff --git a/lib/community/community_course.dart b/lib/community/community_course.dart index da083281..1da62710 100644 --- a/lib/community/community_course.dart +++ b/lib/community/community_course.dart @@ -9,6 +9,8 @@ import 'package:huixiang/retrofit/data/base_data.dart'; import 'package:huixiang/retrofit/data/brand.dart'; import 'package:huixiang/retrofit/data/brand_data.dart'; import 'package:huixiang/retrofit/data/category_select_list.dart'; +import 'package:huixiang/retrofit/data/collect_class_list.dart'; +import 'package:huixiang/retrofit/data/course_details.dart'; import 'package:huixiang/retrofit/data/course_list.dart'; import 'package:huixiang/retrofit/data/page.dart'; import 'package:huixiang/retrofit/retrofit_api.dart'; @@ -45,6 +47,8 @@ class _CommunityCourse extends State List classSelectList = []; List classList = []; List classTabList = []; + List collectList = []; + List collect = []; int checkIndex = 0; @override @@ -58,10 +62,13 @@ class _CommunityCourse extends State } }); classListAsync(); + collectionList(); + // courseDetails("1451753512101740544"); } ///课程分类列表 - classListAsync() async { + classListAsync() async + { if (apiService == null) { SharedPreferences value = await SharedPreferences.getInstance(); apiService = ApiService( @@ -122,6 +129,48 @@ class _CommunityCourse extends State } } + ///课程的合集列表 + collectionList() async { + if (apiService == null) { + SharedPreferences value = await SharedPreferences.getInstance(); + apiService = ApiService( + Dio(), + context: context, + token: value.getString("token"), + ); + } + BaseData> baseData = await apiService.collectList().catchError((onError) {}); + if (baseData != null && baseData.isSuccess) { + setState(() { + collectList.clear(); + collectList.addAll(baseData.data); + if(collectList.length > 0) + collectCourse(collectList[0].id); + }); + } + EasyLoading.dismiss(); + } + + ///合集包含的课程列表 + collectCourse(collectId) async { + if (apiService == null) { + SharedPreferences value = await SharedPreferences.getInstance(); + apiService = ApiService( + Dio(), + context: context, + token: value.getString("token"), + ); + } + BaseData> baseData = await apiService.collect(collectId).catchError((error) { + }); + if (baseData != null && baseData.isSuccess) { + setState(() { + collect.clear(); + collect.addAll(baseData.data); + }); + } + } + _onRefresh(){ classListAsync(); } @@ -188,9 +237,7 @@ class _CommunityCourse extends State SizedBox(height: 28), ///回乡小课堂 - HomeClass(classList), - - SizedBox(height: 28), + HomeClass(collect,collectList), ///课程导航栏 ClassTitleTab(classSelectList,(index){ @@ -203,32 +250,9 @@ class _CommunityCourse extends State ]; - // if (brands == null) return widgets; - // brands.forEach((value) { - // widgets.add( - // Container( - // key: globaKeys[brands.indexOf(value)], - // child: Container( - // child: Html( - // data: value.content, - // customImageRenders: { - // assetUriMatcher(): assetImageRender(), - // networkSourceMatcher(extension: "svg"): svgNetworkImageRender(), - // networkSourceMatcher(): networkImageRender( - // loadingWidget: () { - // return Container(); - // }, - // ), - // }, - // ), - // ), - // ), - // ); - // }); return widgets; } - @override bool get wantKeepAlive => true; } diff --git a/lib/community/community_view/class_details.dart b/lib/community/community_view/class_details.dart new file mode 100644 index 00000000..376645f9 --- /dev/null +++ b/lib/community/community_view/class_details.dart @@ -0,0 +1,634 @@ +import 'package:chewie/chewie.dart'; +import 'package:dio/dio.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_easyloading/flutter_easyloading.dart'; +import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; +import 'package:huixiang/generated/l10n.dart'; +import 'package:huixiang/retrofit/data/base_data.dart'; +import 'package:huixiang/retrofit/data/chapter.dart'; +import 'package:huixiang/retrofit/data/course_details.dart'; +import 'package:huixiang/retrofit/data/member_comment_list.dart'; +import 'package:huixiang/retrofit/data/page.dart'; +import 'package:huixiang/retrofit/retrofit_api.dart'; +import 'package:huixiang/utils/font_weight.dart'; +import 'package:huixiang/view_widget/custom_image.dart'; +import 'package:chewie/src/chewie_progress_colors.dart' as chewie; +import 'package:huixiang/view_widget/tips_dialog.dart'; +import 'package:huixiang/web/web_view/comment_list.dart'; +import 'package:huixiang/web/web_view/input_comment.dart'; +import 'package:shared_preferences/shared_preferences.dart'; +import 'package:video_player/video_player.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; + +class ClassDetails extends StatefulWidget { + final Map arguments; + + ClassDetails({this.arguments}); + @override + State createState() { + return _ClassDetails(); + } +} + +class _ClassDetails extends State with WidgetsBindingObserver{ + VideoPlayerController videoPlayerController; + Chewie chewies; + ChewieController chewieAudioController; + ApiService apiService; + final GlobalKey commentKey = GlobalKey(); + final ScrollController scrollController = ScrollController(); + bool isKeyBoardShow = false; + var commentFocus = FocusNode(); + String parenId = "0"; + String hintText = S.current.liuxianinjingcaidepinglunba; + List memberList = []; + final GlobalKey inputKey = GlobalKey(); + final TextEditingController commentTextController = TextEditingController(); + int commentTotal = 0; + double commentHeight = 60.h; + CourseDetails course; + List chapterList = []; + bool isShowImg = true; + int chapterIndex = 0; + + @override + void initState() { + super.initState(); + WidgetsBinding.instance.addObserver(this); + courseDetails(widget.arguments["id"]); + queryChapterList(widget.arguments["id"]); + } + + ///课程章节列表 + queryChapterList(courseId) async { + if (apiService == null) { + SharedPreferences value = await SharedPreferences.getInstance(); + apiService = ApiService( + Dio(), + context: context, + token: value.getString("token"), + ); + } + BaseData> baseData = await apiService.catalogList(courseId).catchError((onError) {}); + if (baseData != null && baseData.isSuccess) { + setState(() { + chapterList.clear(); + chapterList.addAll(baseData.data); + chapterIndex = 0; + initVideo(chapterList[chapterIndex].content.fileUrl); + }); + + } + EasyLoading.dismiss(); + } + + ///课程详情 + courseDetails(id) async { + if (apiService == null) { + SharedPreferences value = await SharedPreferences.getInstance(); + apiService = ApiService( + Dio(), + context: context, + token: value.getString("token"), + ); + } + BaseData baseData = await apiService.course(id).catchError((error) {}); + if (baseData != null && baseData.isSuccess) { + setState(() { + course = baseData.data; + }); + } + } + + + @override + void dispose() { + /** + * 页面销毁时,视频播放器也销毁 + */ + + if (chewieAudioController != null) { + chewieAudioController.pause(); + chewieAudioController.dispose(); + chewieAudioController = null; + } + if (videoPlayerController != null) { + videoPlayerController.pause(); + videoPlayerController.dispose(); + } + super.dispose(); + } + + @override + void didChangeMetrics() { + WidgetsBinding.instance.addPostFrameCallback((_) { + if (!mounted) return; + if (MediaQuery + .of(context) + .viewInsets + .bottom == 0) { + if (isKeyBoardShow) { + FocusScope.of(context).requestFocus(FocusNode()); + if (mounted) + setState(() { + hintText = S.current.liuxianinjingcaidepinglunba; + isKeyBoardShow = false; + }); + } + } else { + if (mounted) + setState(() { + isKeyBoardShow = true; + }); + } + }); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + body: Container( + child: SingleChildScrollView( + physics: BouncingScrollPhysics(), + child: Column( + children: [ + Stack( + children: [ + videoWidget( + MediaQuery.of(context).size.width, + videoPlayerController != null + ? (MediaQuery.of(context).size.width) / + videoPlayerController.value.aspectRatio + : MediaQuery.of(context).size.width / 2, + chapterList.length>chapterIndex?chapterList[chapterIndex].content.coverImg:"", + ), + Container( + margin: EdgeInsets.only(top: 40.h, left: 16.w, right: 16.w), + decoration: BoxDecoration( + color: Colors.transparent, + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + GestureDetector( + child: Icon( + Icons.arrow_back_ios, + color: Colors.white, + size: 24, + ), + onTap: () { + Navigator.of(context).pop(); + }, + ), + ], + ), + ), + ], + ), + Container( + height: 123, + margin: EdgeInsets.only(bottom: 16.h), + padding: EdgeInsets.only(left: 16,top: 16,right: 10), + decoration: BoxDecoration( + color: Colors.white, + boxShadow: [ + BoxShadow( + color: Colors.black.withAlpha(12), + offset: Offset(0, 2), + blurRadius: 14, + spreadRadius: 0, + ) + ], + ), + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + Container( + height: 22.h, + width: 40.w, + alignment: Alignment.center, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(2), + border: Border.all( + width: 1, + color: Color(0xFFFF7A1A), + style: BorderStyle.solid, + ), + ), + child: Text( + ( course?.tags != null && course.tags.length > 0 )?course.tags[0] : "", + style: TextStyle( + fontSize: 14.sp, + fontWeight: MyFontWeight.medium, + color: Color(0xFFFF7A1A), + ), + ), + ), + SizedBox( + width: 6.w, + ), + Expanded( + child: Text( + course != null ?course.subject:"", + overflow: TextOverflow.ellipsis, + maxLines: 2, + style: TextStyle( + fontSize: 16.sp, + fontWeight: MyFontWeight.semi_bold, + color: Color(0xFF1A1A1A), + ), + ), + flex: 1, + ) + ], + ), + SizedBox( + height:10.h, + ), + Padding(padding: EdgeInsets.only(right: 16), + child: Row( + children: [ + Expanded( + child: Text( + "讲师:${course !=null ? course.author.name :""}", + overflow: TextOverflow.ellipsis, + maxLines: 2, + style: TextStyle( + fontSize: 12.sp, + fontWeight: MyFontWeight.regular, + color: Colors.black, + ), + )), + Text( + "播放次数", + overflow: TextOverflow.ellipsis, + maxLines: 2, + style: TextStyle( + fontSize: 12.sp, + fontWeight: MyFontWeight.regular, + color: Color(0xFF808080), + ), + ), + SizedBox( + width:4, + ), + Text( + course != null ? course.viewers.toString() :"", + overflow: TextOverflow.ellipsis, + maxLines: 2, + style: TextStyle( + fontSize: 12.sp, + fontWeight: MyFontWeight.regular, + color: Color(0xFF808080), + ), + ), + ], + ),), + SizedBox( + height:10.h, + ), + Text( + course != null ?course.introduce:"", + overflow: TextOverflow.ellipsis, + maxLines: 2, + style: TextStyle( + fontSize: 12.sp, + fontWeight: MyFontWeight.regular, + color: Colors.black, + ), + ), + ], + ), + ), + anthology(), + CommentList( + commentKey, + course?.likes ?? course?.likes?? 0, + course?.id ?? course?.id ??"", + isKeyBoardShow, + _reply, + _delCommentTips, + 12.sp, + ), + if (memberList == null || memberList.length == 0) + Container( + width: double.infinity, + alignment: Alignment.topCenter, + margin: EdgeInsets.only(top: 40), + padding: EdgeInsets.all(22.h), + child: Text( + S + .of(context) + .zanwupinglun, + style: TextStyle( + fontSize: 12, + fontWeight: FontWeight.bold, + color: Color(0xFFA0A0A0), + ), + ), + ), + /// 富文本评论的输入框 + InputComment( + inputKey, + hintText, + isKeyBoardShow, + commentFocus, + commentTextController, + _toComment, + _queryMemberComment, + _queryInformationLikes, + isLike: false, + ), + ], + ), + ), + ), + ); + } + + initVideo(videoUrl) async { + videoPlayerController = VideoPlayerController.network( + videoUrl, + )..initialize().then((value) { + chewieAudioController = ChewieController( + videoPlayerController: videoPlayerController, + aspectRatio: videoPlayerController.value.aspectRatio, + //宽高比 + autoPlay: false, + //自动播放 + looping: false, + //循环播放 + allowFullScreen: true, + // 拖动条样式颜色 + materialProgressColors: chewie.ChewieProgressColors( + playedColor: Colors.white, + handleColor: Colors.white, + backgroundColor: Colors.grey, + bufferedColor: Colors.transparent, + ), + autoInitialize: true, + ); + chewieAudioController.addListener(_fullScreenListener); + if (mounted) setState(() {}); + }); + } + + Future _fullScreenListener() async { + if (!chewieAudioController.isFullScreen) { + Future.delayed(Duration(seconds: 1), () { + }); + } + } + + Widget videoWidget(double width, double height, src) { + print("src : $src"); + return MediaQuery( + data: MediaQuery.of(context).copyWith( + textScaleFactor: 0.9, + ), + child: !isShowImg + ? (chewieAudioController != null + ? Container( + width: width, + height: height, + child: chewies = Chewie( + controller: chewieAudioController, + ), + ) + : Container( + width: width, + height: height, + )) + : GestureDetector( + onTap: (){ + setState(() { + isShowImg = false; + }); + }, + child: Container( + width: width, + height: width / 7 * 5, + color: Colors.black, + child: Stack( + children: [ + Center( + child: MImage( + src, + fit: BoxFit.cover, + errorSrc: "assets/image/default_2_1.png", + fadeSrc: "assets/image/default_2_1.png", + ), + ), + Center( + child: Icon( + Icons.play_circle_outline, + color: Colors.white, + size: 60, + ), + ), + ], + ), + ), + ), + ); + } + + Widget anthology() { + return Container( + color: Colors.white, + margin: EdgeInsets.only(bottom: 16), + padding: EdgeInsets.all(16), + child: Column( + children: [ + Row( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + "选集", + style: TextStyle( + fontSize: 15.sp, + fontWeight: MyFontWeight.medium, + color: Color(0xFF1A1A1A), + ), + ), + Text( + "共${chapterList.length}集", + style: TextStyle( + fontSize: 16.sp, + fontWeight: MyFontWeight.regular, + color: Color(0xFF1A1A1A), + ), + ), + ], + ), + Container( + height: 70.h, + margin: EdgeInsets.only(top:10), + child: ListView.builder( + scrollDirection: Axis.horizontal, + physics: BouncingScrollPhysics(), + itemCount:chapterList.length, + itemBuilder: (context, position) { + return GestureDetector( + onTap: () { + setState(() { + chapterIndex = position; + isShowImg = true; + initVideo(chapterList[position].content.fileUrl); + }); + }, + child: classSelectItem(chapterList[position],position), + ); + }, + ), + ), + ], + ), + ); + } + + Widget classSelectItem(Chapter chapterList,position) { + return Container( + width: 106.w, + alignment: Alignment.center, + margin: EdgeInsets.symmetric( + horizontal: 6.w, + vertical: 3, + ), + padding: EdgeInsets.all(8), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(4), + color: position==chapterIndex ? Color(0xFF32A060): Color(0xFFE5E5E5), + ), + child: Text( + chapterList?.name ?? chapterList.name ?? "", + style: TextStyle( + fontSize: 12.sp, + fontWeight: MyFontWeight.regular, + color: position == chapterIndex ? Colors.white :Color(0xFF7C7C7C), + ), + ), + ); + } + + contentHeight() { + double contentHeight = MediaQuery + .of(context) + .size + .height - + kToolbarHeight - + MediaQuery + .of(context) + .padding + .top - + 160.h; + if ((contentHeight - 60.h) > (128.h * memberList.length)) { + commentHeight = contentHeight - (128.h * memberList.length); + } + } + + ///给文章/活动点赞 + _queryInformationLikes() async { + BaseData baseData = await apiService.informationLikes("1455102859841372160"); + if (baseData != null && baseData.isSuccess) { + commentKey.currentState.setState(() {}); + setState(() { + // if (comunity.selfLike ?? false) + // comunity.likes -= 1; + // else + // comunity.likes += 1; + // comunity.selfLike = !comunity.selfLike ?? false; + }); + } else { + // SmartDialog.showToast(baseData.msg, alignment: Alignment.center); + } + } + + ///发布评论 + _queryMemberComment(String content) async { + BaseData baseData = await apiService.memberComment({ + "content": content, + "parentId": parenId, + "relationalId":course.id, + "relationalType": 1 + }).catchError((error) {}); + if (baseData != null && baseData.isSuccess) { + CommentListState state = commentKey.currentState; + state.queryMemberCommentList(); + commentTextController.text = ""; + FocusScope.of(context).unfocus(); + _queryMemberCommentList(); + } + } + + ///评论列表 + _queryMemberCommentList() async { + SharedPreferences sharedPreferences = await SharedPreferences.getInstance(); + if (apiService == null) + apiService = ApiService( + Dio(), + context: context, + token: sharedPreferences.getString("token"), + showLoading: false, + ); + BaseData> baseData = + await apiService.memberCommentList({ + "pageNum": 1, + "pageSize": 100, + "relationalId":course.id, + "relationalType": 1, + }).catchError((error) {}); + if (baseData != null && baseData.isSuccess) { + commentTotal = baseData.data.size; + memberList = baseData.data.list; + contentHeight(); + if (mounted) setState(() {}); + } + } + + ///滑动到评论列表 + _toComment() { + if (commentKey.currentContext == null) return; + RenderBox firstRenderBox = commentKey.currentContext.findRenderObject(); + Offset first = firstRenderBox.localToGlobal(Offset.zero); + scrollController.animateTo( + first.dy + + scrollController.offset - + (kToolbarHeight + MediaQuery + .of(context) + .padding + .top), + duration: Duration(milliseconds: 300), + curve: Curves.easeIn, + ); + } + + ///评论 回复 + _reply(memberComment) { + FocusScope.of(context).requestFocus(commentFocus); + parenId = memberComment.id; + hintText = S.of(context).huifu_("${memberComment.username}"); + } + + ///删除评论 + delComment(memberComment) async { + BaseData baseData = await apiService.delComment(memberComment.id); + if (baseData != null && baseData.isSuccess) { + CommentListState state = commentKey.currentState; + state.queryMemberCommentList(); + } + } + + ///删除评论的提示 + _delCommentTips(memberComment) { + SmartDialog.show(widget: Tips(() { + delComment(memberComment); + })); + } +} diff --git a/lib/community/community_view/home_class.dart b/lib/community/community_view/home_class.dart index 2f4c13ad..b7b19f0c 100644 --- a/lib/community/community_view/home_class.dart +++ b/lib/community/community_view/home_class.dart @@ -1,18 +1,18 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_baidu_mapapi_base/flutter_baidu_mapapi_base.dart'; -import 'package:flutter_baidu_mapapi_map/flutter_baidu_mapapi_map.dart'; +import 'package:huixiang/retrofit/data/collect_class_list.dart'; import 'package:huixiang/retrofit/data/course_list.dart'; import 'package:huixiang/retrofit/retrofit_api.dart'; import 'package:huixiang/utils/font_weight.dart'; import 'package:huixiang/view_widget/custom_image.dart'; -import 'package:huixiang/view_widget/item_title.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; class HomeClass extends StatefulWidget { - final List classList; + final List collect; + final List collectList; - HomeClass(this.classList); + HomeClass(this.collect,this.collectList); @override State createState() { return _HomeClass(); @@ -23,7 +23,6 @@ class _HomeClass extends State { ApiService apiService; BMFCoordinate latLng; - BMFMapController _mapController; final TextEditingController editingController = TextEditingController(); @override @@ -33,35 +32,63 @@ class _HomeClass extends State { @override Widget build(BuildContext context) { - return Column( - children: [ - ItemTitle( - text: "回乡小课堂", - imgPath: "assets/image/ketang.png", - ), - Container( - height: 189, - margin: EdgeInsets.only(top:10), - child: ListView.builder( - scrollDirection: Axis.horizontal, - physics: BouncingScrollPhysics(), - padding: EdgeInsets.symmetric(horizontal: 10), - itemCount:widget.classList == null ? 0 : widget.classList.length, - itemBuilder: (context, position) { - return GestureDetector( - onTap: () { - Navigator.of(context).pushNamed('/router/class_details'); - }, - child: classItem(widget.classList[position]), - ); - }, + return ListView.builder( + padding: EdgeInsets.zero, + itemCount:widget.collectList == null ? 0 : widget.collectList.length, + scrollDirection: Axis.vertical, + shrinkWrap: true, + physics: NeverScrollableScrollPhysics(), + itemBuilder: (context, position) { + return collectItem(widget.collectList[position]); + }, + ); + } + + Widget collectItem(CollectClassList collectList) { + return Container( + width: 168, + height: 230, + margin: EdgeInsets.symmetric( + horizontal: 6.w, + vertical:10, + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding(padding: EdgeInsets.only(left: 16,top: 5), + child: Text( + collectList.name, + style: TextStyle( + fontSize: 15.sp, + fontWeight: MyFontWeight.medium, + color: Colors.black, + ), + ),), + Container( + height: 189, + margin: EdgeInsets.only(top:10), + child: ListView.builder( + scrollDirection: Axis.horizontal, + physics: BouncingScrollPhysics(), + padding: EdgeInsets.symmetric(horizontal: 10), + itemCount:widget.collect == null ? 0 : widget.collect.length, + itemBuilder: (context, position) { + return GestureDetector( + onTap: () { + Navigator.of(context).pushNamed('/router/class_details', + arguments: {"id":widget.collect[position].id}); + }, + child: classItem(widget.collect[position]), + ); + }, + ), ), - ), - ], + ], + ), ); } - Widget classItem(CourseList classList) { + Widget classItem(CourseList collect) { return Container( width: 168, height: 189, @@ -79,7 +106,7 @@ class _HomeClass extends State { color: Color.fromARGB(80, 0, 0, 0), child: ClipRRect( child: MImage( - classList.coverImg, + collect.coverImg, width: double.infinity, height: 120, fit: BoxFit.cover, @@ -107,7 +134,7 @@ class _HomeClass extends State { ), SizedBox(width:5), Text( - classList.likes.toString(), + collect.likes.toString(), style: TextStyle( fontSize: 12.sp, fontWeight: MyFontWeight.regular, @@ -117,32 +144,32 @@ class _HomeClass extends State { ], ), SizedBox(width:8), - Row( - children: [ - Image.asset( - "assets/image/ketang_message.png", - width: 16.w, - height: 16.h, - color: Colors.white, - ), - SizedBox(width:5), - Text( - classList.viewers.toString(), - style: TextStyle( - fontSize: 12.sp, - fontWeight: MyFontWeight.regular, - color: Colors.white, - ), - ), - ], - ), + // Row( + // children: [ + // Image.asset( + // "assets/image/ketang_message.png", + // width: 16.w, + // height: 16.h, + // color: Colors.white, + // ), + // SizedBox(width:5), + // Text( + // collect.viewers.toString(), + // style: TextStyle( + // fontSize: 12.sp, + // fontWeight: MyFontWeight.regular, + // color: Colors.white, + // ), + // ), + // ], + // ), ], ), ), ], ), Container( - padding: EdgeInsets.only(left: 3,top: 2), + padding: EdgeInsets.only(left:4,top: 2), child: Column( mainAxisAlignment: MainAxisAlignment.spaceAround, crossAxisAlignment: CrossAxisAlignment.start, @@ -153,7 +180,7 @@ class _HomeClass extends State { crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( - height: 15.h, + height: 16.h, width: 30.w, alignment: Alignment.center, decoration: BoxDecoration( @@ -166,7 +193,7 @@ class _HomeClass extends State { ), ), child: Text( - ( classList?.tags != null && classList.tags.length > 0 )?classList.tags[0] : "", + ( collect?.tags != null && collect.tags.length > 0 )?collect.tags[0] : "", style: TextStyle( fontSize: 12.sp, fontWeight: MyFontWeight.medium, @@ -176,7 +203,7 @@ class _HomeClass extends State { ), SizedBox(width:5), Expanded(child: Text( - classList.subject, + collect.subject, style: TextStyle( fontSize: 14.sp, fontWeight: MyFontWeight.medium, @@ -187,7 +214,7 @@ class _HomeClass extends State { ), SizedBox(height:3), Text( - "讲师:${classList.author.name}", + "讲师:${collect.author.name}", style: TextStyle( fontSize: 12.sp, fontWeight: MyFontWeight.regular, diff --git a/lib/home/home_page.dart b/lib/home/home_page.dart index 0ff917ce..22ffdc79 100644 --- a/lib/home/home_page.dart +++ b/lib/home/home_page.dart @@ -32,6 +32,8 @@ import 'package:pull_to_refresh/pull_to_refresh.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'home_view/shortcut_operation.dart'; + class HomePage extends StatefulWidget { final GestureTapCallback callback; @@ -264,6 +266,9 @@ class _HomePage extends State with AutomaticKeepAliveClientMixin { ///banner HomeBanner(bannerData, controller), + ///快捷操作 + ShortcutOperation(), + ///签到 SignView(isSigned,(value){setState(() { isSigned = value; @@ -276,10 +281,11 @@ class _HomePage extends State with AutomaticKeepAliveClientMixin { // ///品牌介绍 // BrandView(brandData), - ///快捷下单 + ///店铺推荐 QuickOrder(), - CouponView(), + ///超级优惠券 + // CouponView(), ///积分商城 HomeIntegralStore(gooods, callback), diff --git a/lib/home/home_view/quick_order.dart b/lib/home/home_view/quick_order.dart index 5b0dd87a..3fd1a771 100644 --- a/lib/home/home_view/quick_order.dart +++ b/lib/home/home_view/quick_order.dart @@ -161,7 +161,7 @@ class _QuickOrder extends State { return Column( children: [ ItemTitle( - text: "快捷下单", + text: "店铺推荐", imgPath: "assets/image/icon_points_mall.png", ), Container( diff --git a/lib/home/home_view/shortcut_operation.dart b/lib/home/home_view/shortcut_operation.dart new file mode 100644 index 00000000..e7675d63 --- /dev/null +++ b/lib/home/home_view/shortcut_operation.dart @@ -0,0 +1,158 @@ +import 'package:dio/dio.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:huixiang/generated/l10n.dart'; +import 'package:huixiang/retrofit/data/activity.dart'; +import 'package:huixiang/retrofit/data/base_data.dart'; +import 'package:huixiang/retrofit/data/page.dart'; +import 'package:huixiang/retrofit/retrofit_api.dart'; +import 'package:huixiang/utils/font_weight.dart'; +import 'package:huixiang/view_widget/item_title.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:shared_preferences/shared_preferences.dart'; + +class ShortcutOperation extends StatefulWidget { + @override + State createState() { + return _ShortcutOperation(); + } +} + +class _ShortcutOperation extends State { + ApiService apiService; + + @override + void initState() { + super.initState(); + } + + + @override + Widget build(BuildContext context) { + return Container( + height: 150.h, + margin: EdgeInsets.only(bottom:15), + child: Row( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + GestureDetector( + onTap: (){ + + }, + child: Container( + width: 106, + color: Colors.white, + margin: EdgeInsets.only(left: 15,right: 15), + padding: EdgeInsets.only(top: 8,bottom: 8), + child: Column( + children: [ + Text( + "现在下单", + style: TextStyle( + fontWeight: MyFontWeight.semi_bold, + fontSize: 15.sp, + color: Colors.black, + ), + ), + SizedBox(height: 5), + Text( + "美味等你来!", + style: TextStyle( + fontWeight: MyFontWeight.regular, + fontSize: 12.sp, + color: Colors.black, + ), + ), + SizedBox(height: 20), + Image.asset( + "assets/image/home_order.png", + width:70, + height:70, + ), + ], + ), + ), + ), + GestureDetector( + onTap: (){ + + }, + child: Container( + width: 106, + color: Colors.white, + margin: EdgeInsets.only(left: 15,right: 15), + padding: EdgeInsets.only(top: 8,bottom: 8), + child: Column( + children: [ + Text( + "平台储值", + style: TextStyle( + fontWeight: MyFontWeight.semi_bold, + fontSize: 15.sp, + color: Colors.black, + ), + ), + SizedBox(height: 5), + Text( + "充值送会员!", + style: TextStyle( + fontWeight: MyFontWeight.regular, + fontSize: 12.sp, + color: Colors.black, + ), + ), + SizedBox(height: 20), + Image.asset( + "assets/image/home_recharge.png", + width:70, + height:70, + ), + ], + ), + ), + ), + GestureDetector( + onTap: (){ + Navigator.of(context).pushNamed('/router/roll_center_page'); + }, + child:Container( + width: 106, + color: Colors.white, + margin: EdgeInsets.only(left: 15,right: 15), + padding: EdgeInsets.only(top: 8,bottom: 8), + child: Column( + children: [ + Text( + "天天有劵", + style: TextStyle( + fontWeight: MyFontWeight.semi_bold, + fontSize: 15.sp, + color: Colors.black, + ), + ), + SizedBox(height: 5), + Text( + "来领超值好劵!", + style: TextStyle( + fontWeight: MyFontWeight.regular, + fontSize: 12.sp, + color: Colors.black, + ), + ), + SizedBox(height: 20), + Image.asset( + "assets/image/home_coupon.png", + width:70, + height:70, + ), + ], + ), + ), + ), + ], + ), + ); + } + +} diff --git a/lib/main.dart b/lib/main.dart index 02623816..5f02f6b1 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -308,5 +308,5 @@ Map routers = { '/router/communityFollow': (context, {arguments}) => CommunityFollow(), '/router/releasePage': (context, {arguments}) => ReleasePage(), '/router/activity_list': (context, {arguments}) => ActivityList(), - '/router/class_details': (context, {arguments}) => ClassDetails(), + '/router/class_details': (context, {arguments}) => ClassDetails(arguments: arguments), }; diff --git a/lib/order/exchange_order_page.dart b/lib/order/exchange_order_page.dart index d06bb26d..5701cc22 100644 --- a/lib/order/exchange_order_page.dart +++ b/lib/order/exchange_order_page.dart @@ -8,6 +8,7 @@ import 'package:huixiang/generated/l10n.dart'; import 'package:huixiang/retrofit/data/base_data.dart'; import 'package:huixiang/retrofit/data/user_info.dart'; import 'package:huixiang/retrofit/retrofit_api.dart'; +import 'package:huixiang/utils/font_weight.dart'; import 'package:huixiang/view_widget/my_appbar.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; @@ -26,6 +27,9 @@ class ExchangeOrderPage extends StatefulWidget { class _ExchangeOrderPage extends State { ApiService apiService; + String money = "0"; + String balance = "0"; + var checkIndex = 1; @override void initState() { @@ -51,14 +55,15 @@ class _ExchangeOrderPage extends State { background: Color(0xFFFAFAFA), leadingColor: Colors.black, ), - body: Column( + body: SingleChildScrollView( + physics: BouncingScrollPhysics(), + child: Column( children: [ - Expanded( - child: Column( + Column( children: [ Container( margin: - EdgeInsets.only(left: 16, right: 16, top: 26, bottom: 8), + EdgeInsets.only(left: 16, right: 16, top: 26, bottom: 8), padding: EdgeInsets.all(20), decoration: BoxDecoration( color: Colors.white, @@ -110,8 +115,8 @@ class _ExchangeOrderPage extends State { widget.arguments["useTyped"] == 1 ? S.of(context).ziti : widget.arguments["useTyped"] == 2 - ? S.of(context).peisong - : S.of(context).xianshangfafang, + ? S.of(context).peisong + : S.of(context).xianshangfafang, style: TextStyle( fontSize: 14.sp, color: Color(0xFF353535), @@ -153,13 +158,13 @@ class _ExchangeOrderPage extends State { (address != null && address != "") ? address : widget.arguments["useTyped"] == 1 - ? S.of(context).qingxuanzhemendian - : widget.arguments["useTyped"] == - 2 - ? S - .of(context) - .qingxuanzeshouhuodizhi - : S.of(context).xuni, + ? S.of(context).qingxuanzhemendian + : widget.arguments["useTyped"] == + 2 + ? S + .of(context) + .qingxuanzeshouhuodizhi + : S.of(context).xuni, overflow: TextOverflow.ellipsis, style: TextStyle( fontSize: 14.sp, @@ -205,8 +210,8 @@ class _ExchangeOrderPage extends State { widget.arguments["useTyped"] == 1 ? S.of(context).duihuanhouwugegongzuori : widget.arguments["useTyped"] == 2 - ? S.of(context).duihuanhoufahuo - : S.of(context).feishiwushangpin, + ? S.of(context).duihuanhoufahuo + : S.of(context).feishiwushangpin, style: TextStyle( fontSize: 14.sp, color: widget.arguments["useTyped"] == 3 @@ -220,7 +225,7 @@ class _ExchangeOrderPage extends State { ), Container( margin: - EdgeInsets.only(left: 16, right: 16, top: 8, bottom: 16), + EdgeInsets.only(left: 16, right: 16, top: 8, bottom: 16), padding: EdgeInsets.all(20), decoration: BoxDecoration( color: Colors.white, @@ -356,33 +361,265 @@ class _ExchangeOrderPage extends State { ], ), ), - ], - )), - GestureDetector( - onTap: () { - if (!storeIsSelected) return; - creditOrder(); - }, - child: Container( - padding: EdgeInsets.only(top: 16, bottom: 16), - decoration: BoxDecoration( - color: MaterialStateColor.resolveWith((states) => + Container( + margin: + EdgeInsets.only(left: 16, right: 16, bottom: 8), + padding: EdgeInsets.all(20), + decoration: BoxDecoration( + color: Colors.white, + boxShadow: [ + BoxShadow( + color: Colors.black.withAlpha(12), + offset: Offset(0, 3), + blurRadius: 14, + spreadRadius: 0, + ) + ], + borderRadius: BorderRadius.all(Radius.circular(8)), + ), + child: Column( + children: [ + Row( + children: [ + Expanded(child: Text( + "兑换数量", + style: TextStyle( + fontWeight: MyFontWeight.regular, + fontSize: 14.sp, + color: Color(0xFF353535)), + )), + InkWell( + onTap: () { + }, + child: Image.asset( + "assets/image/reduce.png", + width: 22, + height: 22, + ), + ), + Container( + width: 30, + alignment: Alignment.center, + child: Text( + "1", + style: TextStyle( + color: Colors.black, + fontSize: 14.sp, + fontWeight: MyFontWeight.medium, + ), + ), + ), + InkWell( + onTap: () { + }, + child: Image.asset( + "assets/image/add.png", + width: 22, + height: 22, + ), + ), + ], + ), + ], + ), + ), + Container( + width: double.infinity, + margin: EdgeInsets.only( + left: 16.w, + right: 16.w, + top: 12.h, + bottom:5.h, + ), + padding: EdgeInsets.only( + left: 16.w, + right: 16.w, + top: 20.h, + bottom: 20.h, + ), + decoration: BoxDecoration( + boxShadow: [ + BoxShadow( + color: Color(0x000000).withAlpha(25), + offset: Offset(0, 1), + blurRadius: 12.0, + ), + ], + color: Colors.white, + borderRadius: BorderRadius.circular(8), + ), + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceAround, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: EdgeInsets.only(bottom: 16.h), + child: Text( + S.of(context).zhifufangshi, + style: TextStyle( + fontSize: 16.sp, + color: Colors.black, + fontWeight: MyFontWeight.regular, + ), + ), + ), + GestureDetector( + onTap: () { + setState(() { + checkIndex = 1; + }); + // widget.payChannelCheck(4); + }, + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + checkPayView(1), + Expanded( + child: Container(), + flex: 1, + ), + Text( + "¥$money", + style: TextStyle( + fontSize: 14.sp, + color: Color(0xff353535), + fontWeight: MyFontWeight.semi_bold, + ), + ), + SizedBox( + width: 10, + ), + Text( + S.of(context).pingtaiyue, + style: TextStyle( + fontSize: 14.sp, + color: Color(0xff353535), + fontWeight: MyFontWeight.semi_bold, + ), + ), + ], + ), + ), + SizedBox( + height: 10, + ), + GestureDetector( + onTap: () { + setState(() { + checkIndex = 2; + }); + }, + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + checkPayView(2), + Expanded( + child: Container(), + flex: 1, + ), + Text( + "¥$balance", + style: TextStyle( + fontSize: 14.sp, + color: Color(0xff353535), + fontWeight: MyFontWeight.semi_bold, + ), + ), + SizedBox( + width: 10, + ), + Text( + S.of(context).dianpuyue, + style: TextStyle( + fontSize: 14.sp, + color: Color(0xff353535), + fontWeight: MyFontWeight.semi_bold, + ), + ), + ], + ), + ), + SizedBox( + height: 10, + ), + GestureDetector( + onTap: () { + setState(() { + checkIndex = 3; + }); + }, + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + checkPayView(3), + Spacer(), + Image.asset("assets/image/icon_we_chat.png"), + Padding( + padding: EdgeInsets.only(left: 8.w), + child: Text( + S.of(context).weixinzhifu, + style: TextStyle( + fontSize: 14.sp, + color: Color(0xff353535), + fontWeight: MyFontWeight.semi_bold, + ), + ), + ), + ], + ), + ), + ], + ), + ), + GestureDetector( + onTap: () { + if (!storeIsSelected) return; + creditOrder(); + }, + child: Container( + padding: EdgeInsets.only(top: 16, bottom: 16), + decoration: BoxDecoration( + color: MaterialStateColor.resolveWith((states) => storeIsSelected ? Color(0xFF32A060) : Color(0xFFD8D8D8)), - borderRadius: BorderRadius.only( - topLeft: Radius.circular(4), - topRight: Radius.circular(4))), - alignment: Alignment.center, - child: Text( - S.of(context).querenduihuan, - style: TextStyle( - fontSize: 16.sp, - color: MaterialStateColor.resolveWith((states) => + borderRadius: BorderRadius.only( + topLeft: Radius.circular(4), + topRight: Radius.circular(4))), + alignment: Alignment.center, + child: Text( + S.of(context).querenduihuan, + style: TextStyle( + fontSize: 16.sp, + color: MaterialStateColor.resolveWith((states) => storeIsSelected ? Colors.white : Color(0xFFA0A0A0)), - fontWeight: FontWeight.bold), + fontWeight: FontWeight.bold), + ), + ), ), - ), + ], ), + + // Expanded( + // child: + // ), + ], + ) ,), + ); + } + + Widget checkPayView(var index) { + return Container( + padding: EdgeInsets.only(right: 16.w), + alignment: Alignment.center, + child: Image.asset( + checkIndex != index + ? "assets/image/icon_radio_unselected.png" + : "assets/image/icon_radio_selected.png", + width: 15.w, + height: 15.h, ), ); } diff --git a/lib/retrofit/data/chapter.dart b/lib/retrofit/data/chapter.dart new file mode 100644 index 00000000..f4111ac1 --- /dev/null +++ b/lib/retrofit/data/chapter.dart @@ -0,0 +1,136 @@ +/// id : "1452530820865589248" +/// createTime : "2021-10-25 15:01:49" +/// createUser : "1" +/// updateTime : "2021-11-02 17:09:56" +/// updateUser : "1" +/// courseId : "1452472611438067712" +/// name : "111" +/// content : {"coverImg":"https://pos.upload.gznl.top/0000/2021/11/3e014154-57cc-441e-9d02-aa53975979f5.png","remark":"11111111","fileUrl":"https://pos.upload.gznl.top/0000/2021/11/d87dd996-e269-46eb-b7ef-f8ceddfabef2.mp4"} +/// sort : 0 +/// isDelete : 0 + +class Chapter { + Chapter({ + String id, + String createTime, + String createUser, + String updateTime, + String updateUser, + String courseId, + String name, + Content content, + int sort, + int isDelete,}){ + _id = id; + _createTime = createTime; + _createUser = createUser; + _updateTime = updateTime; + _updateUser = updateUser; + _courseId = courseId; + _name = name; + _content = content; + _sort = sort; + _isDelete = isDelete; +} + + Chapter.fromJson(dynamic json) { + _id = json['id']; + _createTime = json['createTime']; + _createUser = json['createUser']; + _updateTime = json['updateTime']; + _updateUser = json['updateUser']; + _courseId = json['courseId']; + _name = json['name']; + _content = json['content'] != null ? Content.fromJson(json['content']) : null; + _sort = json['sort']; + _isDelete = json['isDelete']; + } + String _id; + String _createTime; + String _createUser; + String _updateTime; + String _updateUser; + String _courseId; + String _name; + Content _content; + int _sort; + int _isDelete; + + String get id => _id; + String get createTime => _createTime; + String get createUser => _createUser; + String get updateTime => _updateTime; + String get updateUser => _updateUser; + String get courseId => _courseId; + String get name => _name; + Content get content => _content; + int get sort => _sort; + int get isDelete => _isDelete; + + Map toJson() { + final map = {}; + map['id'] = _id; + map['createTime'] = _createTime; + map['createUser'] = _createUser; + map['updateTime'] = _updateTime; + map['updateUser'] = _updateUser; + map['courseId'] = _courseId; + map['name'] = _name; + if (_content != null) { + map['content'] = _content.toJson(); + } + map['sort'] = _sort; + map['isDelete'] = _isDelete; + return map; + } + +} + +/// coverImg : "https://pos.upload.gznl.top/0000/2021/11/3e014154-57cc-441e-9d02-aa53975979f5.png" +/// remark : "11111111" +/// fileUrl : "https://pos.upload.gznl.top/0000/2021/11/d87dd996-e269-46eb-b7ef-f8ceddfabef2.mp4" + +class Content { + Content({ + String coverImg, + String remark, + String fileUrl,}){ + _coverImg = coverImg; + _remark = remark; + _fileUrl = fileUrl; +} + + Content.fromJson(dynamic json) { + _coverImg = json['coverImg']; + _remark = json['remark']; + _fileUrl = json['fileUrl']; + } + String _coverImg; + String _remark; + String _fileUrl; + + String get coverImg => _coverImg; + String get remark => _remark; + String get fileUrl => _fileUrl; + + + set coverImg(String value) { + _coverImg = value; + } + + Map toJson() { + final map = {}; + map['coverImg'] = _coverImg; + map['remark'] = _remark; + map['fileUrl'] = _fileUrl; + return map; + } + + set remark(String value) { + _remark = value; + } + + set fileUrl(String value) { + _fileUrl = value; + } +} \ No newline at end of file diff --git a/lib/retrofit/data/collect_class_list.dart b/lib/retrofit/data/collect_class_list.dart new file mode 100644 index 00000000..be69a97d --- /dev/null +++ b/lib/retrofit/data/collect_class_list.dart @@ -0,0 +1,114 @@ +/// id : "1454326699855446016" +/// createTime : "2021-10-30 13:58:00" +/// createUser : "1" +/// updateTime : "2021-10-30 13:58:00" +/// updateUser : "1" +/// name : "111" +/// sort : 0 +/// enabled : true +/// isDelete : 0 + +class CollectClassList { + CollectClassList({ + String id, + String createTime, + String createUser, + String updateTime, + String updateUser, + String name, + int sort, + bool enabled, + int isDelete,}){ + _id = id; + _createTime = createTime; + _createUser = createUser; + _updateTime = updateTime; + _updateUser = updateUser; + _name = name; + _sort = sort; + _enabled = enabled; + _isDelete = isDelete; +} + + CollectClassList.fromJson(dynamic json) { + _id = json['id']; + _createTime = json['createTime']; + _createUser = json['createUser']; + _updateTime = json['updateTime']; + _updateUser = json['updateUser']; + _name = json['name']; + _sort = json['sort']; + _enabled = json['enabled']; + _isDelete = json['isDelete']; + } + String _id; + String _createTime; + String _createUser; + String _updateTime; + String _updateUser; + String _name; + int _sort; + bool _enabled; + int _isDelete; + + String get id => _id; + String get createTime => _createTime; + String get createUser => _createUser; + String get updateTime => _updateTime; + String get updateUser => _updateUser; + String get name => _name; + int get sort => _sort; + bool get enabled => _enabled; + int get isDelete => _isDelete; + + + set id(String value) { + _id = value; + } + + Map toJson() { + final map = {}; + map['id'] = _id; + map['createTime'] = _createTime; + map['createUser'] = _createUser; + map['updateTime'] = _updateTime; + map['updateUser'] = _updateUser; + map['name'] = _name; + map['sort'] = _sort; + map['enabled'] = _enabled; + map['isDelete'] = _isDelete; + return map; + } + + set createTime(String value) { + _createTime = value; + } + + set createUser(String value) { + _createUser = value; + } + + set updateTime(String value) { + _updateTime = value; + } + + set updateUser(String value) { + _updateUser = value; + } + + set name(String value) { + _name = value; + } + + set sort(int value) { + _sort = value; + } + + set enabled(bool value) { + _enabled = value; + } + + set isDelete(int value) { + _isDelete = value; + } +} \ No newline at end of file diff --git a/lib/retrofit/data/course_details.dart b/lib/retrofit/data/course_details.dart new file mode 100644 index 00000000..5edf03e5 --- /dev/null +++ b/lib/retrofit/data/course_details.dart @@ -0,0 +1,152 @@ +/// id : "1455102859841372160" +/// createTime : "2021-11-01 17:22:11" +/// createUser : "1" +/// updateTime : "2021-11-01 17:22:11" +/// updateUser : "1" +/// categoryId : "1452472226421932032" +/// subject : "后会无期" +/// tags : ["11"] +/// coverImg : "https://pos.upload.gznl.top/0000/2021/11/d8305d15-1a39-4b08-a172-eba7f18b9968.jpg" +/// author : {"name":"1","avatar":"1"} +/// introduce : "1" +/// viewers : 0 +/// likes : 0 +/// state : true +/// isDelete : 0 + +class CourseDetails { + CourseDetails({ + String id, + String createTime, + String createUser, + String updateTime, + String updateUser, + String categoryId, + String subject, + List tags, + String coverImg, + Author author, + String introduce, + int viewers, + int likes, + bool state, + int isDelete,}){ + _id = id; + _createTime = createTime; + _createUser = createUser; + _updateTime = updateTime; + _updateUser = updateUser; + _categoryId = categoryId; + _subject = subject; + _tags = tags; + _coverImg = coverImg; + _author = author; + _introduce = introduce; + _viewers = viewers; + _likes = likes; + _state = state; + _isDelete = isDelete; +} + + CourseDetails.fromJson(dynamic json) { + _id = json['id']; + _createTime = json['createTime']; + _createUser = json['createUser']; + _updateTime = json['updateTime']; + _updateUser = json['updateUser']; + _categoryId = json['categoryId']; + _subject = json['subject']; + _tags = json['tags'] != null ? json['tags'].cast() : []; + _coverImg = json['coverImg']; + _author = json['author'] != null ? Author.fromJson(json['author']) : null; + _introduce = json['introduce']; + _viewers = json['viewers']; + _likes = json['likes']; + _state = json['state']; + _isDelete = json['isDelete']; + } + String _id; + String _createTime; + String _createUser; + String _updateTime; + String _updateUser; + String _categoryId; + String _subject; + List _tags; + String _coverImg; + Author _author; + String _introduce; + int _viewers; + int _likes; + bool _state; + int _isDelete; + + String get id => _id; + String get createTime => _createTime; + String get createUser => _createUser; + String get updateTime => _updateTime; + String get updateUser => _updateUser; + String get categoryId => _categoryId; + String get subject => _subject; + List get tags => _tags; + String get coverImg => _coverImg; + Author get author => _author; + String get introduce => _introduce; + int get viewers => _viewers; + int get likes => _likes; + bool get state => _state; + int get isDelete => _isDelete; + + Map toJson() { + final map = {}; + map['id'] = _id; + map['createTime'] = _createTime; + map['createUser'] = _createUser; + map['updateTime'] = _updateTime; + map['updateUser'] = _updateUser; + map['categoryId'] = _categoryId; + map['subject'] = _subject; + map['tags'] = _tags; + map['coverImg'] = _coverImg; + if (_author != null) { + map['author'] = _author.toJson(); + } + map['introduce'] = _introduce; + map['viewers'] = _viewers; + map['likes'] = _likes; + map['state'] = _state; + map['isDelete'] = _isDelete; + return map; + } + +} + +/// name : "1" +/// avatar : "1" + +class Author { + Author({ + String name, + String avatar,}){ + _name = name; + _avatar = avatar; +} + + Author.fromJson(dynamic json) { + _name = json['name']; + _avatar = json['avatar']; + } + String _name; + String _avatar; + + String get name => _name; + String get avatar => _avatar; + + Map toJson() { + final map = {}; + map['name'] = _name; + map['avatar'] = _avatar; + return map; + } + +} \ No newline at end of file diff --git a/lib/retrofit/retrofit_api.dart b/lib/retrofit/retrofit_api.dart index 6ad80563..007c9611 100644 --- a/lib/retrofit/retrofit_api.dart +++ b/lib/retrofit/retrofit_api.dart @@ -21,6 +21,9 @@ import 'data/address.dart'; import 'data/banner.dart'; import 'data/brand_data.dart'; import 'data/category_select_list.dart'; +import 'data/chapter.dart'; +import 'data/collect_class_list.dart'; +import 'data/course_details.dart'; import 'data/course_list.dart'; import 'data/exchange_order.dart'; import 'data/follow_list.dart'; @@ -397,10 +400,22 @@ abstract class ApiService { ///课程章节列表 @GET("/course/catalogList/{courseId}") - Future catalogList(@Path("courseId") String courseId); + Future>> catalogList(@Path("courseId") String courseId); /// 课程列表 @POST("/course/list") Future>> courseList(@Body() Map map); + ///课程的合集列表 + @GET("/course/collectList") + Future>> collectList(); + + ///合集包含的课程列表 + @GET("/course/collect/{collectId}") + Future>> collect(@Path("collectId") String collectId); + + ///课程详情 + @GET("/course/{id}") + Future> course(@Path("id") String id); + } diff --git a/lib/retrofit/retrofit_api.g.dart b/lib/retrofit/retrofit_api.g.dart index 63ddb880..cfab0889 100644 --- a/lib/retrofit/retrofit_api.g.dart +++ b/lib/retrofit/retrofit_api.g.dart @@ -1369,7 +1369,7 @@ class _ApiService implements ApiService { } @override - Future> catalogList(courseId) async { + Future>> catalogList(courseId) async { ArgumentError.checkNotNull(courseId, 'courseId'); const _extra = {}; final queryParameters = {}; @@ -1383,13 +1383,37 @@ class _ApiService implements ApiService { extra: _extra, baseUrl: baseUrl), data: _data); - final value = BaseData.fromJson( - _result.data, - (json) => json as dynamic, - ); + final value = BaseData>.fromJson( + _result.data, + (json) => (json as List) + .map((i) => Chapter.fromJson(i as Map)) + .toList()); return value; } + // + // @override + // Future> catalogList(courseId) async { + // ArgumentError.checkNotNull(courseId, 'courseId'); + // const _extra = {}; + // final queryParameters = {}; + // final _data = {}; + // final _result = await _dio.request>( + // '/course/catalogList/$courseId', + // queryParameters: queryParameters, + // options: RequestOptions( + // method: 'GET', + // headers: {}, + // extra: _extra, + // baseUrl: baseUrl), + // data: _data); + // final value = BaseData.fromJson( + // _result.data, + // (json) => json as dynamic, + // ); + // return value; + // } + @override Future>> courseList(map) async { ArgumentError.checkNotNull(map, 'map'); @@ -1416,4 +1440,71 @@ class _ApiService implements ApiService { return value; } + @override + Future>> collectList() async { + const _extra = {}; + final queryParameters = {}; + final _data = {}; + final _result = await _dio.request>( + '/course/collectList', + queryParameters: queryParameters, + options: RequestOptions( + method: 'GET', + headers: {}, + extra: _extra, + baseUrl: baseUrl), + data: _data); + final value = BaseData>.fromJson( + _result.data, + (json) => (json as List) + .map((i) => CollectClassList.fromJson(i as Map)) + .toList()); + return value; + } + + @override + Future>> collect(collectId) async { + ArgumentError.checkNotNull(collectId, 'collectId'); + const _extra = {}; + final queryParameters = {}; + final _data = {}; + final _result = await _dio.request>( + '/course/collect/$collectId', + queryParameters: queryParameters, + options: RequestOptions( + method: 'GET', + headers: {}, + extra: _extra, + baseUrl: baseUrl), + data: _data); + final value = BaseData>.fromJson( + _result.data, + (json) => (json as List) + .map((i) => CourseList.fromJson(i as Map)) + .toList()); + return value; + } + + @override + Future> course(id) async { + ArgumentError.checkNotNull(id, 'id'); + const _extra = {}; + final queryParameters = {}; + final _data = {}; + final _result = await _dio.request>( + '/course/$id', + queryParameters: queryParameters, + options: RequestOptions( + method: 'GET', + headers: {}, + extra: _extra, + baseUrl: baseUrl), + data: _data); + final value = BaseData.fromJson( + _result.data, + (json) => CourseDetails.fromJson(json), + ); + return value; + } + } diff --git a/lib/web/web_view/comment_list.dart b/lib/web/web_view/comment_list.dart index 10dd6fd0..06619ee5 100644 --- a/lib/web/web_view/comment_list.dart +++ b/lib/web/web_view/comment_list.dart @@ -159,23 +159,23 @@ class CommentListState extends State { ), ), ), - if (memberList == null || memberList.length == 0) - Container( - width: double.infinity, - height: MediaQuery.of(context).size.height - kToolbarHeight - - MediaQuery.of(context).padding.top - 160.h, - alignment: Alignment.topCenter, - color: Color(0xFFF2F2F2), - padding: EdgeInsets.only(top: 22.h), - child: Text( - S.of(context).zanwupinglun, - style: TextStyle( - fontSize: widget.fontSize + 2, - fontWeight: FontWeight.bold, - color: Color(0xFFA0A0A0), - ), - ), - ), + // if (memberList == null || memberList.length == 0) + // Container( + // width: double.infinity, + // height: MediaQuery.of(context).size.height - kToolbarHeight + // - MediaQuery.of(context).padding.top - 160.h, + // alignment: Alignment.topCenter, + // color: Color(0xFFF2F2F2), + // padding: EdgeInsets.only(top: 22.h), + // child: Text( + // S.of(context).zanwupinglun, + // style: TextStyle( + // fontSize: widget.fontSize + 2, + // fontWeight: FontWeight.bold, + // color: Color(0xFFA0A0A0), + // ), + // ), + // ), ], ), ),