From fb06daaf869846328c593ce89c60a996c2ce9562 Mon Sep 17 00:00:00 2001 From: PH2 <1293456824@qq.com> Date: Tue, 22 Sep 2020 16:35:42 +0800 Subject: [PATCH] =?UTF-8?q?1=E3=80=81=E5=95=86=E5=93=81=E8=AF=A6=E6=83=85?= =?UTF-8?q?=E7=9A=84=E5=AE=8C=E5=96=84=E5=90=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../bloc/goods_details_page_bloc.dart | 11 +- .../bloc/goods_details_page_repository.dart | 122 ++++++++++++++---- .../goods_details_page.dart | 15 ++- lib/pages/sreach_page/sreach_page.dart | 11 ++ .../sreach_result_page.dart | 11 ++ lib/register.dart | 18 ++- .../coupon/bloc/counpon_bloc.dart | 8 +- .../coupon/bloc/counpon_repository.dart | 8 ++ .../coupon/bloc/counpon_state.dart | 3 + .../goods_details/coupon/counpon_sk.dart | 2 +- .../goods_details/coupon/counpon_widget.dart | 70 ++++++---- .../coupon/model/counpon_model.dart | 54 +++++++- .../bloc/goods_details_img_bloc.dart | 54 ++++++++ .../bloc/goods_details_img_event.dart | 18 +++ .../bloc/goods_details_img_repository.dart | 35 +++++ .../bloc/goods_details_img_state.dart | 30 +++++ .../detail_img/goods_details_img.dart | 110 ++++++++++++++++ .../detail_img/goods_details_img_sk.dart | 11 ++ .../model/goods_details_img_model.dart | 41 ++++++ .../goods_details_evaluate_widget.dart | 39 +++++- .../model/goods_details_evaluate_model.dart | 39 ++++++ .../bloc/goods_details_footer_bloc.dart | 51 ++++++++ .../bloc/goods_details_footer_event.dart | 23 ++++ .../bloc/goods_details_footer_repository.dart | 25 ++++ .../bloc/goods_details_footer_state.dart | 29 +++++ .../footer/goods_details_footer_sk.dart | 3 +- .../footer/goods_details_footer_widget.dart | 112 ++++++++++------ .../model/goods_details_footer_model.dart | 69 ++++++++++ .../price/goods_details_price_widget.dart | 58 ++++++--- .../model/goods_details_price_model.dart | 71 ++++++++++ .../bloc/goods_details_slide_banner_bloc.dart | 13 +- ...goods_details_slide_banner_repository.dart | 6 +- .../goods_details_slide_banner_widget.dart | 14 +- .../goods_details_silde_banner_model.dart | 89 +++++-------- .../goods_details/store/bloc/store_bloc.dart | 23 ++-- .../goods_details/store/bloc/store_event.dart | 7 +- .../store/bloc/store_repository.dart | 11 +- .../store/model/store_model.dart | 53 +++++++- lib/widgets/goods_details/store/store_sk.dart | 3 + .../goods_details/store/store_widget.dart | 44 +++---- .../title/goods_details_title_widget.dart | 88 ++++++++++--- .../model/goods_details_title_model.dart | 58 +++++++++ .../upgrade_tip/model/upgrade_tip_model.dart | 35 ++++- .../upgrade_tip/upgrade_tip_widget.dart | 61 ++++++--- .../home/home_goods/home_goods_item.dart | 87 +++++++------ .../home_goods/models/home_goods_model.dart | 4 + .../home_goods/models/home_goods_model.g.dart | 2 + .../home_slide_banner/home_slide_banner.dart | 8 +- 48 files changed, 1435 insertions(+), 322 deletions(-) create mode 100644 lib/pages/sreach_page/sreach_page.dart create mode 100644 lib/pages/sreach_result_page/sreach_result_page.dart create mode 100644 lib/widgets/goods_details/detail_img/bloc/goods_details_img_bloc.dart create mode 100644 lib/widgets/goods_details/detail_img/bloc/goods_details_img_event.dart create mode 100644 lib/widgets/goods_details/detail_img/bloc/goods_details_img_repository.dart create mode 100644 lib/widgets/goods_details/detail_img/bloc/goods_details_img_state.dart create mode 100644 lib/widgets/goods_details/detail_img/goods_details_img.dart create mode 100644 lib/widgets/goods_details/detail_img/goods_details_img_sk.dart create mode 100644 lib/widgets/goods_details/detail_img/model/goods_details_img_model.dart create mode 100644 lib/widgets/goods_details/evaluate/model/goods_details_evaluate_model.dart create mode 100644 lib/widgets/goods_details/footer/bloc/goods_details_footer_bloc.dart create mode 100644 lib/widgets/goods_details/footer/bloc/goods_details_footer_event.dart create mode 100644 lib/widgets/goods_details/footer/bloc/goods_details_footer_repository.dart create mode 100644 lib/widgets/goods_details/footer/bloc/goods_details_footer_state.dart create mode 100644 lib/widgets/goods_details/footer/model/goods_details_footer_model.dart create mode 100644 lib/widgets/goods_details/price/model/goods_details_price_model.dart create mode 100644 lib/widgets/goods_details/title/model/goods_details_title_model.dart diff --git a/lib/pages/goods_details_page/bloc/goods_details_page_bloc.dart b/lib/pages/goods_details_page/bloc/goods_details_page_bloc.dart index 3960ec1..81cdf21 100644 --- a/lib/pages/goods_details_page/bloc/goods_details_page_bloc.dart +++ b/lib/pages/goods_details_page/bloc/goods_details_page_bloc.dart @@ -30,10 +30,15 @@ class GoodsDetailsPageBloc extends Bloc<GoodsDetailsPageEvent, GoodsDetailsPageS } Stream<GoodsDetailsPageState> _mapInitEventToState(GoodsDetailsPageInitEvent event) async* { - var result = await repository.fetchInitData(event.model); - if (!EmptyUtil.isEmpty(result)) + var result = await repository.fetchInitModData(event.model); + if (!EmptyUtil.isEmpty(result)) { yield GoodsDetailsPageLoadedState(model: result); - else + // var itemModelData = await repository.fetchModData(event.model); + // if(!EmptyUtil.isEmpty(itemModelData)){ + // yield GoodsDetailsPageLoadedState(model: itemModelData); + // } + } else { yield GoodsDetailsPageErrorState(); + } } } diff --git a/lib/pages/goods_details_page/bloc/goods_details_page_repository.dart b/lib/pages/goods_details_page/bloc/goods_details_page_repository.dart index 77ed80e..8beaab1 100644 --- a/lib/pages/goods_details_page/bloc/goods_details_page_repository.dart +++ b/lib/pages/goods_details_page/bloc/goods_details_page_repository.dart @@ -1,40 +1,108 @@ +import 'dart:convert'; import 'package:zhiying_comm/zhiying_comm.dart'; class GoodsDetailsPageRepository { - List<Map<String, dynamic>> _pageData = []; - - /// 初始化 - Future<List<Map<String, dynamic>>> fetchInitData(Map<String, dynamic> model) async { - int id = 13; - var result = await NetUtil.post('/api/v1/mod', - method: NetMethod.POST, - params: Map<String, dynamic>.from({ - 'ids': [id] - })); + + + + + /// 获取数据 + Future<List<Map<String, dynamic>>> fetchInitModData(final Map<String, dynamic> model) async{ + + String provider = model['provider']; + String goodId = model['good_id']; try { - if(NetUtil.isSuccess(result) && !EmptyUtil.isEmpty(result[GlobalConfig.HTTP_RESPONSE_KEY_DATA])) { - return _loadData(id, result[GlobalConfig.HTTP_RESPONSE_KEY_DATA]); + if (!EmptyUtil.isEmpty(provider) && !EmptyUtil.isEmpty(goodId)) { + Logger.log('商品类型 = $provider, 商品ID = $goodId'); + var result = await NetUtil.post('/api/v1/detail/$provider/$goodId', method: NetMethod.GET); + if (NetUtil.isSuccess(result) && !EmptyUtil.isEmpty(result[GlobalConfig.HTTP_RESPONSE_KEY_DATA])) { + + List<Map<String, dynamic>> _pageData = []; + /// 合并数据 + List<dynamic> modLists = result[GlobalConfig.HTTP_RESPONSE_KEY_DATA]['mod_list']; + for(int i = 0; i < modLists.length; i++){ + Map<String, dynamic> item = modLists[i]; + Map<String, dynamic> data = item['data']; + Map<String, dynamic> style = jsonDecode(item['style']); + + Map<String, dynamic> baseData = {'provider': provider, 'good_id': goodId}; + style.addAll(baseData); + + if(!EmptyUtil.isEmpty(data)){ + style.addAll(data); + item['data'] = jsonEncode(style); + _pageData.add(item); + }else{ + item['data'] = jsonEncode(style); + _pageData.add(item); + } + } + + return _pageData; + } } - } catch (e) { + }catch(e){ Logger.log(e); } return null; } - /// 处理数据 - List<Map<String, dynamic>> _loadData(int id, dynamic data) { - String key = id.toString(); - Map<String, dynamic> json = Map<String, dynamic>.from(data); - if (json.containsKey(key)) { - List<dynamic> list = json[key]; - _pageData = list.map((item) { - return Map<String, dynamic>.from(item); - }).toList(); - return _pageData; - } - return null; - } - /// 获取缓存数据? + ///【弃用】获取mod数据 把子mod数据塞在data中 + // Future<List<Map<String, dynamic>>> fetchModData(final Map<String, dynamic> model) async{ + // String provider = model['provider']; + // String goodId = model['good_id']; + // try { + // if (!EmptyUtil.isEmpty(provider) && !EmptyUtil.isEmpty(goodId)) { + // Logger.log('商品类型 = $provider, 商品ID = $goodId'); + // var result = await NetUtil.post('/api/v1/detail/$provider/$goodId', method: NetMethod.GET); + // if(NetUtil.isSuccess(result) && !EmptyUtil.isEmpty(result[GlobalConfig.HTTP_RESPONSE_KEY_DATA])) { + // for (int i = 0; i < _pageData.length; i++) { + // //result[GlobalConfig.HTTP_RESPONSE_KEY_DATA]['mod_list'][i]; + // Map<String, dynamic> resultData = result[GlobalConfig.HTTP_RESPONSE_KEY_DATA]['mod_list'][i]; + // Map<String, dynamic> data = jsonDecode(_pageData[i]['data']); + // if(!EmptyUtil.isEmpty(data)){ + // data.addAll(resultData); + // _pageData[i]['data'] = jsonEncode(data); + // }else{ + // _pageData[i]['data'] = (null != resultData && resultData.length > 0) ? jsonEncode(resultData) : ''; + // } + // } + // return _pageData; + // } + // } + // }catch(e){ + // Logger.log(e); + // } + // return null; + // } + // + // ///【弃用】初始化 + // Future<List<Map<String, dynamic>>> fetchInitData(Map<String, dynamic> model) async { + // int id = 13; + // var result = await NetUtil.post('/api/v1/mod', method: NetMethod.POST, params: {'ids': [id]}); + // try { + // if(NetUtil.isSuccess(result) && !EmptyUtil.isEmpty(result[GlobalConfig.HTTP_RESPONSE_KEY_DATA])) { + // return _loadData(id, result[GlobalConfig.HTTP_RESPONSE_KEY_DATA]); + // } + // } catch (e) { + // Logger.log(e); + // } + // return null; + // } + // + // ///【弃用】处理数据 + // List<Map<String, dynamic>> _loadData(int id, dynamic data) { + // String key = id.toString(); + // Map<String, dynamic> json = Map<String, dynamic>.from(data); + // if (json.containsKey(key)) { + // List<dynamic> list = json[key]; + // _pageData = list.map((item) { + // return Map<String, dynamic>.from(item); + // }).toList(); + // return _pageData; + // } + // return null; + // } } diff --git a/lib/pages/goods_details_page/goods_details_page.dart b/lib/pages/goods_details_page/goods_details_page.dart index a033f9f..fa38d3d 100644 --- a/lib/pages/goods_details_page/goods_details_page.dart +++ b/lib/pages/goods_details_page/goods_details_page.dart @@ -19,6 +19,11 @@ class GoodsDetailsPage extends StatefulWidget { } class _GoodsDetailsPageState extends State<GoodsDetailsPage> { + @override + void initState() { + print("parent data = ${widget.data}"); + super.initState(); + } @override Widget build(BuildContext context) { return Scaffold( @@ -136,18 +141,18 @@ class _GoodsDetailsContainerState extends State<GoodsDetailsContainer> { ), ), /// appBar - Align( - alignment: Alignment.topCenter, - child: _getAppBarWidget()), + Align(alignment: Alignment.topCenter, child: _getAppBarWidget()), + /// 底部 - Align(alignment: Alignment.bottomCenter, child: GoodsDetailsFooterWidget(null)) + Align(alignment: Alignment.bottomCenter, child: GoodsDetailsFooterWidget(!EmptyUtil.isEmpty(datas) ? datas[ datas.length-1 ] : null)) ], ); } List<Widget> _createContent(BuildContext context, List<Map<String, dynamic>> datas) { List<Widget> list = List(); - for (int i = 0; i < datas.length; i++) { + /// datas.length - 1 为最后一个在底部 + for (int i = 0; i < datas.length - 1; i++) { WidgetModel item = WidgetModel.fromJson(Map<String, dynamic>.from(datas[i])); print('item.modName ${item.modName}'); diff --git a/lib/pages/sreach_page/sreach_page.dart b/lib/pages/sreach_page/sreach_page.dart new file mode 100644 index 0000000..74240f1 --- /dev/null +++ b/lib/pages/sreach_page/sreach_page.dart @@ -0,0 +1,11 @@ +import 'package:flutter/material.dart'; + +/// +/// 搜索页 +/// +class SreachPage extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Container(); + } +} diff --git a/lib/pages/sreach_result_page/sreach_result_page.dart b/lib/pages/sreach_result_page/sreach_result_page.dart new file mode 100644 index 0000000..8d70417 --- /dev/null +++ b/lib/pages/sreach_result_page/sreach_result_page.dart @@ -0,0 +1,11 @@ +import 'package:flutter/material.dart'; + +/// +/// 搜索结果页面 +/// +class SreachResultPage extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Container(); + } +} diff --git a/lib/register.dart b/lib/register.dart index 55a1501..48e2d79 100644 --- a/lib/register.dart +++ b/lib/register.dart @@ -5,6 +5,8 @@ import 'package:zhiying_base_widget/pages/main_page/main_page.dart'; import 'package:zhiying_base_widget/pages/mine_detail_page/mine_detail_page.dart'; import 'package:zhiying_base_widget/pages/orders_page/orders_page.dart'; import 'package:zhiying_base_widget/pages/setting_page/setting_page.dart'; +import 'package:zhiying_base_widget/pages/sreach_page/sreach_page.dart'; +import 'package:zhiying_base_widget/pages/sreach_result_page/sreach_result_page.dart'; import 'package:zhiying_base_widget/pages/wallet_page/wallet_page.dart'; import 'package:zhiying_base_widget/widgets/home/home_auth/home_auth_creater.dart'; import 'package:zhiying_base_widget/widgets/goods_details/footer/goods_details_footer_widget.dart'; @@ -33,6 +35,7 @@ import 'package:zhiying_comm/util/defalut_widget_creater.dart'; import 'package:zhiying_comm/zhiying_comm.dart'; import 'widgets/goods_details/coupon/counpon_widget.dart'; +import 'widgets/goods_details/detail_img/goods_details_img.dart'; import 'widgets/goods_details/evaluate/goods_details_evaluate_widget.dart'; import 'widgets/goods_details/title/goods_details_title_widget.dart'; import 'widgets/home/home_quick_entry/home_quick_entry.dart'; @@ -51,6 +54,8 @@ class BaseWidgetRegister { PageFactory.regist('profile', (model) => MainPage(model)); PageFactory.regist('category', (model) => WalletPage()); PageFactory.regist('goods_details', (model) => GoodsDetailsPage(model)); + PageFactory.regist('sreach', (model) => SreachPage() ); + PageFactory.regist('sreach_result', (model) => SreachResultPage() ); // PageFactory.regist('login', (model) => LoginPage(model)); // PageFactory.regist('login_quick', (model) => LoginQuickPage(model)); // PageFactory.regist('login_account', (model) => LoginAccountPage(model)); @@ -73,7 +78,7 @@ class BaseWidgetRegister { // WidgetFactory.regist('index_title', NormalNavCreater()); /// 首页搜索栏 // WidgetFactory.regist('index_search', HomeSreachCreater()); - // WidgetFactory.regist('index_search', DefaultWidgetCreater((model) => HomeSreachWidget(model))); + WidgetFactory.regist('index_search', DefaultWidgetCreater((model) => HomeSreachWidget(model))); /// 可滚动banner WidgetFactory.regist('index_carousel', HomeSlideBannerCreater()); WidgetFactory.regist('index_recommend_list', GoodsListCreater()); @@ -89,6 +94,12 @@ class BaseWidgetRegister { WidgetFactory.regist('index_banner_two', HomeBannerCreater()); WidgetFactory.regist('index_taobao_auth_tip', HomeAuthCreater()); + /// ==================== 搜索页 ==================== /// + + + /// ==================== 搜索结果页 ==================== /// + + /// ==================== 商品详情 ==================== /// // 商品详情轮播图 WidgetFactory.regist('product_detail_carousel', DefaultWidgetCreater((model) => GoodsDetailsSlideBannerWidget(model))); @@ -105,9 +116,10 @@ class BaseWidgetRegister { // 商品详情宝贝评价 WidgetFactory.regist('product_detail_comment', DefaultWidgetCreater((model) => GoodsDetailsEvaluateWidget(model))); // 商品详情图片 - // WidgetFactory.regist('product_detail_img_list', MineNavCreater()); + WidgetFactory.regist('product_detail_img_list', DefaultWidgetCreater((model) => GoodsDetailsImgWidget(model))); // 商品详情底部推荐列表 - // WidgetFactory.regist('product_detail_bottom_rec', DefaultWidgetCreater((model) => GoodsDetailsEvaluateWidget(model))); + // WidgetFactory.regist('product_detail_bottom_rec', DefaultWidgetCreater((model) => GoodsListCreater(model))); + WidgetFactory.regist('product_detail_bottom_rec', GoodsListCreater()); // 商品详情底部 WidgetFactory.regist('product_detail_bottom', DefaultWidgetCreater((model) => GoodsDetailsFooterWidget(model))); diff --git a/lib/widgets/goods_details/coupon/bloc/counpon_bloc.dart b/lib/widgets/goods_details/coupon/bloc/counpon_bloc.dart index bf024b8..b0d2329 100644 --- a/lib/widgets/goods_details/coupon/bloc/counpon_bloc.dart +++ b/lib/widgets/goods_details/coupon/bloc/counpon_bloc.dart @@ -1,9 +1,9 @@ import 'dart:async'; -import 'dart:math'; import 'package:bloc/bloc.dart'; import 'package:zhiying_base_widget/widgets/goods_details/coupon/bloc/counpon_repository.dart'; import 'bloc.dart'; +import 'package:zhiying_comm/zhiying_comm.dart'; class CounponBloc extends Bloc<CounponEvent, CounponState> { @override @@ -25,6 +25,10 @@ class CounponBloc extends Bloc<CounponEvent, CounponState> { /// 获取数据 Stream<CounponState> _mapInitEnvetTostate(CounponInitEvent event) async* { var result = await repository.fetchParentData(event); - yield CounponLoadedState(model: result); + if(!EmptyUtil.isEmpty(result)) { + yield CounponLoadedState(model: result); + }else { + yield CounponErrorState(); + } } } diff --git a/lib/widgets/goods_details/coupon/bloc/counpon_repository.dart b/lib/widgets/goods_details/coupon/bloc/counpon_repository.dart index 4d5a4f3..0a90436 100644 --- a/lib/widgets/goods_details/coupon/bloc/counpon_repository.dart +++ b/lib/widgets/goods_details/coupon/bloc/counpon_repository.dart @@ -1,10 +1,18 @@ +import 'dart:convert'; + import 'package:zhiying_base_widget/widgets/goods_details/coupon/bloc/bloc.dart'; import 'package:zhiying_base_widget/widgets/goods_details/coupon/model/counpon_model.dart'; +import 'package:zhiying_comm/zhiying_comm.dart'; class CounponRepository { /// 获取父页面传进来的数据 Future<CounponModel> fetchParentData(CounponInitEvent event) async{ + try{ + return CounponModel.fromJson(json.decode(event.model['data'])); + }catch(e){ + Logger.log('CounponRepository e = $e'); + } return null; } diff --git a/lib/widgets/goods_details/coupon/bloc/counpon_state.dart b/lib/widgets/goods_details/coupon/bloc/counpon_state.dart index 8dcc9a0..42bcbf1 100644 --- a/lib/widgets/goods_details/coupon/bloc/counpon_state.dart +++ b/lib/widgets/goods_details/coupon/bloc/counpon_state.dart @@ -5,11 +5,13 @@ abstract class CounponState extends Equatable { const CounponState(); } +/// 初始化 class CounponInitial extends CounponState { @override List<Object> get props => []; } +/// 数据加载成功 class CounponLoadedState extends CounponState { CounponModel model; @@ -19,6 +21,7 @@ class CounponLoadedState extends CounponState { List<Object> get props => [this.model]; } +/// 数据加载失败 class CounponErrorState extends CounponState { @override List<Object> get props => []; diff --git a/lib/widgets/goods_details/coupon/counpon_sk.dart b/lib/widgets/goods_details/coupon/counpon_sk.dart index 65e33d6..6273296 100644 --- a/lib/widgets/goods_details/coupon/counpon_sk.dart +++ b/lib/widgets/goods_details/coupon/counpon_sk.dart @@ -5,7 +5,7 @@ class CounponSkeleton extends StatelessWidget { @override Widget build(BuildContext context) { return Container( - margin: const EdgeInsets.only(left: 12.5, right: 12.5), + margin: const EdgeInsets.only(left: 12.5, right: 12.5, top: 12), width: double.infinity, height: 70, child: _shimmerWidget(width: double.infinity, height: 65, radius: 7.5), diff --git a/lib/widgets/goods_details/coupon/counpon_widget.dart b/lib/widgets/goods_details/coupon/counpon_widget.dart index 0af9170..66ec81e 100644 --- a/lib/widgets/goods_details/coupon/counpon_widget.dart +++ b/lib/widgets/goods_details/coupon/counpon_widget.dart @@ -5,6 +5,7 @@ import 'package:zhiying_base_widget/widgets/goods_details/coupon/counpon_sk.dart import 'package:zhiying_base_widget/widgets/goods_details/coupon/model/counpon_model.dart'; import 'package:zhiying_comm/zhiying_comm.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:cached_network_image/cached_network_image.dart'; /// /// 优惠券widget @@ -16,26 +17,26 @@ class CounponWidget extends StatelessWidget { @override Widget build(BuildContext context) { - return Container(); - // return BlocProvider<CounponBloc>( - // create: (_) => CounponBloc(repository: CounponRepository())..add(CounponInitEvent(model: model)), - // child: CounponContainer(), - // ); + // return Container(); + return BlocProvider<CounponBloc>( + create: (_) => CounponBloc(repository: CounponRepository())..add(CounponInitEvent(model: model)), + child: CounponWidgetContainer(), + ); } } -class CounponContainer extends StatefulWidget { +class CounponWidgetContainer extends StatefulWidget { @override - _CounponContainerState createState() => _CounponContainerState(); + _CounponWidgetContainerState createState() => _CounponWidgetContainerState(); } -class _CounponContainerState extends State<CounponContainer> { +class _CounponWidgetContainerState extends State<CounponWidgetContainer> { /// 点击领取 void _onJump(CounponModel model) {} @override Widget build(BuildContext context) { - BlocConsumer<CounponBloc, CounponState>( + return BlocConsumer<CounponBloc, CounponState>( listener: (context, state) {}, buildWhen: (prev, current) { if (current is CounponErrorState) { @@ -45,10 +46,9 @@ class _CounponContainerState extends State<CounponContainer> { }, builder: (context, state) { if (state is CounponLoadedState) { - // return _getMainWdiget(state.model); + return _getMainWdiget(state.model); } - // return CounponSkeleton(); - return Container(); + return CounponSkeleton(); }, ); } @@ -60,17 +60,30 @@ class _CounponContainerState extends State<CounponContainer> { behavior: HitTestBehavior.opaque, child: Container( width: double.infinity, - margin: const EdgeInsets.only(left: 12.5, right: 12.5), - padding: const EdgeInsets.only(left: 18.5), - alignment: Alignment.centerLeft, - child: Row( - children: <Widget>[ - /// 价格 - _getPriceWidget(model), - const SizedBox(width: 7.5), - /// 有效期 - _getTimeWidget(model) - ], + color: Colors.white, + padding: const EdgeInsets.only(left: 12.5, right: 12.5, top: 12), + child: Container( + // color: Colors.red, + width: double.infinity, + padding: const EdgeInsets.only(left: 18.5, top: 12, bottom: 14), + decoration: BoxDecoration( + image: DecorationImage( + image: CachedNetworkImageProvider( + model?.bg_img ??'', + ), + fit: BoxFit.fill + ) + ), + alignment: Alignment.centerLeft, + child: Row( + children: <Widget>[ + /// 价格 + _getPriceWidget(model), + const SizedBox(width: 7.5), + /// 有效期 + _getTimeWidget(model) + ], + ), ), ), ); @@ -79,12 +92,14 @@ class _CounponContainerState extends State<CounponContainer> { /// 价格 Widget _getPriceWidget(CounponModel model) { return Row( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ /// 价格类型 - Text('¥', style: TextStyle(fontSize: 15, color: HexColor.fromHex('#FFFFFF'))), + Text(model?.price_type ?? '¥ ', style: TextStyle(fontSize: 15, color: HexColor.fromHex(model?.price_type_color ?? '#FFFFFF'))), /// 价格 - Text('100', style: TextStyle(fontSize: 30, color: HexColor.fromHex('#FFFFFF'))), + Text(model?.coupon_price ??'100', style: TextStyle(fontSize: 30, color: HexColor.fromHex(model?.coupon_price_color ?? '#FFFFFF'), fontFamily: 'Din', package: 'zhiying_base_widget')), ], ); } @@ -92,12 +107,13 @@ class _CounponContainerState extends State<CounponContainer> { /// 名称与有效期 Widget _getTimeWidget(CounponModel model) { return Column( + crossAxisAlignment: CrossAxisAlignment.start, children: <Widget>[ /// 标题 - Text('优惠券', style: TextStyle(fontSize: 17, color: HexColor.fromHex('#FFFFFF'))), + Text(model?.coupon_title ?? '优惠券', style: TextStyle(fontSize: 17, color: HexColor.fromHex( model?.coupon_title_color ?? '#FFFFFF'))), /// 到期时间 - Text('有效期至2020-10-01', style: TextStyle(fontSize: 10, color: HexColor.fromHex('#FFFFFF'))) + Text(model?.coupon_endtime ?? '有效期至2020-10-01', style: TextStyle(fontSize: 10, color: HexColor.fromHex(model?.coupon_time_color ?? '#FFFFFF'))) ], ); } diff --git a/lib/widgets/goods_details/coupon/model/counpon_model.dart b/lib/widgets/goods_details/coupon/model/counpon_model.dart index 090b814..8b6c586 100644 --- a/lib/widgets/goods_details/coupon/model/counpon_model.dart +++ b/lib/widgets/goods_details/coupon/model/counpon_model.dart @@ -1,2 +1,54 @@ +class CounponModel { + String bg_img; + String coupon_endtime; + String coupon_price; + String coupon_price_color; + String coupon_time_color; + String coupon_title; + String coupon_title_color; + String coupon_url; + String price_type; + String price_type_color; -class CounponModel{} \ No newline at end of file + CounponModel( + {this.bg_img, + this.coupon_endtime, + this.coupon_price, + this.coupon_price_color, + this.coupon_time_color, + this.coupon_title, + this.coupon_title_color, + this.coupon_url, + this.price_type, + this.price_type_color}); + + factory CounponModel.fromJson(Map<String, dynamic> json) { + return CounponModel( + bg_img: json['bg_img'], + coupon_endtime: json['coupon_endtime'], + coupon_price: json['coupon_price'], + coupon_price_color: json['coupon_price_color'], + coupon_time_color: json['coupon_time_color'], + coupon_title: json['coupon_title'], + coupon_title_color: json['coupon_title_color'], + coupon_url: json['coupon_url'], + price_type: json['price_type'], + price_type_color: json['price_type_color'], + ); + } + + Map<String, dynamic> toJson() { + final Map<String, dynamic> data = new Map<String, dynamic>(); + data['bg_img'] = this.bg_img; + data['coupon_endtime'] = this.coupon_endtime; + data['coupon_price'] = this.coupon_price; + data['coupon_price_color'] = this.coupon_price_color; + data['coupon_time_color'] = this.coupon_time_color; + data['coupon_title'] = this.coupon_title; + data['coupon_title_color'] = this.coupon_title_color; + data['coupon_url'] = this.coupon_url; + data['price_type'] = this.price_type; + data['price_type_color'] = this.price_type_color; + return data; + } +} diff --git a/lib/widgets/goods_details/detail_img/bloc/goods_details_img_bloc.dart b/lib/widgets/goods_details/detail_img/bloc/goods_details_img_bloc.dart new file mode 100644 index 0000000..2222ef6 --- /dev/null +++ b/lib/widgets/goods_details/detail_img/bloc/goods_details_img_bloc.dart @@ -0,0 +1,54 @@ +import 'dart:async'; + +import 'package:bloc/bloc.dart'; +import 'package:equatable/equatable.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:zhiying_base_widget/widgets/goods_details/detail_img/bloc/goods_details_img_repository.dart'; +import 'package:zhiying_comm/util/empty_util.dart'; +import 'package:zhiying_base_widget/widgets/goods_details/detail_img/model/goods_details_img_model.dart'; +import 'package:zhiying_comm/util/global_config.dart'; + +part 'goods_details_img_event.dart'; + +part 'goods_details_img_state.dart'; + +class GoodsDetailsImgBloc extends Bloc<GoodsDetailsImgEvent, GoodsDetailsImgState> { + GoodsDetailsImgBloc({this.repository}); + + GoodsDetailsImgRepository repository; + + @override + GoodsDetailsImgState get initialState => GoodsDetailsImgInitial(); + + @override + Stream<GoodsDetailsImgState> mapEventToState( + GoodsDetailsImgEvent event, + ) async* { + /// 初始化事件 + if (event is GoodsDetailsImgInitEvent) { + yield* _mapInitEventToState(event); + } + } + + /// 初始化方法 + Stream<GoodsDetailsImgState> _mapInitEventToState(GoodsDetailsImgInitEvent event) async* { + var parentData = await repository.fetchParentData(event.model); + if (!EmptyUtil.isEmpty(parentData)) { + yield GoodsDetailsImgLoadedState(model: parentData); + /// 如果等于淘宝类型,就前端去抓去商品详情图片 + if (parentData.provider == GlobalConfig.PROVIDER_TB || parentData.provider == GlobalConfig.PROVIDER_TM) { + /// 进行网络访问 + var netData = await repository.fetchNetData(event.model); + if (!EmptyUtil.isEmpty(netData)) { + // yield Good; + yield GoodsDetailsImgLoadedState(model: netData); + } else { + yield GoodsDetailsImgErrorState(); + } + } + + } else { + yield GoodsDetailsImgErrorState(); + } + } +} diff --git a/lib/widgets/goods_details/detail_img/bloc/goods_details_img_event.dart b/lib/widgets/goods_details/detail_img/bloc/goods_details_img_event.dart new file mode 100644 index 0000000..99a3e9c --- /dev/null +++ b/lib/widgets/goods_details/detail_img/bloc/goods_details_img_event.dart @@ -0,0 +1,18 @@ +part of 'goods_details_img_bloc.dart'; + +abstract class GoodsDetailsImgEvent extends Equatable { + const GoodsDetailsImgEvent(); + + @override + List<Object> get props => []; +} + +/// 初始化数据 +class GoodsDetailsImgInitEvent extends GoodsDetailsImgEvent { + final Map<String, dynamic> model; + + const GoodsDetailsImgInitEvent({@required this.model}); + + @override + List<Object> get props => [this.model]; +} diff --git a/lib/widgets/goods_details/detail_img/bloc/goods_details_img_repository.dart b/lib/widgets/goods_details/detail_img/bloc/goods_details_img_repository.dart new file mode 100644 index 0000000..cced390 --- /dev/null +++ b/lib/widgets/goods_details/detail_img/bloc/goods_details_img_repository.dart @@ -0,0 +1,35 @@ +import 'dart:convert'; + +import 'package:zhiying_base_widget/widgets/goods_details/detail_img/model/goods_details_img_model.dart'; +import 'package:zhiying_comm/zhiying_comm.dart'; +import 'package:zhiying_comm/util/taobao/taobao_loader.dart'; + +class GoodsDetailsImgRepository { + GoodsDetailsImgModel _model; + /// 获取父数据 + Future<GoodsDetailsImgModel> fetchParentData(final Map<String, dynamic> model) async { + try { + _model = GoodsDetailsImgModel.fromJson(jsonDecode(model['data'])); + if(!EmptyUtil.isEmpty(_model)) { + return _model; + } + } catch (e) { + Logger.log('GoodsDetailsImgRepository e = $e'); + } + return null; + } + + /// 获取网络的数据 + Future<GoodsDetailsImgModel> fetchNetData(final Map<String, dynamic> model) async { + try { + if(!EmptyUtil.isEmpty(_model)) { + List<String> imgs = await TaobaoLoader.loadImages(_model.good_id); + _model.image_detail_list = imgs; + return _model; + } + }catch(e){ + + } + return null; + } +} diff --git a/lib/widgets/goods_details/detail_img/bloc/goods_details_img_state.dart b/lib/widgets/goods_details/detail_img/bloc/goods_details_img_state.dart new file mode 100644 index 0000000..da08223 --- /dev/null +++ b/lib/widgets/goods_details/detail_img/bloc/goods_details_img_state.dart @@ -0,0 +1,30 @@ +part of 'goods_details_img_bloc.dart'; + +abstract class GoodsDetailsImgState extends Equatable { + const GoodsDetailsImgState(); + + @override + List<Object> get props => []; +} + +class GoodsDetailsImgInitial extends GoodsDetailsImgState { + @override + List<Object> get props => []; +} + +/// 数据加载成功 +class GoodsDetailsImgLoadedState extends GoodsDetailsImgState { + GoodsDetailsImgModel model; + + GoodsDetailsImgLoadedState({this.model}); + + GoodsDetailsImgLoadedState copyWith({@required GoodsDetailsImgModel newData}) { + return GoodsDetailsImgLoadedState(model: newData ?? model); + } + + @override + List<Object> get props => [this.model]; +} + +/// 数据加载失败 +class GoodsDetailsImgErrorState extends GoodsDetailsImgState {} diff --git a/lib/widgets/goods_details/detail_img/goods_details_img.dart b/lib/widgets/goods_details/detail_img/goods_details_img.dart new file mode 100644 index 0000000..7dd395d --- /dev/null +++ b/lib/widgets/goods_details/detail_img/goods_details_img.dart @@ -0,0 +1,110 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:zhiying_base_widget/widgets/goods_details/detail_img/bloc/goods_details_img_bloc.dart'; +import 'package:zhiying_base_widget/widgets/goods_details/detail_img/goods_details_img_sk.dart'; +import 'package:zhiying_base_widget/widgets/goods_details/detail_img/model/goods_details_img_model.dart'; +import 'package:zhiying_base_widget/widgets/home/home_quick_entry/cached_network_image_util.dart'; +import 'package:zhiying_comm/zhiying_comm.dart'; +import 'package:cached_network_image/cached_network_image.dart'; +import 'package:zhiying_base_widget/widgets/goods_details/detail_img/bloc/goods_details_img_repository.dart'; + +/// +/// 商品详情图片 +/// +class GoodsDetailsImgWidget extends StatelessWidget { + final Map<String, dynamic> model; + + const GoodsDetailsImgWidget(this.model); + + @override + Widget build(BuildContext context) { + return BlocProvider<GoodsDetailsImgBloc>( + create: (_) => GoodsDetailsImgBloc(repository: GoodsDetailsImgRepository())..add(GoodsDetailsImgInitEvent(model: model)), + child: GoodsDetailsImgWidgetContainer(), + ); + } +} + +class GoodsDetailsImgWidgetContainer extends StatefulWidget { + @override + _GoodsDetailsImgWidgetContainerState createState() => _GoodsDetailsImgWidgetContainerState(); +} + +class _GoodsDetailsImgWidgetContainerState extends State<GoodsDetailsImgWidgetContainer> { + @override + Widget build(BuildContext context) { + return BlocConsumer<GoodsDetailsImgBloc, GoodsDetailsImgState>( + listener: (BuildContext context, GoodsDetailsImgState state) { + if (state is GoodsDetailsImgErrorState) { + print('数据加载出错'); + } + }, + buildWhen: (previous, current) { + /// 数据加载出错不进行build + if (current is GoodsDetailsImgErrorState) { + return false; + } + return true; + }, + builder: (context, state) { + print('currente state = $state'); + if (state is GoodsDetailsImgLoadedState) { + if (!EmptyUtil.isEmpty(state.model)) { + return _getMainWidget(state.model); + } + } + // 骨架屏 + return GoodsDetailsImgSkeleton(); + }, + ); + } + + /// + Widget _getMainWidget(GoodsDetailsImgModel model) { + return Column( + children: <Widget>[ + /// 标题 + _getTitleWidget(model), + /// 图片列表 + _getImgListWidget(model), + ], + ); + } + + /// 图片列表 + Widget _getImgListWidget(GoodsDetailsImgModel model){ + return Column( + children: model.image_detail_list.map((item){ + return CachedNetworkImage( + imageUrl: item ?? '', + fit: BoxFit.fitWidth, + ); + }).toList(), + ); + } + + /// 标题Widget + Widget _getTitleWidget(GoodsDetailsImgModel model) { + return Container( + color: Colors.white, + margin: const EdgeInsets.only(top: 6), + width: double.infinity, + padding: const EdgeInsets.only(top: 15, bottom: 15, left: 12.5, right: 12.5), + child: _getLeftWidget(model), + ); + } + + /// 左边图标加文字 + Widget _getLeftWidget(GoodsDetailsImgModel model) { + return Row( + children: <Widget>[ + CachedNetworkImage( + imageUrl: model?.icon ?? '', + width: 12, + ), + const SizedBox(width: 2.5), + Text(model?.title ?? '商品详情', style: TextStyle(color: HexColor.fromHex(model?.title_color ?? '#333333'), fontSize: 12)), + ], + ); + } +} diff --git a/lib/widgets/goods_details/detail_img/goods_details_img_sk.dart b/lib/widgets/goods_details/detail_img/goods_details_img_sk.dart new file mode 100644 index 0000000..52bd89f --- /dev/null +++ b/lib/widgets/goods_details/detail_img/goods_details_img_sk.dart @@ -0,0 +1,11 @@ +import 'package:flutter/material.dart'; + +/// +/// 商品详情骨架图 +/// +class GoodsDetailsImgSkeleton extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Container(); + } +} diff --git a/lib/widgets/goods_details/detail_img/model/goods_details_img_model.dart b/lib/widgets/goods_details/detail_img/model/goods_details_img_model.dart new file mode 100644 index 0000000..d2631db --- /dev/null +++ b/lib/widgets/goods_details/detail_img/model/goods_details_img_model.dart @@ -0,0 +1,41 @@ +class GoodsDetailsImgModel { + List<String> image_detail_list; + String title; + String title_color; + String provider; + String good_id; + String icon; + + GoodsDetailsImgModel({ + this.image_detail_list, + this.title, + this.title_color, + this.provider, + this.good_id, + this.icon + }); + + factory GoodsDetailsImgModel.fromJson(Map<String, dynamic> json) { + return GoodsDetailsImgModel( + image_detail_list: json['image_detail_list'] != null ? new List<String>.from(json['image_detail_list']) : null, + title: json['title'], + title_color: json['title_color'], + provider: json['provider'], + good_id: json['good_id'], + icon: json['icon'] + ); + } + + Map<String, dynamic> toJson() { + final Map<String, dynamic> data = new Map<String, dynamic>(); + data['title'] = this.title; + data['title_color'] = this.title_color; + if (this.image_detail_list != null) { + data['image_detail_list'] = this.image_detail_list; + } + data['provider'] = this.provider; + data['good_id'] = this.good_id; + data['icon'] = this.icon; + return data; + } +} diff --git a/lib/widgets/goods_details/evaluate/goods_details_evaluate_widget.dart b/lib/widgets/goods_details/evaluate/goods_details_evaluate_widget.dart index 1f404f5..45c8192 100644 --- a/lib/widgets/goods_details/evaluate/goods_details_evaluate_widget.dart +++ b/lib/widgets/goods_details/evaluate/goods_details_evaluate_widget.dart @@ -1,4 +1,8 @@ +import 'dart:convert'; + import 'package:flutter/material.dart'; +import 'package:zhiying_base_widget/widgets/goods_details/evaluate/model/goods_details_evaluate_model.dart'; +import 'package:cached_network_image/cached_network_image.dart'; import 'package:zhiying_comm/zhiying_comm.dart'; /// @@ -6,8 +10,15 @@ import 'package:zhiying_comm/zhiying_comm.dart'; /// class GoodsDetailsEvaluateWidget extends StatelessWidget { final Map<String, dynamic> model; + GoodsDetailsEvaluateModel _modell; - const GoodsDetailsEvaluateWidget(this.model); + GoodsDetailsEvaluateWidget(this.model, {Key key}) : super(key: key) { + try { + _modell = GoodsDetailsEvaluateModel.fromJson(jsonDecode(model['data'])); + } catch (e) { + Logger.log('GoodsDetailsEvaluateWidget e = $e}'); + } + } /// 点击查看更多 void _openLookMore() {} @@ -18,21 +29,39 @@ class GoodsDetailsEvaluateWidget extends StatelessWidget { onTap: () => _openLookMore(), behavior: HitTestBehavior.opaque, child: Container( + color: Colors.white, + margin: const EdgeInsets.only(top: 6), width: double.infinity, padding: const EdgeInsets.only(top: 15, bottom: 15, left: 12.5, right: 12.5), - child: getMainWidget(), + child: getMainWidget(_modell), ), ); } /// 评价以及查看更多 - Widget getMainWidget() { + Widget getMainWidget(GoodsDetailsEvaluateModel model) { return Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: <Widget>[ - Text('宝贝评价', style: TextStyle(color: HexColor.fromHex('#333333'), fontSize: 12)), - Text('查看更多 >', style: TextStyle(color: HexColor.fromHex('#999999'), fontSize: 11)), + getLeftWidget(model), + Text(model?.more ?? '查看更多 >', style: TextStyle(color: HexColor.fromHex(model?.more_color ?? '#999999'), fontSize: 11)), + ], + ); + } + + + /// 左边图标加文字 + Widget getLeftWidget(GoodsDetailsEvaluateModel model){ + return Row( + children: <Widget>[ + CachedNetworkImage( + imageUrl: model?.icon ?? '', + width: 12, + ), + const SizedBox(width: 2.5), + Text(model?.title ?? '宝贝评价', style: TextStyle(color: HexColor.fromHex(model?.title_color ?? '#333333'), fontSize: 12)), ], ); } + } diff --git a/lib/widgets/goods_details/evaluate/model/goods_details_evaluate_model.dart b/lib/widgets/goods_details/evaluate/model/goods_details_evaluate_model.dart new file mode 100644 index 0000000..f5dafc4 --- /dev/null +++ b/lib/widgets/goods_details/evaluate/model/goods_details_evaluate_model.dart @@ -0,0 +1,39 @@ +class GoodsDetailsEvaluateModel { + String comment_url; + String more; + String more_color; + String title; + String title_color; + String icon; + + GoodsDetailsEvaluateModel({ + this.comment_url, + this.more, + this.more_color, + this.title, + this.title_color, + this.icon, + }); + + factory GoodsDetailsEvaluateModel.fromJson(Map<String, dynamic> json) { + return GoodsDetailsEvaluateModel( + comment_url: json['comment_url'], + more: json['more'], + more_color: json['more_color'], + title: json['title'], + title_color: json['title_color'], + icon: json['icon'], + ); + } + + Map<String, dynamic> toJson() { + final Map<String, dynamic> data = new Map<String, dynamic>(); + data['comment_url'] = this.comment_url; + data['more'] = this.more; + data['more_color'] = this.more_color; + data['title'] = this.title; + data['title_color'] = this.title_color; + data['icon'] = this.icon; + return data; + } +} diff --git a/lib/widgets/goods_details/footer/bloc/goods_details_footer_bloc.dart b/lib/widgets/goods_details/footer/bloc/goods_details_footer_bloc.dart new file mode 100644 index 0000000..a73b0b1 --- /dev/null +++ b/lib/widgets/goods_details/footer/bloc/goods_details_footer_bloc.dart @@ -0,0 +1,51 @@ +import 'dart:async'; + +import 'package:bloc/bloc.dart'; +import 'package:equatable/equatable.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:zhiying_base_widget/widgets/goods_details/footer/bloc/goods_details_footer_repository.dart'; +import 'package:zhiying_base_widget/widgets/goods_details/footer/model/goods_details_footer_model.dart'; +import 'package:zhiying_comm/util/empty_util.dart'; + +part 'goods_details_footer_event.dart'; + +part 'goods_details_footer_state.dart'; + +class GoodsDetailsFooterBloc extends Bloc<GoodsDetailsFooterEvent, GoodsDetailsFooterState> { + GoodsDetailsFooterBloc({this.repository}); + + GoodsDetailsFooterRepository repository; + + @override + GoodsDetailsFooterState get initialState => GoodsDetailsFooterInitial(); + + @override + Stream<GoodsDetailsFooterState> mapEventToState( + GoodsDetailsFooterEvent event, + ) async* { + /// 初始化 + if (event is GoodsDetailsFooterInitEvent) { + yield* _mapInitEventToState(event); + } + } + + /// 初始化 + Stream<GoodsDetailsFooterState> _mapInitEventToState(GoodsDetailsFooterInitEvent event) async* { + var result = await repository.fetchParentData(event.model); + if (!EmptyUtil.isEmpty(result)) { + print('result = ${result.toString()}'); + yield GoodsDetailsFooterLoadedState(model: result); + } else { + yield GoodsDetailsFooterErrorState(); + } + } + + /// 点击收藏 + Stream<GoodsDetailsFooterState> _mapCollectEventToState(GoodsDetailsFooterCollectEvent event) async* { + var result = await repository.fetchCollect(); + if (!EmptyUtil.isEmpty(result)) + yield GoodsDetailsFooterLoadedState(model: result); + else + yield GoodsDetailsFooterErrorState(); + } +} diff --git a/lib/widgets/goods_details/footer/bloc/goods_details_footer_event.dart b/lib/widgets/goods_details/footer/bloc/goods_details_footer_event.dart new file mode 100644 index 0000000..6f9f44b --- /dev/null +++ b/lib/widgets/goods_details/footer/bloc/goods_details_footer_event.dart @@ -0,0 +1,23 @@ +part of 'goods_details_footer_bloc.dart'; + +abstract class GoodsDetailsFooterEvent extends Equatable { + const GoodsDetailsFooterEvent(); + + @override + List<Object> get props => []; +} + +/// 初始化事件 +class GoodsDetailsFooterInitEvent extends GoodsDetailsFooterEvent { + final Map<String, dynamic> model; + + const GoodsDetailsFooterInitEvent({@required this.model}); + + @override + List<Object> get props => [this.model]; +} + +/// 点击收藏 +class GoodsDetailsFooterCollectEvent extends GoodsDetailsFooterEvent { + +} diff --git a/lib/widgets/goods_details/footer/bloc/goods_details_footer_repository.dart b/lib/widgets/goods_details/footer/bloc/goods_details_footer_repository.dart new file mode 100644 index 0000000..e34a8c5 --- /dev/null +++ b/lib/widgets/goods_details/footer/bloc/goods_details_footer_repository.dart @@ -0,0 +1,25 @@ +import 'dart:convert'; + +import 'package:zhiying_base_widget/widgets/goods_details/footer/model/goods_details_footer_model.dart'; +import 'package:zhiying_comm/zhiying_comm.dart'; + +class GoodsDetailsFooterRepository { + /// 初始化数据 + Future<GoodsDetailsFooterModel> fetchParentData(final Map<String, dynamic> model) async { + try { + return GoodsDetailsFooterModel.fromJson(jsonDecode(model['data'])); + } catch (e) { + Logger.log('GoodsDetailsFooterRepository e = $e'); + } + return null; + } + + /// 点击收藏 + Future<GoodsDetailsFooterModel> fetchCollect() async{ + return null; + } + + /// 跳转购买 + + /// 分享 +} diff --git a/lib/widgets/goods_details/footer/bloc/goods_details_footer_state.dart b/lib/widgets/goods_details/footer/bloc/goods_details_footer_state.dart new file mode 100644 index 0000000..ae3ae2d --- /dev/null +++ b/lib/widgets/goods_details/footer/bloc/goods_details_footer_state.dart @@ -0,0 +1,29 @@ +part of 'goods_details_footer_bloc.dart'; + +abstract class GoodsDetailsFooterState extends Equatable { + const GoodsDetailsFooterState(); + + @override + List<Object> get props => []; +} + +class GoodsDetailsFooterInitial extends GoodsDetailsFooterState { + @override + List<Object> get props => []; +} + +/// 数据加载完毕 +class GoodsDetailsFooterLoadedState extends GoodsDetailsFooterState { + GoodsDetailsFooterModel model; + + GoodsDetailsFooterLoadedState({@required this.model}); + + @override + List<Object> get props => [this.model]; +} + +/// 数据加载出错 +class GoodsDetailsFooterErrorState extends GoodsDetailsFooterState { + @override + List<Object> get props => []; +} diff --git a/lib/widgets/goods_details/footer/goods_details_footer_sk.dart b/lib/widgets/goods_details/footer/goods_details_footer_sk.dart index bf7e85e..929d91c 100644 --- a/lib/widgets/goods_details/footer/goods_details_footer_sk.dart +++ b/lib/widgets/goods_details/footer/goods_details_footer_sk.dart @@ -6,6 +6,7 @@ class GoodsDetailsFooterSkeleton extends StatelessWidget { Widget build(BuildContext context) { return Container( width: double.infinity, + color: Colors.white, padding: const EdgeInsets.only(left: 21, right: 12.5, top: 12.5, bottom: 12.5), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, @@ -18,7 +19,7 @@ class GoodsDetailsFooterSkeleton extends StatelessWidget { ], ), - _shimmerWidget( height: 44, width: 230, radius: 22), + _shimmerWidget( height: 44, width: 180, radius: 22), ], ), ); diff --git a/lib/widgets/goods_details/footer/goods_details_footer_widget.dart b/lib/widgets/goods_details/footer/goods_details_footer_widget.dart index 1ec445c..dc51d49 100644 --- a/lib/widgets/goods_details/footer/goods_details_footer_widget.dart +++ b/lib/widgets/goods_details/footer/goods_details_footer_widget.dart @@ -1,18 +1,30 @@ import 'package:flutter/material.dart'; +import 'package:zhiying_base_widget/widgets/goods_details/footer/bloc/goods_details_footer_bloc.dart'; +import 'package:zhiying_base_widget/widgets/goods_details/footer/bloc/goods_details_footer_repository.dart'; +import 'package:zhiying_base_widget/widgets/goods_details/footer/goods_details_footer_sk.dart'; +import 'package:zhiying_base_widget/widgets/goods_details/footer/model/goods_details_footer_model.dart'; import 'package:zhiying_comm/zhiying_comm.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:cached_network_image/cached_network_image.dart'; /// /// 商品详情底部Widget /// class GoodsDetailsFooterWidget extends StatelessWidget { - final Map<String, dynamic> model; const GoodsDetailsFooterWidget(this.model); @override Widget build(BuildContext context) { - return GooddsDetailsFooterContainer(); + return Visibility( + visible: !EmptyUtil.isEmpty(model), + replacement: GoodsDetailsFooterSkeleton(), + child: BlocProvider<GoodsDetailsFooterBloc>( + create: (_) => GoodsDetailsFooterBloc(repository: GoodsDetailsFooterRepository())..add(GoodsDetailsFooterInitEvent(model: model)), + child: GooddsDetailsFooterContainer(), + ), + ); } } @@ -36,38 +48,57 @@ class _GooddsDetailsFooterContainerState extends State<GooddsDetailsFooterContai @override Widget build(BuildContext context) { + return BlocConsumer<GoodsDetailsFooterBloc, GoodsDetailsFooterState>( + listener: (context, state) {}, + buildWhen: (prev, current) { + if (current is GoodsDetailsFooterErrorState) { + return false; + } + return true; + }, + builder: (context, state) { + print('GoodsDetailsFooterWidget state = $state'); + if (state is GoodsDetailsFooterLoadedState) { + return _getMainWidget(state.model); + } + return GoodsDetailsFooterSkeleton(); + }, + ); + } + + Widget _getMainWidget(GoodsDetailsFooterModel model) { return Container( height: 70, width: double.infinity, padding: const EdgeInsets.only(bottom: 10, top: 12.5, left: 21, right: 12.5), decoration: BoxDecoration( - boxShadow:[ - BoxShadow(color: Colors.grey[300], offset: Offset(0.0, 0.0), blurRadius: 5.0, spreadRadius: 2.0), - BoxShadow(color: Colors.grey[300], offset: Offset(0.0, 0.0)), - ], - color: Colors.white + // boxShadow: [ + // BoxShadow(color: Colors.grey[300], offset: Offset(0.0, 0.0), blurRadius: 5.0, spreadRadius: 2.0), + // BoxShadow(color: Colors.grey[300], offset: Offset(0.0, 0.0)), + // ], + color: Colors.white, ), - child: _getMainWidet(), + child: _getMainWidet(model), ); } /// 主Widget - Widget _getMainWidet() { + Widget _getMainWidet(GoodsDetailsFooterModel model) { return Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, crossAxisAlignment: CrossAxisAlignment.center, children: <Widget>[ /// 首页与收藏 - _getLeftWidget(), + _getLeftWidget(model), /// 分享赚与自购省 - _getRightWidget(), + _getRightWidget(model), ], ); } /// 首页 和 收藏 - Widget _getLeftWidget() { + Widget _getLeftWidget(GoodsDetailsFooterModel model) { return Row( crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.start, @@ -77,47 +108,43 @@ class _GooddsDetailsFooterContainerState extends State<GooddsDetailsFooterContai onTap: () => _openHome(), child: Padding( padding: const EdgeInsets.only(right: 35), - child: _getCustomWidget('首页', '999999', null), + child: _getCustomWidget(model?.home ?? '首页', model?.home_color ?? '999999', model?.home_icon ?? ''), )), GestureDetector( behavior: HitTestBehavior.opaque, onTap: () => _collectOnClick(), - child: Padding(padding: const EdgeInsets.only(right: 0), child: _getCustomWidget('收藏', '999999', null))) + child: Padding(padding: const EdgeInsets.only(right: 0), child: _getCustomWidget(model?.collect ?? '收藏', model?.collect_color ?? '999999', model?.collect_icon ?? ''))) ], ); } /// 分享赚与自购省 - Widget _getRightWidget() { + Widget _getRightWidget(GoodsDetailsFooterModel model) { return Row( mainAxisAlignment: MainAxisAlignment.end, crossAxisAlignment: CrossAxisAlignment.center, - children: <Widget>[_getFxzButton(), _getZgsButton()], + children: <Widget>[_getFxzButton(model), _getZgsButton(model)], ); } /// 分享赚, - Widget _getFxzButton() { + Widget _getFxzButton(GoodsDetailsFooterModel model) { return GestureDetector( onTap: () => _shareOnClick(), child: Container( alignment: Alignment.center, padding: const EdgeInsets.only(left: 30, right: 30, top: 5, bottom: 5), decoration: BoxDecoration( - gradient: LinearGradient(colors: [HexColor.fromHex('#FFCA66'), HexColor.fromHex('#FFD961')], begin: Alignment.centerLeft, end: Alignment.centerRight), - borderRadius: BorderRadius.only( - bottomLeft: Radius.circular(25), - topLeft: Radius.circular(25) - ) - ), + gradient: LinearGradient(colors: [HexColor.fromHex(model?.share_earn_bg1_color ?? '#FFCA66'), HexColor.fromHex(model?.share_earn_bg2_color ?? '#FFD961')], begin: Alignment.centerLeft, end: Alignment.centerRight), + borderRadius: BorderRadius.only(bottomLeft: Radius.circular(25), topLeft: Radius.circular(25))), child: Column( children: <Widget>[ RichText( - text: TextSpan(text: '¥', style: TextStyle(fontSize: 12, color: HexColor.fromHex('FFFFFF')), children: [ - TextSpan(text: '3.10', style: TextStyle(fontSize: 15, color: HexColor.fromHex('#FFFFFF'))), + text: TextSpan(text: '¥ ', style: TextStyle(fontSize: 12, color: HexColor.fromHex(model?.share_earn_val_color ?? 'FFFFFF')), children: [ + TextSpan(text: model?.share_value ?? '0.0', style: TextStyle(fontSize: 15, color: HexColor.fromHex(model?.share_earn_color ?? '#FFFFFF'), fontFamily: 'Din', package: 'zhiying_base_widget')), ]), ), - Text('分享赚', style: TextStyle(color: HexColor.fromHex('#FFFFFF'), fontSize: 15)) + Text(model?.share_earn ?? '分享赚', style: TextStyle(color: HexColor.fromHex(model?.share_earn_color ?? '#FFFFFF'), fontSize: 15)) ], ), ), @@ -125,7 +152,7 @@ class _GooddsDetailsFooterContainerState extends State<GooddsDetailsFooterContai } /// 自购省 - Widget _getZgsButton() { + Widget _getZgsButton(GoodsDetailsFooterModel model) { return GestureDetector( behavior: HitTestBehavior.opaque, onTap: () => _savemoneyOnClick(), @@ -133,20 +160,23 @@ class _GooddsDetailsFooterContainerState extends State<GooddsDetailsFooterContai alignment: Alignment.center, padding: const EdgeInsets.only(left: 30, right: 30, top: 5, bottom: 5), decoration: BoxDecoration( - gradient: LinearGradient(colors: [HexColor.fromHex('#FF6969'), HexColor.fromHex('#FF4646')], begin: Alignment.centerLeft, end: Alignment.centerRight), - borderRadius: BorderRadius.only( - bottomRight: Radius.circular(25), - topRight: Radius.circular(25) - ) - ), + gradient: LinearGradient(colors: [HexColor.fromHex(model?.save_earn_bg1_color ?? '#FF6969'), HexColor.fromHex(model?.save_earn_bg2_color ?? '#FF4646')], begin: Alignment.centerLeft, end: Alignment.centerRight), + borderRadius: BorderRadius.only(bottomRight: Radius.circular(25), topRight: Radius.circular(25))), child: Column( children: <Widget>[ RichText( - text: TextSpan(text: '¥', style: TextStyle(fontSize: 12, color: HexColor.fromHex('FFFFFF')), children: [ - TextSpan(text: '23.10', style: TextStyle(fontSize: 15, color: HexColor.fromHex('#FFFFFF'))), + text: TextSpan(text: '¥ ', style: TextStyle(fontSize: 12, color: HexColor.fromHex(model?.save_earn_val_color ?? 'FFFFFF')), children: [ + TextSpan( + text: model?.slef_buy_value ??'0.0', + style: TextStyle( + fontSize: 15, + color: HexColor.fromHex(model?.save_earn_val_color ?? '#FFFFFF'), + fontFamily: 'Din', + package: 'zhiying_base_widget', + )), ]), ), - Text('自购省', style: TextStyle(color: HexColor.fromHex('#FFFFFF'), fontSize: 15)) + Text(model?.save_earn ?? '自购省', style: TextStyle(color: HexColor.fromHex(model?.save_earn_color ?? '#FFFFFF'), fontSize: 15)) ], ), ), @@ -159,8 +189,14 @@ class _GooddsDetailsFooterContainerState extends State<GooddsDetailsFooterContai mainAxisAlignment: MainAxisAlignment.end, children: <Widget>[ /// 图标 - Container(height: 25, width: 25, color: Colors.red, margin: const EdgeInsets.only(bottom: 3)), - + CachedNetworkImage( + imageUrl: icon, + fit: BoxFit.fill, + width: 25, + height: 25, + ), + // Container( width: 25, margin: const EdgeInsets.only(bottom: 3), child: CachedNetworkImage(imageUrl: icon, fit: BoxFit.fill, width: 25,),), + const SizedBox(height: 3), /// 图片 Text(text, style: TextStyle(color: HexColor.fromHex(textColor), fontSize: 11)) ], diff --git a/lib/widgets/goods_details/footer/model/goods_details_footer_model.dart b/lib/widgets/goods_details/footer/model/goods_details_footer_model.dart new file mode 100644 index 0000000..2bc7836 --- /dev/null +++ b/lib/widgets/goods_details/footer/model/goods_details_footer_model.dart @@ -0,0 +1,69 @@ + +class GoodsDetailsFooterModel { + String collect; + String collect_color; + String collect_icon; + String home; + String home_color; + String home_icon; + String save_earn; + String save_earn_bg1_color; + String save_earn_bg2_color; + String save_earn_color; + String save_earn_val_color; + String share_earn; + String share_earn_bg1_color; + String share_earn_bg2_color; + String share_earn_color; + String share_earn_val_color; + String share_value; + String slef_buy_value; + + GoodsDetailsFooterModel({this.collect, this.collect_color, this.collect_icon, this.home, this.home_color, this.home_icon, this.save_earn, this.save_earn_bg1_color, this.save_earn_bg2_color, this.save_earn_color, this.save_earn_val_color, this.share_earn, this.share_earn_bg1_color, this.share_earn_bg2_color, this.share_earn_color, this.share_earn_val_color, this.share_value, this.slef_buy_value}); + + factory GoodsDetailsFooterModel.fromJson(Map<String, dynamic> json) { + return GoodsDetailsFooterModel( + collect: json['collect'], + collect_color: json['collect_color'], + collect_icon: json['collect_icon'], + home: json['home'], + home_color: json['home_color'], + home_icon: json['home_icon'], + save_earn: json['save_earn'], + save_earn_bg1_color: json['save_earn_bg1_color'], + save_earn_bg2_color: json['save_earn_bg2_color'], + save_earn_color: json['save_earn_color'], + save_earn_val_color: json['save_earn_val_color'], + share_earn: json['share_earn'], + share_earn_bg1_color: json['share_earn_bg1_color'], + share_earn_bg2_color: json['share_earn_bg2_color'], + share_earn_color: json['share_earn_color'], + share_earn_val_color: json['share_earn_val_color'], + share_value: json['share_value'], + slef_buy_value: json['slef_buy_value'], + ); + } + + Map<String, dynamic> toJson() { + final Map<String, dynamic> data = new Map<String, dynamic>(); + data['collect'] = this.collect; + data['collect_color'] = this.collect_color; + data['collect_icon'] = this.collect_icon; + data['home'] = this.home; + data['home_color'] = this.home_color; + data['home_icon'] = this.home_icon; + data['save_earn'] = this.save_earn; + data['save_earn_bg1_color'] = this.save_earn_bg1_color; + data['save_earn_bg2_color'] = this.save_earn_bg2_color; + data['save_earn_color'] = this.save_earn_color; + data['save_earn_val_color'] = this.save_earn_val_color; + data['share_earn'] = this.share_earn; + data['share_earn_bg1_color'] = this.share_earn_bg1_color; + data['share_earn_bg2_color'] = this.share_earn_bg2_color; + data['share_earn_color'] = this.share_earn_color; + data['share_earn_val_color'] = this.share_earn_val_color; + data['share_value'] = this.share_value; + data['slef_buy_value'] = this.slef_buy_value; + return data; + } +} \ No newline at end of file diff --git a/lib/widgets/goods_details/price/goods_details_price_widget.dart b/lib/widgets/goods_details/price/goods_details_price_widget.dart index 36d22ca..2cc70f3 100644 --- a/lib/widgets/goods_details/price/goods_details_price_widget.dart +++ b/lib/widgets/goods_details/price/goods_details_price_widget.dart @@ -1,4 +1,7 @@ +import 'dart:convert'; + import 'package:flutter/material.dart'; +import 'package:zhiying_base_widget/widgets/goods_details/price/model/goods_details_price_model.dart'; import 'package:zhiying_comm/zhiying_comm.dart'; /// @@ -6,78 +9,91 @@ import 'package:zhiying_comm/zhiying_comm.dart'; /// class GoodsDetailsPriceWidget extends StatelessWidget { final Map<String, dynamic> model; - - const GoodsDetailsPriceWidget(this.model); + GoodsDetailsPriceModel _model; + GoodsDetailsPriceWidget(this.model, {Key key}) : super(key: key){ + try{ + _model = GoodsDetailsPriceModel.fromJson(jsonDecode(model['data'])); + }catch(e){ + Logger.log('GoodsDetailsPriceWidget e = $e'); + } + } @override Widget build(BuildContext context) { - return Container(margin: const EdgeInsets.symmetric(horizontal: 12.5), child: _getMainWidget()); + return Container( + width: double.infinity, + color: Colors.white, + padding: const EdgeInsets.only(left: 12.5, right: 12.5, top: 7.5), + child: _getMainWidget(_model), + ); } /// 主体视图 - Widget _getMainWidget() { + Widget _getMainWidget(GoodsDetailsPriceModel model) { return Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: <Widget>[ - _getLeftWidget(), + _getLeftWidget(model), /// 右边widget - _getBuyNumberWidget(), + _getBuyNumberWidget(model), ], ); } /// 左边的wiget 包括价格等 - Widget _getLeftWidget() { + Widget _getLeftWidget(GoodsDetailsPriceModel model) { return Row( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.center, children: <Widget>[ /// 价格 - _getPriceWidget(), + _getPriceWidget(model), const SizedBox(width: 5), /// 券后 - _getQhPriceWidget(), + _getQhPriceWidget(model), const SizedBox(width: 5), /// 积分 - _getPointsWidget() + Visibility( + visible: !EmptyUtil.isEmpty(model?.point), + child: _getPointsWidget(model)) ], ); } /// 价格 - Widget _getPriceWidget() { + Widget _getPriceWidget(GoodsDetailsPriceModel model) { return Row( children: <Widget>[ - Text('¥', style: TextStyle(color: HexColor.fromHex('#FF4242'), fontSize: 15)), - Text('99', style: TextStyle(color: HexColor.fromHex('#FF4242'), fontSize: 30)), + Text(model?.symbol ?? '¥ ', style: TextStyle(color: HexColor.fromHex( model?.price_color ??'#FF4242'), fontSize: 15)), + Text(model?.current_price ?? '0', style: TextStyle(color: HexColor.fromHex(model?.price_color ?? '#FF4242'), fontSize: 30, fontFamily: 'Din', package: 'zhiying_base_widget')), ], ); } /// 积分 - Widget _getPointsWidget() { + Widget _getPointsWidget(GoodsDetailsPriceModel model) { return Container( - decoration: BoxDecoration(color: HexColor.fromHex('#FFEFDA'), borderRadius: BorderRadius.circular(5)), + decoration: BoxDecoration(color: HexColor.fromHex(model?.points_bg_color ?? '#FFEFDA'), borderRadius: BorderRadius.circular(5)), padding: const EdgeInsets.only(left: 4, right: 7.5, top: 4, bottom: 4), - child: Text('', style: TextStyle(color: HexColor.fromHex('#B78107'), fontSize: 9)), + child: Text(model?.point ?? '+ 0.00 积分', style: TextStyle(color: HexColor.fromHex( model?.points_color ?? '#B78107'), fontSize: 9, fontFamily: 'Din', package: 'zhiying_base_widget')), ); } /// 券后价格 - Widget _getQhPriceWidget() { + Widget _getQhPriceWidget(GoodsDetailsPriceModel model) { return Column( children: <Widget>[ - Text('券后', style: TextStyle(color: HexColor.fromHex('#FF4242'), fontSize: 11)), - Text('¥ 199', style: TextStyle(color: HexColor.fromHex('#FF4242'), fontSize: 10)), + Text(model?.ticket ?? '券后', style: TextStyle(color: HexColor.fromHex(model?.ticket_color ?? '#FF4242'), fontSize: 11)), + Text('${model?.symbol}${model?.market_price}' ?? '¥ 199', style: TextStyle(color: HexColor.fromHex(model?.ticket_price_color ?? '#FF4242'), fontSize: 10, fontFamily: 'Din', package: 'zhiying_base_widget', decoration: TextDecoration.lineThrough)), ], ); } /// 购买人数 - Widget _getBuyNumberWidget() { - return Text('99999人已购买', style: TextStyle(color: HexColor.fromHex('#999999'), fontSize: 12.5)); + Widget _getBuyNumberWidget(GoodsDetailsPriceModel model) { + return Text('${model?.sold_count}${model?.buy_text}' ?? '99999人已购买', style: TextStyle(color: HexColor.fromHex(model?.buy_color ?? '#999999'), fontSize: 12.5)); } } diff --git a/lib/widgets/goods_details/price/model/goods_details_price_model.dart b/lib/widgets/goods_details/price/model/goods_details_price_model.dart new file mode 100644 index 0000000..1a6f962 --- /dev/null +++ b/lib/widgets/goods_details/price/model/goods_details_price_model.dart @@ -0,0 +1,71 @@ +class GoodsDetailsPriceModel { + String buy_color; + String buy_text; + String current_price; + String good_id; + String market_price; + String point; + String points_bg_color; + String points_color; + String sold_count; + String ticket; + String ticket_color; + String ticket_price_color; + String price_color; + String symbol; + + + GoodsDetailsPriceModel( + {this.buy_color, + this.buy_text, + this.current_price, + this.good_id, + this.market_price, + this.point, + this.points_bg_color, + this.points_color, + this.sold_count, + this.ticket, + this.ticket_color, + this.ticket_price_color, + this.price_color, + this.symbol}); + + factory GoodsDetailsPriceModel.fromJson(Map<String, dynamic> json) { + return GoodsDetailsPriceModel( + buy_color: json['buy_color'], + buy_text: json['buy_text'], + current_price: json['current_price'], + good_id: json['good_id'], + market_price: json['market_price'], + point: json['point'], + points_bg_color: json['points_bg_color'], + points_color: json['points_color'], + sold_count: json['sold_count'], + ticket: json['ticket'], + ticket_color: json['ticket_color'], + ticket_price_color: json['ticket_price_color'], + price_color: json['price_color'], + symbol: json['symbol'], + ); + } + + Map<String, dynamic> toJson() { + final Map<String, dynamic> data = new Map<String, dynamic>(); + data['buy_color'] = this.buy_color; + data['buy_text'] = this.buy_text; + data['current_price'] = this.current_price; + data['good_id'] = this.good_id; + data['market_price'] = this.market_price; + data['point'] = this.point; + data['points_bg_color'] = this.points_bg_color; + data['points_color'] = this.points_color; + data['sold_count'] = this.sold_count; + data['ticket'] = this.ticket; + data['ticket_color'] = this.ticket_color; + data['ticket_price_color'] = this.ticket_price_color; + data['price_color'] = this.price_color; + data['symbol'] = this.symbol; + return data; + } +} diff --git a/lib/widgets/goods_details/slide_banner/bloc/goods_details_slide_banner_bloc.dart b/lib/widgets/goods_details/slide_banner/bloc/goods_details_slide_banner_bloc.dart index de1fd8f..66c0295 100644 --- a/lib/widgets/goods_details/slide_banner/bloc/goods_details_slide_banner_bloc.dart +++ b/lib/widgets/goods_details/slide_banner/bloc/goods_details_slide_banner_bloc.dart @@ -35,12 +35,13 @@ class GoodsDetailsSlideBannerBloc extends Bloc<GoodsDetailsSlideBannerEvent, Goo var parentData = await repository.fetchParentData(event.model); if (!EmptyUtil.isEmpty(parentData)) { yield GoodsDetailsSlideBannerLoadedState(model: parentData); - return; - } - var netData = await repository.fetchNetData(event.model); - if (!EmptyUtil.isEmpty(netData)) - yield GoodsDetailsSlideBannerLoadedState(model: parentData); - else + }else{ yield GoodsDetailsSlideBannerErrorState(); + } + // var netData = await repository.fetchNetData(event.model); + // if (!EmptyUtil.isEmpty(netData)) + // yield GoodsDetailsSlideBannerLoadedState(model: parentData); + // else + // yield GoodsDetailsSlideBannerErrorState(); } } diff --git a/lib/widgets/goods_details/slide_banner/bloc/goods_details_slide_banner_repository.dart b/lib/widgets/goods_details/slide_banner/bloc/goods_details_slide_banner_repository.dart index c43c29a..a6a49a0 100644 --- a/lib/widgets/goods_details/slide_banner/bloc/goods_details_slide_banner_repository.dart +++ b/lib/widgets/goods_details/slide_banner/bloc/goods_details_slide_banner_repository.dart @@ -1,3 +1,5 @@ +import 'dart:convert'; + import 'package:zhiying_base_widget/widgets/goods_details/slide_banner/model/goods_details_silde_banner_model.dart'; import 'package:zhiying_comm/zhiying_comm.dart'; @@ -6,9 +8,9 @@ class GoodsDetailsSlideBannerRepository { Future<GoodsDetailsSlideBannerModel> fetchParentData(final Map<String, dynamic> model) async { if (!EmptyUtil.isEmpty(model)) { try { - return GoodsDetailsSlideBannerModel.fromJson(model['data']); + return GoodsDetailsSlideBannerModel.fromJson(jsonDecode(model['data'])); } catch (e) { - Logger.log(e); + Logger.log('GoodsDetailsSlideBannerRepository = $e'); } } return null; diff --git a/lib/widgets/goods_details/slide_banner/goods_details_slide_banner_widget.dart b/lib/widgets/goods_details/slide_banner/goods_details_slide_banner_widget.dart index c1abccf..de9b966 100644 --- a/lib/widgets/goods_details/slide_banner/goods_details_slide_banner_widget.dart +++ b/lib/widgets/goods_details/slide_banner/goods_details_slide_banner_widget.dart @@ -36,7 +36,7 @@ class GoodsDetailsSlideBannerContainer extends StatefulWidget { class _GoodsDetailsSlideBannerContainerState extends State<GoodsDetailsSlideBannerContainer> { /// 子元素点击事件 - void _itemOnClick(IndexCarousel model) { + void _itemOnClick(String model) { print('点击了 $model'); } @@ -58,7 +58,7 @@ class _GoodsDetailsSlideBannerContainerState extends State<GoodsDetailsSlideBann builder: (context, state) { print('currente state = $state'); if (state is GoodsDetailsSlideBannerLoadedState) { - if (!EmptyUtil.isEmpty(state.model) && !EmptyUtil.isEmpty(state.model.index_carousel_list)) { + if (!EmptyUtil.isEmpty(state.model) && !EmptyUtil.isEmpty(state.model.image_list)) { return _getMainWidget(state.model); } } @@ -75,17 +75,17 @@ class _GoodsDetailsSlideBannerContainerState extends State<GoodsDetailsSlideBann height: 375, child: Swiper( itemBuilder: (BuildContext context, int index) { - IndexCarousel items = datas.index_carousel_list[index]; + String items = datas.image_list[index]; return Container( width: double.infinity, - child: CachedNetworkImage(imageUrl: items?.img ?? '', fit: BoxFit.cover), + child: CachedNetworkImage(imageUrl: items ?? '', fit: BoxFit.cover), ); }, - itemCount: datas?.index_carousel_list?.length ?? 0, + itemCount: datas?.image_list?.length ?? 0, loop: true, autoplay: true, - onTap: (index) => _itemOnClick(datas.index_carousel_list[index]), - pagination: _getSwiperStyleByType(datas, datas?.index_carousel_list?.length ?? 0), + onTap: (index) => _itemOnClick(datas.image_list[index]), + pagination: _getSwiperStyleByType(datas, datas?.image_list?.length ?? 0), ), ); } diff --git a/lib/widgets/goods_details/slide_banner/model/goods_details_silde_banner_model.dart b/lib/widgets/goods_details/slide_banner/model/goods_details_silde_banner_model.dart index 40f1dd9..c02e769 100644 --- a/lib/widgets/goods_details/slide_banner/model/goods_details_silde_banner_model.dart +++ b/lib/widgets/goods_details/slide_banner/model/goods_details_silde_banner_model.dart @@ -1,61 +1,36 @@ - - class GoodsDetailsSlideBannerModel { - String pagination; - String pagination_open; - List<String> pagination_options; - List<IndexCarousel> index_carousel_list; - String pagination_select_color; - String pagination_unselect_color; - - GoodsDetailsSlideBannerModel({this.pagination, this.pagination_open, this.pagination_options, this.pagination_select_color, this.pagination_unselect_color, this.index_carousel_list}); - - factory GoodsDetailsSlideBannerModel.fromJson(Map<String, dynamic> json) { - return GoodsDetailsSlideBannerModel( - pagination: json['pagination'], - pagination_open: json['pagination_open'], - pagination_options: json['pagination_options'] != null ? new List<String>.from(json['pagination_options']) : null, - index_carousel_list: json['index_carousel_list'] != null ? (json['index_carousel_list'] as List).map((i) => IndexCarousel.fromJson(i)).toList() : null, - pagination_select_color: json['pagination_select_color'], - pagination_unselect_color: json['pagination_unselect_color'], - - ); - } - - Map<String, dynamic> toJson() { - final Map<String, dynamic> data = new Map<String, dynamic>(); - data['pagination'] = this.pagination; - data['pagination_open'] = this.pagination_open; - data['pagination_select_color'] = this.pagination_select_color; - data['pagination_unselect_color'] = this.pagination_unselect_color; - if (this.pagination_options != null) { - data['pagination_options'] = this.pagination_options; + List<String> image_list; + String pagination; + String pagination_open; + List<String> pagination_options; + String pagination_select_color; + String pagination_unselect_color; + + GoodsDetailsSlideBannerModel({this.image_list, this.pagination, this.pagination_open, this.pagination_options, this.pagination_select_color, this.pagination_unselect_color}); + + factory GoodsDetailsSlideBannerModel.fromJson(Map<String, dynamic> json) { + return GoodsDetailsSlideBannerModel( + image_list: json['image_list'] != null ? new List<String>.from(json['image_list']) : null, + pagination: json['pagination'], + pagination_open: json['pagination_open'], + pagination_options: json['pagination_options'] != null ? new List<String>.from(json['pagination_options']) : null, + pagination_select_color: json['pagination_select_color'], + pagination_unselect_color: json['pagination_unselect_color'], + ); } - if (this.index_carousel_list != null) { - data['index_carousel_list'] = this.index_carousel_list.map((v) => v.toJson()).toList(); - } - return data; - } -} - - -class IndexCarousel { - String img; - String skip_identifier; - IndexCarousel({this.img, this.skip_identifier}); - - factory IndexCarousel.fromJson(Map<String, dynamic> json) { - return IndexCarousel( - img: json['img'], - skip_identifier: json['skip_identifier'], - ); - } - - Map<String, dynamic> toJson() { - final Map<String, dynamic> data = new Map<String, dynamic>(); - data['img'] = this.img; - data['skip_identifier'] = this.skip_identifier; - return data; - } + Map<String, dynamic> toJson() { + final Map<String, dynamic> data = new Map<String, dynamic>(); + data['pagination'] = this.pagination; + data['pagination_open'] = this.pagination_open; + data['pagination_select_color'] = this.pagination_select_color; + data['pagination_unselect_color'] = this.pagination_unselect_color; + if (this.image_list != null) { + data['image_list'] = this.image_list; + } + if (this.pagination_options != null) { + data['pagination_options'] = this.pagination_options; + } + return data; + } } \ No newline at end of file diff --git a/lib/widgets/goods_details/store/bloc/store_bloc.dart b/lib/widgets/goods_details/store/bloc/store_bloc.dart index 37a23fd..38d4f58 100644 --- a/lib/widgets/goods_details/store/bloc/store_bloc.dart +++ b/lib/widgets/goods_details/store/bloc/store_bloc.dart @@ -1,8 +1,7 @@ import 'dart:async'; import 'package:bloc/bloc.dart'; import 'package:zhiying_base_widget/widgets/goods_details/store/bloc/store_repository.dart'; -import 'package:zhiying_comm/util/empty_util.dart' - ''; +import 'package:zhiying_comm/util/empty_util.dart'; import 'bloc.dart'; @@ -29,15 +28,21 @@ class StoreBloc extends Bloc<StoreEvent, StoreState> { /// 获取数据 Stream<StoreState> _mapInitEventToState(StoreInitEvent event) async*{ var result = await repository.fetchParentData(event); - if(!EmptyUtil.isEmpty(result)){ + if(!EmptyUtil.isEmpty(result)) { yield StoreLoadedState(model: result); - return; - } - var net = await repository.fetchNetData(event); - if(!EmptyUtil.isEmpty(net)) - yield StoreLoadedState(model: result); - else + }else{ yield StoreErrorState(); + } + + // if(!EmptyUtil.isEmpty(result)){ + // yield StoreLoadedState(model: result); + // return; + // } + // var net = await repository.fetchNetData(event); + // if(!EmptyUtil.isEmpty(net)) + // yield StoreLoadedState(model: result); + // else + // yield StoreErrorState(); } } diff --git a/lib/widgets/goods_details/store/bloc/store_event.dart b/lib/widgets/goods_details/store/bloc/store_event.dart index f7c8642..ab8a392 100644 --- a/lib/widgets/goods_details/store/bloc/store_event.dart +++ b/lib/widgets/goods_details/store/bloc/store_event.dart @@ -1,4 +1,5 @@ import 'package:equatable/equatable.dart'; +import 'package:flutter/cupertino.dart'; abstract class StoreEvent extends Equatable { const StoreEvent(); @@ -6,6 +7,10 @@ abstract class StoreEvent extends Equatable { /// 初始化事件 class StoreInitEvent extends StoreEvent { + + final Map<String, dynamic> model; + const StoreInitEvent({@required this.model}); + @override - List<Object> get props => []; + List<Object> get props => [this.model]; } diff --git a/lib/widgets/goods_details/store/bloc/store_repository.dart b/lib/widgets/goods_details/store/bloc/store_repository.dart index 46d56ad..81ad582 100644 --- a/lib/widgets/goods_details/store/bloc/store_repository.dart +++ b/lib/widgets/goods_details/store/bloc/store_repository.dart @@ -1,9 +1,18 @@ +import 'dart:convert'; + import 'package:zhiying_base_widget/widgets/goods_details/store/bloc/bloc.dart'; import 'package:zhiying_base_widget/widgets/goods_details/store/model/store_model.dart'; +import 'package:zhiying_comm/zhiying_comm.dart'; class StoreRepository { /// 获取上级数据 - Future<StoreModel> fetchParentData(StoreInitEvent event) async {} + Future<StoreModel> fetchParentData(StoreInitEvent event) async { + try { + return StoreModel.fromJson(json.decode(event.model['data'])); + } catch (e) { + Logger.log('StoreRepository e= $e'); + } + } /// 网络数据 Future<StoreModel> fetchNetData(StoreInitEvent event) async {} diff --git a/lib/widgets/goods_details/store/model/store_model.dart b/lib/widgets/goods_details/store/model/store_model.dart index a3200a9..a21cb72 100644 --- a/lib/widgets/goods_details/store/model/store_model.dart +++ b/lib/widgets/goods_details/store/model/store_model.dart @@ -1,3 +1,54 @@ +class StoreModel { + String description; + String description_color; + String description_leve_icon; + String logistics; + String logistics_color; + String logistics_leve_icon; + String more; + String service; + String service_color; + String service_leve_icon; + String shop_id; + String shop_name; + String shop_name_color; -class StoreModel{} \ No newline at end of file + StoreModel({this.description, this.description_color, this.description_leve_icon, this.logistics, this.logistics_color, this.logistics_leve_icon, this.more, this.service, this.service_color, this.service_leve_icon, this.shop_id, this.shop_name, this.shop_name_color}); + + factory StoreModel.fromJson(Map<String, dynamic> json) { + return StoreModel( + description: json['description'], + description_color: json['description_color'], + description_leve_icon: json['description_leve_icon'], + logistics: json['logistics'], + logistics_color: json['logistics_color'], + logistics_leve_icon: json['logistics_leve_icon'], + more: json['more'], + service: json['service'], + service_color: json['service_color'], + service_leve_icon: json['service_leve_icon'], + shop_id: json['shop_id'], + shop_name: json['shop_name'], + shop_name_color: json['shop_name_color'], + ); + } + + Map<String, dynamic> toJson() { + final Map<String, dynamic> data = new Map<String, dynamic>(); + data['description'] = this.description; + data['description_color'] = this.description_color; + data['description_leve_icon'] = this.description_leve_icon; + data['logistics'] = this.logistics; + data['logistics_color'] = this.logistics_color; + data['logistics_leve_icon'] = this.logistics_leve_icon; + data['more'] = this.more; + data['service'] = this.service; + data['service_color'] = this.service_color; + data['service_leve_icon'] = this.service_leve_icon; + data['shop_id'] = this.shop_id; + data['shop_name'] = this.shop_name; + data['shop_name_color'] = this.shop_name_color; + return data; + } +} \ No newline at end of file diff --git a/lib/widgets/goods_details/store/store_sk.dart b/lib/widgets/goods_details/store/store_sk.dart index c3017bc..053e05e 100644 --- a/lib/widgets/goods_details/store/store_sk.dart +++ b/lib/widgets/goods_details/store/store_sk.dart @@ -6,6 +6,7 @@ class StoreSkeleton extends StatelessWidget { Widget build(BuildContext context) { return Container( height: 50, + margin: const EdgeInsets.only(left: 12.5, right: 12.5, top: 20), width: double.infinity, child: Row( mainAxisAlignment: MainAxisAlignment.start, @@ -14,9 +15,11 @@ class StoreSkeleton extends StatelessWidget { /// 图片 _shimmerWidget(width: 50, height: 50), + const SizedBox(width: 10), /// Column( mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.start, children: <Widget>[ _shimmerWidget(width: 150, height: 20), diff --git a/lib/widgets/goods_details/store/store_widget.dart b/lib/widgets/goods_details/store/store_widget.dart index de3e999..af3f37e 100644 --- a/lib/widgets/goods_details/store/store_widget.dart +++ b/lib/widgets/goods_details/store/store_widget.dart @@ -2,6 +2,7 @@ import 'package:flutter/material.dart'; import 'package:zhiying_base_widget/widgets/goods_details/store/bloc/bloc.dart'; import 'package:zhiying_base_widget/widgets/goods_details/store/bloc/store_repository.dart'; import 'package:zhiying_base_widget/widgets/goods_details/store/model/store_model.dart'; +import 'package:cached_network_image/cached_network_image.dart'; import 'package:zhiying_comm/zhiying_comm.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; @@ -18,7 +19,7 @@ class StoreWidget extends StatelessWidget { @override Widget build(BuildContext context) { return BlocProvider<StoreBloc>( - create: (_) => StoreBloc(repository: StoreRepository())..add(StoreInitEvent()), + create: (_) => StoreBloc(repository: StoreRepository())..add(StoreInitEvent(model: model)), child: StoreContainer(), ); } @@ -30,16 +31,11 @@ class StoreContainer extends StatefulWidget { } class _StoreContainerState extends State<StoreContainer> { - /// 点击更多 - void _onMoreClick(){ - - } + void _onMoreClick() {} /// 点击商家 - void _onStoreClick(){ - - } + void _onStoreClick() {} @override Widget build(BuildContext context) { @@ -63,14 +59,18 @@ class _StoreContainerState extends State<StoreContainer> { /// 主视图 Widget _getMianWidget(StoreModel model) { return Container( - margin: const EdgeInsets.only(left: 12.5, right: 12.5), + color: Colors.white, + width: double.infinity, + height: 50 + 20.0 + 18, + padding: const EdgeInsets.only(left: 12.5, right: 12.5, top: 20, bottom: 18), child: Row( children: <Widget>[ /// 商家图片 _getStoreImgWidget(model), - + const SizedBox(width: 7.5), Expanded( child: Column( + crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.spaceBetween, children: <Widget>[ /// 商店名称与更多 @@ -98,19 +98,14 @@ class _StoreContainerState extends State<StoreContainer> { /// 商店名称 Widget _getStoreNameWidget(StoreModel model) { return Row( + crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.spaceBetween, children: <Widget>[ /// 商店名称 - Text( - '品胜京东自营旗舰店', - style: TextStyle(color: HexColor.fromHex('#333333'), fontSize: 13), - ), + Text(model?.shop_name ?? '品胜京东自营旗舰店', style: TextStyle(color: HexColor.fromHex(model?.shop_name_color ?? '#333333'), fontSize: 13, fontWeight: FontWeight.bold)), /// 更多 - Text( - '更多店铺优惠 >', - style: TextStyle(color: HexColor.fromHex('#FF4242'), fontSize: 11), - ), + Text(model?.more ?? '更多店铺优惠 >', style: TextStyle(color: HexColor.fromHex('#FF4242'), fontSize: 11)), ], ); } @@ -121,13 +116,13 @@ class _StoreContainerState extends State<StoreContainer> { mainAxisAlignment: MainAxisAlignment.spaceBetween, children: <Widget>[ /// 宝贝描述 5.0 - _getCoustomWidet('宝贝描述 5.0', '#999999', ''), + _getCoustomWidet(model?.description ?? '宝贝描述 5.0',model?.description_color ?? '#999999', model?.description_leve_icon ?? ''), /// 物流服务 5.0 - _getCoustomWidet('宝贝描述 5.0', '#999999', ''), + _getCoustomWidet(model?.logistics ?? '宝贝描述 5.0', model?.logistics_color ?? '#999999', model?.logistics_leve_icon ?? ''), /// 服务态度 1.0 - _getCoustomWidet('宝贝描述 5.0', '#999999', ''), + _getCoustomWidet(model?.service ?? '宝贝描述 5.0', model?.service_color ?? '#999999', model?.service_leve_icon ?? ''), ], ); } @@ -136,10 +131,15 @@ class _StoreContainerState extends State<StoreContainer> { return Row( children: <Widget>[ Text(text, style: TextStyle(fontSize: 11, color: HexColor.fromHex(textColor))), + const SizedBox(width: 3), Container( width: 12, height: 12, - color: Colors.red, + // color: Colors.red, + child: CachedNetworkImage( + imageUrl: icon ?? '', + + ), ), ], ); diff --git a/lib/widgets/goods_details/title/goods_details_title_widget.dart b/lib/widgets/goods_details/title/goods_details_title_widget.dart index 17a9a32..47083c3 100644 --- a/lib/widgets/goods_details/title/goods_details_title_widget.dart +++ b/lib/widgets/goods_details/title/goods_details_title_widget.dart @@ -1,4 +1,7 @@ +import 'dart:convert'; + import 'package:flutter/material.dart'; +import 'package:zhiying_base_widget/widgets/goods_details/title/model/goods_details_title_model.dart'; import 'package:zhiying_comm/zhiying_comm.dart'; /// @@ -6,43 +9,92 @@ import 'package:zhiying_comm/zhiying_comm.dart'; /// class GoodsDetailsTitleWidget extends StatelessWidget { final Map<String, dynamic> model; + GoodsDetailsTitleModel _model; - const GoodsDetailsTitleWidget(this.model); + GoodsDetailsTitleWidget(this.model, {Key key}) : super(key: key) { + try { + _model = GoodsDetailsTitleModel.fromJson(jsonDecode(model['data'])); + } catch (e) { + Logger.log('GoodsDetailsTitleWidget e = $e'); + } + } @override Widget build(BuildContext context) { return Container( width: double.infinity, - margin: const EdgeInsets.only(left: 12.5, right: 12.5), - child: _getMaiWidget(), + color: Colors.white, + padding: const EdgeInsets.only(left: 12.5, right: 12.5, top: 6.5), + child: _getMaiWidget(_model), ); } /// 主widget - Widget _getMaiWidget() { - return RichText( - maxLines: 2, - overflow: TextOverflow.ellipsis, - text: TextSpan(children: [ - WidgetSpan( - child: _getGoodsTypeIcon(), + Widget _getMaiWidget(GoodsDetailsTitleModel model) { + return Column( + children: <Widget>[ + RichText( + maxLines: 2, + overflow: TextOverflow.ellipsis, + text: TextSpan(children: [ + WidgetSpan( + child: _getGoodsTypeIcon(model), + ), + _getGoodsTitle(model), + ]), ), - _getGoodsTitle(), - ]), + /// 优惠卷说明 + Padding(padding: const EdgeInsets.only(top: 12.5), child: _getCounponDestrWidget(model)), + ], ); } /// 商品类型图标 - Widget _getGoodsTypeIcon() { + Widget _getGoodsTypeIcon(GoodsDetailsTitleModel model) { return Container( - height: 15, - width: 32, - color: Colors.red, + // height: 15, + // width: 32, + padding: const EdgeInsets.only(left: 7.5, right: 7.5, bottom: 2, top: 3), + margin: const EdgeInsets.only(right: 4), + decoration: BoxDecoration(borderRadius: BorderRadius.circular(2.5), color: HexColor.fromHex(model?.provider_bg_color)), + child: Text(model?.provider_name, style: TextStyle(color: HexColor.fromHex(model?.provider_name_color), fontSize: 9)), ); } /// 商品标题 - InlineSpan _getGoodsTitle() { - return TextSpan(text: '品胜(PISEN)苹果数据线1.5米 适用于苹果手机所有机型 MFI认证安全稳定一年换新1.5米2米', style: TextStyle(fontSize: 14, color: HexColor.fromHex('#FF333333'))); + InlineSpan _getGoodsTitle(GoodsDetailsTitleModel model) { + return TextSpan( + text: model?.title ?? '品胜(PISEN)苹果数据线1.5米 适用于苹果手机所有机型 MFI认证安全稳定一年换新1.5米2米', + style: TextStyle( + fontWeight: FontWeight.bold, + fontSize: 14, + color: HexColor.fromHex(model?.good_title_color ?? '#FF333333'), + )); + } + + /// 优惠卷说明 + Widget _getCounponDestrWidget(GoodsDetailsTitleModel model) { + return Row( + mainAxisAlignment: MainAxisAlignment.start, + children: <Widget>[ + /// 领券立减100元 widget + _getCoumstonButtomWidget(model?.coupon_text, model?.coupon_text_color, model?.coupon_bg_color), + const SizedBox(width: 5), + + /// 收货后返现5.5元 + _getCoumstonButtomWidget(model?.commission_text, model?.commission_text_color, model?.commission_bg_color), + ], + ); + } + + Widget _getCoumstonButtomWidget(String text, String textColor, String bg) { + return Container( + padding: const EdgeInsets.only(left: 13.5, right: 14.5, top: 2.5, bottom: 2.5), + decoration: BoxDecoration(borderRadius: BorderRadius.circular(30), color: HexColor.fromHex(bg)), + child: Text( + text, + style: TextStyle(color: HexColor.fromHex(textColor), fontSize: 11), + ), + ); } } diff --git a/lib/widgets/goods_details/title/model/goods_details_title_model.dart b/lib/widgets/goods_details/title/model/goods_details_title_model.dart new file mode 100644 index 0000000..f06e357 --- /dev/null +++ b/lib/widgets/goods_details/title/model/goods_details_title_model.dart @@ -0,0 +1,58 @@ +class GoodsDetailsTitleModel { + String commission_bg_color; + String commission_text; + String commission_text_color; + String coupon_bg_color; + String coupon_text; + String coupon_text_color; + String good_title_color; + String provider_bg_color; + String provider_name; + String provider_name_color; + String title; + + GoodsDetailsTitleModel( + {this.commission_bg_color, + this.commission_text, + this.commission_text_color, + this.coupon_bg_color, + this.coupon_text, + this.coupon_text_color, + this.good_title_color, + this.provider_bg_color, + this.provider_name, + this.provider_name_color, + this.title}); + + factory GoodsDetailsTitleModel.fromJson(Map<String, dynamic> json) { + return GoodsDetailsTitleModel( + commission_bg_color: json['commission_bg_color'], + commission_text: json['commission_text'], + commission_text_color: json['commission_text_color'], + coupon_bg_color: json['coupon_bg_color'], + coupon_text: json['coupon_text'], + coupon_text_color: json['coupon_text_color'], + good_title_color: json['good_title_color'], + provider_bg_color: json['provider_bg_color'], + provider_name: json['provider_name'], + provider_name_color: json['provider_name_color'], + title: json['title'], + ); + } + + Map<String, dynamic> toJson() { + final Map<String, dynamic> data = new Map<String, dynamic>(); + data['commission_bg_color'] = this.commission_bg_color; + data['commission_text'] = this.commission_text; + data['commission_text_color'] = this.commission_text_color; + data['coupon_bg_color'] = this.coupon_bg_color; + data['coupon_text'] = this.coupon_text; + data['coupon_text_color'] = this.coupon_text_color; + data['good_title_color'] = this.good_title_color; + data['provider_bg_color'] = this.provider_bg_color; + data['provider_name'] = this.provider_name; + data['provider_name_color'] = this.provider_name_color; + data['title'] = this.title; + return data; + } +} diff --git a/lib/widgets/goods_details/upgrade_tip/model/upgrade_tip_model.dart b/lib/widgets/goods_details/upgrade_tip/model/upgrade_tip_model.dart index 0d86b2f..20bc502 100644 --- a/lib/widgets/goods_details/upgrade_tip/model/upgrade_tip_model.dart +++ b/lib/widgets/goods_details/upgrade_tip/model/upgrade_tip_model.dart @@ -1,3 +1,36 @@ -class UpgradeTipModel{} +class UpgradeTipModel { + String bg_color; + String go_text; + String go_text_color; + String icon; + String text; + String text_color; + String url; + UpgradeTipModel({this.bg_color, this.go_text, this.go_text_color, this.icon, this.text, this.text_color, this.url}); + + factory UpgradeTipModel.fromJson(Map<String, dynamic> json) { + return UpgradeTipModel( + bg_color: json['bg_color'], + go_text: json['go_text'], + go_text_color: json['go_text_color'], + icon: json['icon'], + text: json['text'], + text_color: json['text_color'], + url: json['url'], + ); + } + + Map<String, dynamic> toJson() { + final Map<String, dynamic> data = new Map<String, dynamic>(); + data['bg_color'] = this.bg_color; + data['go_text'] = this.go_text; + data['go_text_color'] = this.go_text_color; + data['icon'] = this.icon; + data['text'] = this.text; + data['text_color'] = this.text_color; + data['url'] = this.url; + return data; + } +} \ No newline at end of file diff --git a/lib/widgets/goods_details/upgrade_tip/upgrade_tip_widget.dart b/lib/widgets/goods_details/upgrade_tip/upgrade_tip_widget.dart index 9f9e69e..48897b6 100644 --- a/lib/widgets/goods_details/upgrade_tip/upgrade_tip_widget.dart +++ b/lib/widgets/goods_details/upgrade_tip/upgrade_tip_widget.dart @@ -1,30 +1,47 @@ +import 'dart:convert'; + import 'package:flutter/material.dart'; import 'package:zhiying_base_widget/widgets/goods_details/upgrade_tip/model/upgrade_tip_model.dart'; import 'package:zhiying_comm/zhiying_comm.dart'; +import 'package:cached_network_image/cached_network_image.dart'; /// /// 更新提示widget /// class UpgradeTipWidget extends StatelessWidget { final Map<String, dynamic> model; - - const UpgradeTipWidget(this.model); + UpgradeTipModel _upgradeTipModel; + UpgradeTipWidget(this.model, {Key key}) : super(key: key){ + try{ + _upgradeTipModel = UpgradeTipModel.fromJson(jsonDecode(model['data'])); + }catch(e){ + Logger.log('UpgradeTipWidget e = $e'); + } + } @override Widget build(BuildContext context) { return Container( + width: double.infinity, + padding: const EdgeInsets.only(left: 12.5, right: 12.5, top: 12.5), decoration: BoxDecoration( - color: HexColor.fromHex('#FFEFDA'), - borderRadius: BorderRadius.circular(30), + color: Colors.white, + borderRadius: BorderRadius.only(topLeft: Radius.circular(7.5), topRight: Radius.circular(7.5)) ), - padding: const EdgeInsets.only(left: 10, right: 13, top: 10, bottom: 10), - margin: const EdgeInsets.symmetric(horizontal: 12.5), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: <Widget>[ - _geLeftWidget(null), - _getRightWidget(null), - ], + child: Container( + decoration: BoxDecoration( + /// 背景颜色 + color: HexColor.fromHex(_upgradeTipModel?.bg_color ?? '#FFEFDA'), + borderRadius: BorderRadius.circular(30), + ), + padding: const EdgeInsets.only(left: 10, right: 13, top: 10, bottom: 10), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: <Widget>[ + _geLeftWidget(_upgradeTipModel), + _getRightWidget(_upgradeTipModel), + ], + ), ), ); } @@ -34,24 +51,26 @@ class UpgradeTipWidget extends StatelessWidget { return Row( children: <Widget>[ /// 图标 - Container(width: 15, height: 15, color: Colors.red), + // Container(width: 15, height: 15, child: ,), + CachedNetworkImage(imageUrl: model?.icon ?? '', width: 15,), const SizedBox(width: 7.5), /// 文字 - Text('下载APP升级运营商,享受更多收益', style: TextStyle(color: HexColor.fromHex('#C09023'), fontSize: 11)) + Text(model?.text ?? '下载APP升级运营商,享受更多收益', style: TextStyle(color: HexColor.fromHex( model?.text_color ?? '#C09023'), fontSize: 11)) ], ); } /// 右边的视图 Widget _getRightWidget(UpgradeTipModel model) { - return Row( - children: <Widget>[ - Text('前往下载', style: TextStyle(color: HexColor.fromHex('#C09023'), fontSize: 11)), - const SizedBox(width: 4), - Text('》', style: TextStyle(color: HexColor.fromHex('#C09023'), fontSize: 11)) - ], - ); + return Text(model?.go_text ??'前往下载', style: TextStyle(color: HexColor.fromHex(model?.go_text_color ?? '#C09023'), fontSize: 11)); + // return Row( + // children: <Widget>[ + // Text(model?.go_text ??'前往下载', style: TextStyle(color: HexColor.fromHex('#C09023'), fontSize: 11)), + // const SizedBox(width: 4), + // Text('》', style: TextStyle(color: HexColor.fromHex('#C09023'), fontSize: 11)) + // ], + // ); } } diff --git a/lib/widgets/home/home_goods/home_goods_item.dart b/lib/widgets/home/home_goods/home_goods_item.dart index 78a2b38..13bef25 100644 --- a/lib/widgets/home/home_goods/home_goods_item.dart +++ b/lib/widgets/home/home_goods/home_goods_item.dart @@ -2,6 +2,7 @@ import 'dart:convert'; import 'package:cached_network_image/cached_network_image.dart'; import 'package:flutter/material.dart'; +import 'package:zhiying_base_widget/pages/goods_details_page/goods_details_page.dart'; import 'package:zhiying_base_widget/widgets/home/home_goods/models/home_goods_model.dart'; import 'package:zhiying_base_widget/widgets/home/home_goods/models/home_goods_style_model.dart'; import 'package:zhiying_comm/zhiying_comm.dart'; @@ -21,49 +22,59 @@ class HomeGoodsItem extends StatelessWidget { } } + /// 跳到商品详情 + void _onJumpGoodsDetails(BuildContext context,HomeGoodsModel goods){ + Navigator.push(context, MaterialPageRoute( + builder: (_)=> GoodsDetailsPage(goods.toJson()) + )); + } + @override Widget build(BuildContext context) { - return Container( - margin: EdgeInsets.only(left: 12.5, right: 12.5, top: 4, bottom: 4), - padding: EdgeInsets.all(7.5), - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.all(Radius.circular(7.5))), - child: Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: <Widget>[ - Container( - width: 126, - height: 126, - margin: EdgeInsets.only(right: 10), - child: ClipRRect( - borderRadius: BorderRadius.circular(7.5), - child: CachedNetworkImage( - imageUrl: goods.goodImage, - fit: BoxFit.fitHeight, - ), - ), - ), - Expanded( - child: Container( + return GestureDetector( + onTap: ()=> _onJumpGoodsDetails(context, goods), + child: Container( + margin: EdgeInsets.only(left: 12.5, right: 12.5, top: 4, bottom: 4), + padding: EdgeInsets.all(7.5), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.all(Radius.circular(7.5))), + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: <Widget>[ + Container( + width: 126, height: 126, - width: double.infinity, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: <Widget>[ - Container( - width: double.infinity, - child: _createTitle(), - ), - _createShop(), - _createCupone(), - Expanded(child: Container()), - _createBottom(), - ], + margin: EdgeInsets.only(right: 10), + child: ClipRRect( + borderRadius: BorderRadius.circular(7.5), + child: CachedNetworkImage( + imageUrl: goods.goodImage, + fit: BoxFit.fitHeight, + ), ), ), - ) - ], + Expanded( + child: Container( + height: 126, + width: double.infinity, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: <Widget>[ + Container( + width: double.infinity, + child: _createTitle(), + ), + _createShop(), + _createCupone(), + Expanded(child: Container()), + _createBottom(), + ], + ), + ), + ) + ], + ), ), ); } diff --git a/lib/widgets/home/home_goods/models/home_goods_model.dart b/lib/widgets/home/home_goods/models/home_goods_model.dart index 9e5ba87..16c6dda 100644 --- a/lib/widgets/home/home_goods/models/home_goods_model.dart +++ b/lib/widgets/home/home_goods/models/home_goods_model.dart @@ -4,6 +4,9 @@ part 'home_goods_model.g.dart'; @JsonSerializable() class HomeGoodsModel extends Object { + @JsonKey(name: 'provider') + String provider; + @JsonKey(name: 'provider_name') String providerName; @@ -35,6 +38,7 @@ class HomeGoodsModel extends Object { String inorderCount; HomeGoodsModel( + this.provider, this.providerName, this.goodId, this.goodImage, diff --git a/lib/widgets/home/home_goods/models/home_goods_model.g.dart b/lib/widgets/home/home_goods/models/home_goods_model.g.dart index 8e0acb1..397c6ca 100644 --- a/lib/widgets/home/home_goods/models/home_goods_model.g.dart +++ b/lib/widgets/home/home_goods/models/home_goods_model.g.dart @@ -8,6 +8,7 @@ part of 'home_goods_model.dart'; HomeGoodsModel _$HomeGoodsModelFromJson(Map<String, dynamic> json) { return HomeGoodsModel( + json['provider'] as String, json['provider_name'] as String, json['good_id'] as String, json['good_image'] as String, @@ -23,6 +24,7 @@ HomeGoodsModel _$HomeGoodsModelFromJson(Map<String, dynamic> json) { Map<String, dynamic> _$HomeGoodsModelToJson(HomeGoodsModel instance) => <String, dynamic>{ + 'provider': instance.provider, 'provider_name': instance.providerName, 'good_id': instance.goodId, 'good_image': instance.goodImage, diff --git a/lib/widgets/home/home_slide_banner/home_slide_banner.dart b/lib/widgets/home/home_slide_banner/home_slide_banner.dart index 9c1fd78..56f073c 100644 --- a/lib/widgets/home/home_slide_banner/home_slide_banner.dart +++ b/lib/widgets/home/home_slide_banner/home_slide_banner.dart @@ -44,10 +44,10 @@ class _HomeSlideBannerContainerState extends State<HomeSlideBannerContainer> { /// 子元素点击事件 void _itemOnClick(IndexCarousel model) { print('点击了 $model'); - // RouterUtil.route(model.toJson(), context); - Navigator.push(context, MaterialPageRoute( - builder: (_) => PageFactory.create('goods_details', null) - )); + RouterUtil.route(model.toJson(), context); + // Navigator.push(context, MaterialPageRoute( + // builder: (_) => PageFactory.create('goods_details', null) + // )); } @override