| @@ -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(); | |||
| } | |||
| } | |||
| } | |||
| @@ -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; | |||
| // } | |||
| } | |||
| @@ -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}'); | |||
| @@ -0,0 +1,11 @@ | |||
| import 'package:flutter/material.dart'; | |||
| /// | |||
| /// 搜索页 | |||
| /// | |||
| class SreachPage extends StatelessWidget { | |||
| @override | |||
| Widget build(BuildContext context) { | |||
| return Container(); | |||
| } | |||
| } | |||
| @@ -0,0 +1,11 @@ | |||
| import 'package:flutter/material.dart'; | |||
| /// | |||
| /// 搜索结果页面 | |||
| /// | |||
| class SreachResultPage extends StatelessWidget { | |||
| @override | |||
| Widget build(BuildContext context) { | |||
| return Container(); | |||
| } | |||
| } | |||
| @@ -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))); | |||
| @@ -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(); | |||
| } | |||
| } | |||
| } | |||
| @@ -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; | |||
| } | |||
| @@ -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 => []; | |||
| @@ -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), | |||
| @@ -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'))) | |||
| ], | |||
| ); | |||
| } | |||
| @@ -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{} | |||
| 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; | |||
| } | |||
| } | |||
| @@ -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(); | |||
| } | |||
| } | |||
| } | |||
| @@ -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]; | |||
| } | |||
| @@ -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; | |||
| } | |||
| } | |||
| @@ -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 {} | |||
| @@ -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)), | |||
| ], | |||
| ); | |||
| } | |||
| } | |||
| @@ -0,0 +1,11 @@ | |||
| import 'package:flutter/material.dart'; | |||
| /// | |||
| /// 商品详情骨架图 | |||
| /// | |||
| class GoodsDetailsImgSkeleton extends StatelessWidget { | |||
| @override | |||
| Widget build(BuildContext context) { | |||
| return Container(); | |||
| } | |||
| } | |||
| @@ -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; | |||
| } | |||
| } | |||
| @@ -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)), | |||
| ], | |||
| ); | |||
| } | |||
| } | |||
| @@ -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; | |||
| } | |||
| } | |||
| @@ -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(); | |||
| } | |||
| } | |||
| @@ -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 { | |||
| } | |||
| @@ -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; | |||
| } | |||
| /// 跳转购买 | |||
| /// 分享 | |||
| } | |||
| @@ -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 => []; | |||
| } | |||
| @@ -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), | |||
| ], | |||
| ), | |||
| ); | |||
| @@ -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)) | |||
| ], | |||
| @@ -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; | |||
| } | |||
| } | |||
| @@ -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)); | |||
| } | |||
| } | |||
| @@ -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; | |||
| } | |||
| } | |||
| @@ -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(); | |||
| } | |||
| } | |||
| @@ -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; | |||
| @@ -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), | |||
| ), | |||
| ); | |||
| } | |||
| @@ -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; | |||
| } | |||
| } | |||
| @@ -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(); | |||
| } | |||
| } | |||
| @@ -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]; | |||
| } | |||
| @@ -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 {} | |||
| @@ -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{} | |||
| 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; | |||
| } | |||
| } | |||
| @@ -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), | |||
| @@ -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 ?? '', | |||
| ), | |||
| ), | |||
| ], | |||
| ); | |||
| @@ -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), | |||
| ), | |||
| ); | |||
| } | |||
| } | |||
| @@ -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; | |||
| } | |||
| } | |||
| @@ -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; | |||
| } | |||
| } | |||
| @@ -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)) | |||
| // ], | |||
| // ); | |||
| } | |||
| } | |||
| @@ -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(), | |||
| ], | |||
| ), | |||
| ), | |||
| ) | |||
| ], | |||
| ), | |||
| ), | |||
| ); | |||
| } | |||
| @@ -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, | |||
| @@ -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, | |||
| @@ -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 | |||