| @@ -18,6 +18,7 @@ class SearchTagNotifier with ChangeNotifier { | |||
| SharedPreferences prefs = await SharedPreferences.getInstance(); | |||
| String jsonStr = prefs.getString(_SP_HOISTROY_KEY); | |||
| if (null != jsonStr && jsonStr.length > 0) { | |||
| _tagList.clear(); | |||
| final Map jsonMap = jsonDecode(jsonStr); | |||
| if (jsonMap != null && jsonMap.length > 0) { | |||
| jsonMap.forEach((key, value) => _tagList.insert(0, value)); | |||
| @@ -55,34 +55,37 @@ class _CounponWidgetContainerState extends State<CounponWidgetContainer> { | |||
| /// 主视图 | |||
| Widget _getMainWdiget(CounponModel model) { | |||
| return GestureDetector( | |||
| onTap: () => _onJump(model), | |||
| behavior: HitTestBehavior.opaque, | |||
| child: Container( | |||
| width: double.infinity, | |||
| color: Colors.white, | |||
| padding: const EdgeInsets.only(left: 12.5, right: 12.5, top: 12), | |||
| return Visibility( | |||
| visible: !EmptyUtil.isEmpty(model?.coupon_price), | |||
| child: GestureDetector( | |||
| onTap: () => _onJump(model), | |||
| behavior: HitTestBehavior.opaque, | |||
| 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) | |||
| ], | |||
| 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) | |||
| ], | |||
| ), | |||
| ), | |||
| ), | |||
| ), | |||
| @@ -134,7 +134,7 @@ class _GooddsDetailsFooterContainerState | |||
| child: Container( | |||
| width: double.infinity, | |||
| padding: EdgeInsets.only( | |||
| bottom: (height > 10 ? 0 : 10), top: 10, left: 21, right: 12.5), | |||
| bottom: (height > 10 ? 0 : 8), top: 8, 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), | |||
| @@ -233,6 +233,7 @@ class _GooddsDetailsFooterContainerState | |||
| text: model?.share_value ?? '0.0', | |||
| style: TextStyle( | |||
| fontSize: 15, | |||
| fontWeight: FontWeight.bold, | |||
| color: HexColor.fromHex( | |||
| model?.share_earn_color ?? '#FFFFFF'), | |||
| fontFamily: 'Din', | |||
| @@ -285,6 +286,7 @@ class _GooddsDetailsFooterContainerState | |||
| text: model?.slef_buy_value ?? '0.0', | |||
| style: TextStyle( | |||
| fontSize: 15, | |||
| fontWeight: FontWeight.bold, | |||
| color: HexColor.fromHex( | |||
| model?.save_earn_val_color ?? '#FFFFFF'), | |||
| fontFamily: 'Din', | |||
| @@ -312,11 +314,11 @@ class _GooddsDetailsFooterContainerState | |||
| CachedNetworkImage( | |||
| imageUrl: icon, | |||
| fit: BoxFit.fill, | |||
| width: 25, | |||
| height: 25, | |||
| width: 20, | |||
| height: 20, | |||
| ), | |||
| // Container( width: 25, margin: const EdgeInsets.only(bottom: 3), child: CachedNetworkImage(imageUrl: icon, fit: BoxFit.fill, width: 25,),), | |||
| const SizedBox(height: 3), | |||
| const SizedBox(height: 5), | |||
| /// 图片 | |||
| Text(text, | |||
| @@ -68,7 +68,7 @@ class GoodsDetailsPriceWidget extends StatelessWidget { | |||
| return Row( | |||
| children: <Widget>[ | |||
| 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')), | |||
| Text(model?.current_price ?? '0', style: TextStyle(color: HexColor.fromHex(model?.price_color ?? '#FF4242'), fontSize: 30, fontFamily: 'Din', package: 'zhiying_base_widget', fontWeight: FontWeight.bold)), | |||
| ], | |||
| ); | |||
| } | |||
| @@ -46,9 +46,34 @@ class SearchResultGoodsListBloc extends Bloc<SearchResultGoodsListEvent, SearchR | |||
| } | |||
| /// 搜索 | |||
| if(event is SearchResultGoodsListSubmitEvent){ | |||
| if (event is SearchResultGoodsListSubmitEvent) { | |||
| yield* _mapSubmitToState(event); | |||
| } | |||
| /// 排序 | |||
| if(event is SearchResultGoodsListSortEvent){ | |||
| yield* _mapSortEventToState(event); | |||
| } | |||
| /// 综合 | |||
| if (event is SearchResultGoodsListZHSortEvent) { | |||
| yield* _mapZhSortEventToState(event); | |||
| } | |||
| /// 补贴 | |||
| if (event is SearchResultGoodsListBtSortEvent) { | |||
| yield* _mapBTSortEventToState(event); | |||
| } | |||
| /// 优惠券 | |||
| if (event is SearchResultGoodsListYHQSortEvent) { | |||
| yield* _mapYHQSortEventToState(event); | |||
| } | |||
| /// 筛选 | |||
| if (event is SearchResultGoodsListSXSortEvent) { | |||
| yield* _mapSXSortEventToState(event); | |||
| } | |||
| } | |||
| /// 初始化事件 | |||
| @@ -100,4 +125,54 @@ class SearchResultGoodsListBloc extends Bloc<SearchResultGoodsListEvent, SearchR | |||
| yield SearchResultGoodsListErrorState(); | |||
| } | |||
| } | |||
| /// 排序 | |||
| Stream<SearchResultGoodsListState> _mapSortEventToState(SearchResultGoodsListSortEvent event) async* { | |||
| var result = await repository.fetchSort(event.args, event.id, event.remove); | |||
| if (!EmptyUtil.isEmpty(result)) { | |||
| yield SearchResultGoodsListLoadedState(model: result); | |||
| } else { | |||
| yield SearchResultGoodsListErrorState(); | |||
| } | |||
| } | |||
| /// 综合排序 | |||
| Stream<SearchResultGoodsListState> _mapZhSortEventToState(SearchResultGoodsListZHSortEvent event) async* { | |||
| var result = await repository.fetchZhSort(event.args); | |||
| if (!EmptyUtil.isEmpty(result)) { | |||
| yield SearchResultGoodsListLoadedState(model: result); | |||
| } else { | |||
| yield SearchResultGoodsListErrorState(); | |||
| } | |||
| } | |||
| /// 补贴排序 | |||
| Stream<SearchResultGoodsListState> _mapBTSortEventToState(SearchResultGoodsListBtSortEvent event) async* { | |||
| var result = await repository.fetchBt(event.args); | |||
| if (!EmptyUtil.isEmpty(result)) { | |||
| yield SearchResultGoodsListLoadedState(model: result); | |||
| } else { | |||
| yield SearchResultGoodsListErrorState(); | |||
| } | |||
| } | |||
| /// 优惠券排序 | |||
| Stream<SearchResultGoodsListState> _mapYHQSortEventToState(SearchResultGoodsListYHQSortEvent event) async* { | |||
| var result = await repository.fetchYhq(event.args); | |||
| if (!EmptyUtil.isEmpty(result)) { | |||
| yield SearchResultGoodsListLoadedState(model: result); | |||
| } else { | |||
| yield SearchResultGoodsListErrorState(); | |||
| } | |||
| } | |||
| /// 筛选排序 | |||
| Stream<SearchResultGoodsListState> _mapSXSortEventToState(SearchResultGoodsListSXSortEvent event) async* { | |||
| var result = await repository.fetchSX(event.args); | |||
| if (!EmptyUtil.isEmpty(result)) { | |||
| yield SearchResultGoodsListLoadedState(model: result); | |||
| } else { | |||
| yield SearchResultGoodsListErrorState(); | |||
| } | |||
| } | |||
| } | |||
| @@ -23,4 +23,54 @@ class SearchResultGoodsListChangeStyleEvent extends SearchResultGoodsListEvent{} | |||
| class SearchResultGoodsListSubmitEvent extends SearchResultGoodsListEvent{ | |||
| final String keywords; | |||
| const SearchResultGoodsListSubmitEvent(this.keywords); | |||
| } | |||
| /// 排序 | |||
| class SearchResultGoodsListSortEvent extends SearchResultGoodsListEvent{ | |||
| String args; | |||
| String id; | |||
| bool remove; | |||
| SearchResultGoodsListSortEvent({@required this.args, @required this.id, this.remove =false}); | |||
| @override | |||
| List<Object> get props => [this.args, this.id]; | |||
| } | |||
| /// 综合排序 | |||
| class SearchResultGoodsListZHSortEvent extends SearchResultGoodsListEvent{ | |||
| String args; | |||
| String id; | |||
| SearchResultGoodsListZHSortEvent(this.args, this.id); | |||
| @override | |||
| List<Object> get props => [this.args, this.id]; | |||
| } | |||
| /// 补贴排序 | |||
| class SearchResultGoodsListBtSortEvent extends SearchResultGoodsListEvent{ | |||
| String args; | |||
| String id; | |||
| SearchResultGoodsListBtSortEvent(this.args, this.id); | |||
| @override | |||
| List<Object> get props => [this.args, this.id]; | |||
| } | |||
| /// 优惠券排序 | |||
| class SearchResultGoodsListYHQSortEvent extends SearchResultGoodsListEvent{ | |||
| String args; | |||
| String id; | |||
| SearchResultGoodsListYHQSortEvent(this.args, this.id); | |||
| @override | |||
| List<Object> get props => [this.args, this.id]; | |||
| } | |||
| /// 优惠券排序 | |||
| class SearchResultGoodsListSXSortEvent extends SearchResultGoodsListEvent{ | |||
| String args; | |||
| String id; | |||
| SearchResultGoodsListSXSortEvent(this.args, this.id); | |||
| @override | |||
| List<Object> get props => [this.args, this.id]; | |||
| } | |||
| @@ -22,6 +22,7 @@ class SearchResultGoodsListRepository { | |||
| /// 查询数据参数 | |||
| Map<String, dynamic> reqData = {}; | |||
| Map<String, String> _urlArgs = {}; | |||
| /// 初始化 | |||
| Future<List<HomeGoodsModel>> fetchInitData() async { | |||
| @@ -32,9 +33,11 @@ class SearchResultGoodsListRepository { | |||
| /// 下拉刷新 | |||
| Future<List<HomeGoodsModel>> fetchRefreshData() async { | |||
| // 参数清除 | |||
| // _urlArgs.clear(); | |||
| _currentPage = 1; | |||
| _hasNomore = true; | |||
| return _baseInitData(true,reqData); | |||
| return _baseInitData(true, reqData); | |||
| } | |||
| /// 上拉更多 | |||
| @@ -54,22 +57,67 @@ class SearchResultGoodsListRepository { | |||
| } | |||
| /// 输入框修改关键字 | |||
| Future<List<HomeGoodsModel>> fetchSearchSubmit(String keywords) async{ | |||
| if(!EmptyUtil.isEmpty(keywords)) { | |||
| Future<List<HomeGoodsModel>> fetchSearchSubmit(String keywords) async { | |||
| if (!EmptyUtil.isEmpty(keywords)) { | |||
| reqData['reqData'] = keywords; | |||
| _currentPage = 1; | |||
| _hasNomore =true; | |||
| _hasNomore = true; | |||
| return _baseInitData(true, reqData); | |||
| } | |||
| return null; | |||
| } | |||
| /// 排序 | |||
| Future<List<HomeGoodsModel>> fetchSort(String arg, String id, bool remove) async { | |||
| _urlArgs[id] = arg; | |||
| if(EmptyUtil.isEmpty(arg) || remove){ | |||
| _urlArgs.remove(id); | |||
| } | |||
| _currentPage = 1; | |||
| _hasNomore = true; | |||
| return _baseInitData(true, reqData); | |||
| } | |||
| /// 综合排序 | |||
| Future<List<HomeGoodsModel>> fetchZhSort(String arg) async { | |||
| _urlArgs['zh'] = arg; | |||
| _currentPage = 1; | |||
| _hasNomore = true; | |||
| return _baseInitData(true, reqData); | |||
| } | |||
| /// 补贴 | |||
| Future<List<HomeGoodsModel>> fetchBt(String arg) async { | |||
| _urlArgs['bt'] = arg; | |||
| _currentPage = 1; | |||
| _hasNomore = true; | |||
| return _baseInitData(true, reqData); | |||
| } | |||
| /// 优惠券 | |||
| Future<List<HomeGoodsModel>> fetchYhq(String arg) async { | |||
| _urlArgs['yhq'] = arg; | |||
| _currentPage = 1; | |||
| _hasNomore = true; | |||
| return _baseInitData(true, reqData); | |||
| } | |||
| /// 筛选 | |||
| Future<List<HomeGoodsModel>> fetchSX(String arg) async { | |||
| _urlArgs['sx'] = arg; | |||
| _currentPage = 1; | |||
| _hasNomore = true; | |||
| return _baseInitData(true, reqData); | |||
| } | |||
| /// 查询 | |||
| Future<List<HomeGoodsModel>> _baseInitData(bool refresh,final Map<String, dynamic> model) async { | |||
| Future<List<HomeGoodsModel>> _baseInitData(bool refresh, final Map<String, dynamic> model) async { | |||
| String keyword = model['keywords'] ?? ''; | |||
| String type = model['type']; | |||
| String type = model.containsKey('type') ? model['type'] : 'taobao'; | |||
| if (EmptyUtil.isEmpty(keyword)) return null; | |||
| var result = await NetUtil.post('/api/v1/s/$type', | |||
| /// 构造url | |||
| String url = _buildUrl(type); | |||
| var result = await NetUtil.post(url, | |||
| params: { | |||
| 'keyword': keyword, | |||
| 'size': MAX.toString(), | |||
| @@ -85,7 +133,7 @@ class SearchResultGoodsListRepository { | |||
| ++_currentPage; | |||
| } | |||
| // 下拉刷新需要清理 | |||
| if(refresh){ | |||
| if (refresh) { | |||
| _oldDatas.clear(); | |||
| } | |||
| @@ -104,4 +152,29 @@ class SearchResultGoodsListRepository { | |||
| _hasNomore = false; | |||
| return null; | |||
| } | |||
| /// 通过筛选条件构造请求链接 | |||
| String _buildUrl(String type) { | |||
| String url = '/api/v1/s/$type'; | |||
| try { | |||
| StringBuffer sb = StringBuffer(); | |||
| if (EmptyUtil.isEmpty(_urlArgs) && _urlArgs.length > 0) return url; | |||
| sb.write(url); | |||
| int index = 0; | |||
| _urlArgs.keys.forEach((key) { | |||
| String temp = _urlArgs[key]; | |||
| if (!EmptyUtil.isEmpty(temp)) { | |||
| if(index == 0) { | |||
| sb.write('?$temp'); | |||
| }else{ | |||
| sb.write('&$temp'); | |||
| } | |||
| ++index; | |||
| } | |||
| }); | |||
| return sb.toString(); | |||
| } catch (e) { | |||
| return url; | |||
| } | |||
| } | |||
| } | |||
| @@ -1,6 +1,7 @@ | |||
| import 'dart:convert'; | |||
| import 'package:flutter/material.dart'; | |||
| import 'package:zhiying_base_widget/pages/search_think_page/bloc/search_think_bloc.dart'; | |||
| import 'package:zhiying_base_widget/widgets/search_result/goods_list/bloc/search_result_goods_list_bloc.dart'; | |||
| import 'package:zhiying_base_widget/widgets/search_result/search_input/model/search_result_input_model.dart'; | |||
| import 'package:zhiying_comm/zhiying_comm.dart'; | |||
| @@ -44,6 +45,15 @@ class _SearchResultInputWidgetState extends State<SearchResultInputWidget> { | |||
| } | |||
| } | |||
| /// 输入变化 | |||
| // void _onChanged(String text){ | |||
| // if(!EmptyUtil.isEmpty(text)){ | |||
| // BlocProvider.of<SearchThinkBloc>(context).add(SearchThinkKeyWrodsChangeEvent(text)); | |||
| // }else{ | |||
| // BlocProvider.of<SearchThinkBloc>(context).add(SearchThinkShowBaseViewEvent()); | |||
| // } | |||
| // } | |||
| @override | |||
| void initState() { | |||
| _textEditingController = TextEditingController(text: widget?.model?.keywords ?? ''); | |||
| @@ -132,7 +142,9 @@ class _SearchResultInputWidgetState extends State<SearchResultInputWidget> { | |||
| ), | |||
| padding: const EdgeInsets.only(left: 12.5, right: 12.5), | |||
| child: TextField( | |||
| onTap: ()=> Navigator.maybePop(context, _textEditingController?.text?.toString()?.trim()), | |||
| onTap: ()=> Navigator.maybePop(context), | |||
| // onChanged: (str) => _onChanged(str), | |||
| showCursor: true, | |||
| cursorWidth: 1, | |||
| onSubmitted: (text) => _onSearchButtomClick(), | |||
| @@ -59,20 +59,20 @@ class SearchResultItemSort { | |||
| bool isSelect; | |||
| List<SearchResultSortSelect> select_list; | |||
| String type; | |||
| String icon; | |||
| String color_icon; | |||
| String color_icon_up; | |||
| String color_icon_down; | |||
| String icon_1; | |||
| String icon_2; | |||
| String icon_3; | |||
| String state; | |||
| SearchResultItemSort({ | |||
| this.name, | |||
| this.select_list, | |||
| this.isSelect, | |||
| this.type, | |||
| this.icon, | |||
| this.color_icon, | |||
| this.color_icon_up, | |||
| this.color_icon_down, | |||
| this.icon_1, | |||
| this.icon_2, | |||
| this.icon_3, | |||
| this.state, | |||
| }); | |||
| factory SearchResultItemSort.fromJson(Map<String, dynamic> json) { | |||
| @@ -81,10 +81,10 @@ class SearchResultItemSort { | |||
| isSelect: json['isSelect'] ?? false, | |||
| select_list: json['select_list'] != null ? (json['select_list'] as List).map((i) => SearchResultSortSelect.fromJson(i)).toList() : null, | |||
| type: json['type']?.toString(), | |||
| icon: json['icon']?.toString(), | |||
| color_icon: json['color_icon']?.toString(), | |||
| color_icon_up: json['color_icon_up']?.toString(), | |||
| color_icon_down: json['color_icon_down']?.toString(), | |||
| icon_1: json['icon_1']?.toString(), | |||
| icon_2: json['icon_2']?.toString(), | |||
| icon_3: json['icon_3']?.toString(), | |||
| state: json['state'] ?? '0', | |||
| ); | |||
| } | |||
| @@ -96,24 +96,28 @@ class SearchResultItemSort { | |||
| data['select_list'] = this.select_list.map((v) => v.toJson()).toList(); | |||
| } | |||
| data['type'] = this.type; | |||
| data['icon'] = this.icon; | |||
| data['color_icon'] = this.color_icon; | |||
| data['color_icon_up'] = this.color_icon_up; | |||
| data['color_icon_down'] = this.color_icon_down; | |||
| data['icon_1'] = this.icon_1; | |||
| data['icon_2'] = this.icon_2; | |||
| data['icon_3'] = this.icon_3; | |||
| data['state'] = this.state; | |||
| return data; | |||
| } | |||
| } | |||
| class SearchResultSortSelect { | |||
| String id; | |||
| String name; | |||
| String query_args; | |||
| bool isSelect; | |||
| SearchResultSortSelect({this.name, this.query_args}); | |||
| SearchResultSortSelect({this.name, this.query_args, this.id, this.isSelect}); | |||
| factory SearchResultSortSelect.fromJson(Map<String, dynamic> json) { | |||
| return SearchResultSortSelect( | |||
| name: json['name'], | |||
| query_args: json['query_args'], | |||
| id: json['id'], | |||
| isSelect: json['isSelect'] ?? false, | |||
| ); | |||
| } | |||
| @@ -121,6 +125,8 @@ class SearchResultSortSelect { | |||
| final Map<String, dynamic> data = new Map<String, dynamic>(); | |||
| data['name'] = this.name; | |||
| data['query_args'] = this.query_args; | |||
| data['id'] = this.id; | |||
| data['isSelect'] = this.isSelect; | |||
| return data; | |||
| } | |||
| } | |||
| @@ -1,12 +1,13 @@ | |||
| import 'dart:convert'; | |||
| import 'package:flutter/cupertino.dart'; | |||
| import 'package:flutter/material.dart'; | |||
| import 'package:zhiying_base_widget/widgets/home/home_quick_entry/cached_network_image_util.dart'; | |||
| import 'package:zhiying_base_widget/widgets/search_result/goods_list/bloc/search_result_goods_list_bloc.dart'; | |||
| import 'package:zhiying_base_widget/widgets/search_result/sort/model/search_result_sort_model.dart'; | |||
| import 'package:zhiying_comm/zhiying_comm.dart'; | |||
| import 'package:cached_network_image/cached_network_image.dart'; | |||
| import 'package:flutter_bloc/flutter_bloc.dart'; | |||
| import 'package:fluttertoast/fluttertoast.dart'; | |||
| /// | |||
| /// 搜索结果页排序widget | |||
| @@ -33,8 +34,11 @@ class _SearchResultSortWidgetState extends State<SearchResultSortWidget> { | |||
| // 是否展开综合 | |||
| bool _isShowZh = false; | |||
| bool _isShowSX = false; | |||
| // 切换显示样式 | |||
| bool _isShowOneColumn = true; | |||
| // 是否展开下拉选项 | |||
| bool _expand = false; | |||
| @@ -44,31 +48,173 @@ class _SearchResultSortWidgetState extends State<SearchResultSortWidget> { | |||
| BlocProvider.of<SearchResultGoodsListBloc>(context).add(SearchResultGoodsListChangeStyleEvent()); | |||
| } | |||
| /// 张开关闭下拉框 | |||
| void _openXLWidget(){ | |||
| /// 选中综合 | |||
| void _onClickZhSort(List<SearchResultSortSelect> datas, SearchResultSortSelect model, SearchResultItemSort parent) { | |||
| String arg = model?.query_args ?? ''; | |||
| String id = model?.id ?? ''; | |||
| parent.isSelect = true; | |||
| model.isSelect = !model.isSelect; | |||
| datas.forEach((item) { | |||
| if (item.name != model.name) { | |||
| item.isSelect = false; | |||
| } | |||
| }); | |||
| if (!EmptyUtil.isEmpty(id)) { | |||
| BlocProvider.of<SearchResultGoodsListBloc>(context).add(SearchResultGoodsListSortEvent(id: id, args: arg)); | |||
| } | |||
| setState(() { | |||
| _expand = !_expand; | |||
| _expand = false; | |||
| _isShowZh = false; | |||
| _isShowSX = false; | |||
| }); | |||
| } | |||
| /// 展开综合 | |||
| void _openZHPopupWidget() {} | |||
| /// 选中补贴 | |||
| void _onClickBTSort(SearchResultItemSort model) { | |||
| if (model.state == '0') { | |||
| model.state = '1'; | |||
| } else if (model.state == '1') { | |||
| model.state = '2'; | |||
| } else { | |||
| model.state = '0'; | |||
| } | |||
| SearchResultSortSelect item = model.state == '0' ? null : model.state == '1' ? model.select_list[0] : model.select_list[1]; | |||
| /// 展开筛选 | |||
| void _openSXWidget() {} | |||
| String arg = item?.query_args ?? ''; | |||
| String id = model.select_list[0].id; | |||
| if (!EmptyUtil.isEmpty(id)) { | |||
| // BlocProvider.of<SearchResultGoodsListBloc>(context).add(SearchResultGoodsListSortEvent(arg, id)); | |||
| BlocProvider.of<SearchResultGoodsListBloc>(context).add(SearchResultGoodsListSortEvent(id: id, args: arg)); | |||
| } | |||
| setState(() { | |||
| _expand = false; | |||
| _isShowSX = false; | |||
| _isShowZh = false; | |||
| }); | |||
| } | |||
| /// 选中优惠券 | |||
| void _onClickYHQSort(SearchResultItemSort data) { | |||
| print('_onClickYHQSort'); | |||
| data.isSelect = !data.isSelect; | |||
| SearchResultSortSelect model = data.isSelect ? data.select_list[0] : data.select_list[1]; | |||
| String arg = model?.query_args ?? ''; | |||
| String id = model?.id ?? ''; | |||
| if (!EmptyUtil.isEmpty(id)) { | |||
| // BlocProvider.of<SearchResultGoodsListBloc>(context).add(SearchResultGoodsListSortEvent(arg, id)); | |||
| BlocProvider.of<SearchResultGoodsListBloc>(context).add(SearchResultGoodsListSortEvent(id: id, args: arg)); | |||
| } | |||
| setState(() { | |||
| _expand = false; | |||
| _isShowSX = false; | |||
| _isShowZh = false; | |||
| }); | |||
| } | |||
| /// 选中价格 | |||
| void _onClickSXPriceSort(SearchResultItemSort data, SearchResultSortSelect model) { | |||
| print('走塞选'); | |||
| String arg; //model?.query_args ?? ''; | |||
| String id = model?.id ?? ''; | |||
| // is_start_price=0&is_end_price=9999999 | |||
| String startPriceStr = _startPriceEditingController?.text?.toString()?.trim() ?? ''; | |||
| String endPriceStr = _endPriceEditingController?.text?.toString()?.trim() ?? ''; | |||
| if (EmptyUtil.isEmpty(startPriceStr)) { | |||
| Fluttertoast.showToast(msg: '请输入最低价格~'); | |||
| return; | |||
| } | |||
| if (EmptyUtil.isEmpty(endPriceStr)) { | |||
| Fluttertoast.showToast(msg: '请输入最高价格~'); | |||
| return; | |||
| } | |||
| try { | |||
| int starPrice = int.parse(startPriceStr); | |||
| int endPrice = int.parse(endPriceStr); | |||
| if (starPrice < endPrice) { | |||
| arg = 'is_start_price=${starPrice}&is_end_price=${endPrice}'; | |||
| if (!EmptyUtil.isEmpty(id)) { | |||
| // BlocProvider.of<SearchResultGoodsListBloc>(context).add(SearchResultGoodsListSortEvent(arg, id)); | |||
| model.isSelect = true; | |||
| BlocProvider.of<SearchResultGoodsListBloc>(context).add(SearchResultGoodsListSortEvent(id: id, args: arg)); | |||
| } | |||
| } else { | |||
| Fluttertoast.showToast(msg: '最低价格不能大于等于最高价格~'); | |||
| } | |||
| } catch (_) {} | |||
| setState(() { | |||
| _expand = false; | |||
| _isShowSX = false; | |||
| _isShowZh = false; | |||
| }); | |||
| if (model.isSelect || data.select_list[0].isSelect) { | |||
| data.isSelect = true; | |||
| } else { | |||
| data.isSelect = false; | |||
| } | |||
| } | |||
| /// 自营 | |||
| void _onClickZYSort(SearchResultItemSort data, SearchResultSortSelect model) { | |||
| String arg = model?.query_args ?? ''; | |||
| String id = model?.id ?? ''; | |||
| model.isSelect = !model.isSelect; | |||
| if (!EmptyUtil.isEmpty(id)) { | |||
| // BlocProvider.of<SearchResultGoodsListBloc>(context).add(SearchResultGoodsListSortEvent(arg, id)); | |||
| BlocProvider.of<SearchResultGoodsListBloc>(context).add(SearchResultGoodsListSortEvent(id: id, args: arg, remove: !model.isSelect)); | |||
| } | |||
| setState(() { | |||
| _expand = false; | |||
| _isShowSX = false; | |||
| _isShowZh = false; | |||
| }); | |||
| if (model.isSelect || data.select_list[0].isSelect) { | |||
| data.isSelect = true; | |||
| } else { | |||
| data.isSelect = false; | |||
| } | |||
| } | |||
| /// 点击当前 | |||
| void _clickSortType(SearchResultItemSort model) { | |||
| if(model.type != 'sort'){ | |||
| if (model.type == 'popup' || model.type == 'popup-filter') { | |||
| setState(() { | |||
| _expand = !_expand; | |||
| _expand = true; | |||
| if (model.type == 'popup') { | |||
| _isShowZh = true; | |||
| _isShowSX = false; | |||
| } | |||
| if (model.type == 'popup-filter') { | |||
| _isShowSX = true; | |||
| _isShowZh = false; | |||
| } | |||
| }); | |||
| } else { | |||
| /// 优惠券 | |||
| if (model.type == 'select') { | |||
| _onClickYHQSort(model); | |||
| } | |||
| /// 三个选项 | |||
| if (model.type == 'sort') { | |||
| _onClickBTSort(model); | |||
| } | |||
| _closeExpand(); | |||
| } | |||
| } | |||
| /// 关闭下拉框 | |||
| void _closeExpand() { | |||
| setState(() { | |||
| _expand = false; | |||
| }); | |||
| } | |||
| @override | |||
| void initState() { | |||
| @@ -131,7 +277,7 @@ class _SearchResultSortWidgetState extends State<SearchResultSortWidget> { | |||
| child: Expanded( | |||
| child: GestureDetector( | |||
| behavior: HitTestBehavior.opaque, | |||
| onTap: () => _openXLWidget(), | |||
| onTap: () => _closeExpand(), | |||
| child: Container( | |||
| // height: double.infinity, | |||
| width: double.infinity, | |||
| @@ -139,7 +285,7 @@ class _SearchResultSortWidgetState extends State<SearchResultSortWidget> { | |||
| color: HexColor.fromHex('#33333333'), | |||
| ), | |||
| child: Visibility( | |||
| visible: _isShowZh, | |||
| visible: _isShowSX, | |||
| replacement: _getZHWidget(model), | |||
| child: _getSXWidget(model), | |||
| ), | |||
| @@ -156,10 +302,12 @@ class _SearchResultSortWidgetState extends State<SearchResultSortWidget> { | |||
| List<SearchResultSortSelect> model; | |||
| List<Widget> lists = []; | |||
| int sort_list_length = data?.sort_list?.length ?? 0; | |||
| SearchResultItemSort parentData; | |||
| if (sort_list_length > 0) { | |||
| data.sort_list.forEach((item) { | |||
| if (item.type == 'popup') { | |||
| model = item.select_list; | |||
| parentData = item; | |||
| } | |||
| }); | |||
| @@ -168,19 +316,22 @@ class _SearchResultSortWidgetState extends State<SearchResultSortWidget> { | |||
| double borderRadius = (i == model.length - 1) ? 12.5 : 0; | |||
| var padding = EdgeInsets.only(left: 12.5, right: 12.5, top: 10, bottom: (i == model.length - 1) ? 15 : 0); | |||
| lists.add(Container( | |||
| padding: padding, | |||
| decoration: BoxDecoration( | |||
| color: Colors.white, | |||
| border: Border.all(width: 0, color: Colors.transparent), | |||
| borderRadius: BorderRadius.only( | |||
| bottomRight: Radius.circular(borderRadius), | |||
| bottomLeft: Radius.circular(borderRadius), | |||
| )), | |||
| width: double.infinity, | |||
| child: Text( | |||
| item?.name ?? '', | |||
| style: TextStyle(fontSize: 12, color: HexColor.fromHex(widget?.model?.text_no_select_color)), | |||
| lists.add(GestureDetector( | |||
| onTap: () => _onClickZhSort(model, item, parentData), | |||
| child: Container( | |||
| padding: padding, | |||
| decoration: BoxDecoration( | |||
| color: Colors.white, | |||
| border: Border.all(width: 0, color: Colors.transparent), | |||
| borderRadius: BorderRadius.only( | |||
| bottomRight: Radius.circular(borderRadius), | |||
| bottomLeft: Radius.circular(borderRadius), | |||
| )), | |||
| width: double.infinity, | |||
| child: Text( | |||
| item?.name ?? '', | |||
| style: TextStyle(fontSize: 12, color: HexColor.fromHex(item.isSelect ? widget?.model?.text_select_color ?? '' : widget?.model?.text_no_select_color ?? '')), | |||
| ), | |||
| ), | |||
| )); | |||
| } | |||
| @@ -199,11 +350,13 @@ class _SearchResultSortWidgetState extends State<SearchResultSortWidget> { | |||
| Widget _getSXWidget(SearchResultSortModel data) { | |||
| List<Widget> lists = []; | |||
| List<SearchResultSortSelect> model; | |||
| SearchResultItemSort parendData; | |||
| int sort_list_length = data?.sort_list?.length ?? 0; | |||
| if (sort_list_length > 0) { | |||
| data.sort_list.forEach((item) { | |||
| if (item.type == 'popup-filter') { | |||
| model = item.select_list; | |||
| parendData = item; | |||
| } | |||
| }); | |||
| @@ -213,8 +366,8 @@ class _SearchResultSortWidgetState extends State<SearchResultSortWidget> { | |||
| if (i == 0) { | |||
| lists.add(Container( | |||
| padding: const EdgeInsets.only(left: 12.5, right: 12.5, top: 10), | |||
| decoration: BoxDecoration(color: Colors.white, border: Border.all(width: 0, color: Colors.transparent)), | |||
| child: _getPriceBetweenWidget(), | |||
| decoration: BoxDecoration(color: Colors.white, border: Border.all(width: 0, color: Colors.white)), | |||
| child: _getPriceBetweenWidget(parendData, model[0]), | |||
| )); | |||
| } | |||
| if (i == 1) { | |||
| @@ -222,12 +375,12 @@ class _SearchResultSortWidgetState extends State<SearchResultSortWidget> { | |||
| padding: const EdgeInsets.only(left: 12.5, right: 12.5, top: 13, bottom: 15), | |||
| decoration: BoxDecoration( | |||
| color: Colors.white, | |||
| border: Border.all(width: 0, color: Colors.transparent), | |||
| border: Border.all(width: 0, color: Colors.white), | |||
| borderRadius: BorderRadius.only( | |||
| bottomLeft: Radius.circular(12.5), | |||
| bottomRight: Radius.circular(12.5), | |||
| )), | |||
| child: _getStoryType())); | |||
| child: _getStoryType(parendData, model[1]))); | |||
| } | |||
| } | |||
| } else { | |||
| @@ -241,7 +394,7 @@ class _SearchResultSortWidgetState extends State<SearchResultSortWidget> { | |||
| } | |||
| /// 价格区间 | |||
| Widget _getPriceBetweenWidget() { | |||
| Widget _getPriceBetweenWidget(SearchResultItemSort data, SearchResultSortSelect model) { | |||
| return Row( | |||
| mainAxisAlignment: MainAxisAlignment.spaceBetween, | |||
| children: <Widget>[ | |||
| @@ -252,13 +405,15 @@ class _SearchResultSortWidgetState extends State<SearchResultSortWidget> { | |||
| Row( | |||
| children: <Widget>[ | |||
| /// 最低价格 | |||
| _getCustomTextField(controller: _startPriceEditingController, focusNode: _startPriceNode, hintText: '最低价格', hintTextColor: '#999999'), | |||
| _getCustomTextField( | |||
| controller: _startPriceEditingController, focusNode: _startPriceNode, hintText: '最低价格', hintTextColor: '#999999', onTap: (val) => _onClickSXPriceSort(data, model)), | |||
| /// 文字 【至】 | |||
| Container(margin: const EdgeInsets.symmetric(horizontal: 8), child: Text('至', style: TextStyle(color: HexColor.fromHex('#999999'), fontSize: 14))), | |||
| /// 最高价格 | |||
| _getCustomTextField(controller: _endPriceEditingController, focusNode: _endPriceNode, hintTextColor: '#999999', hintText: '最高价格'), | |||
| _getCustomTextField( | |||
| controller: _endPriceEditingController, focusNode: _endPriceNode, hintTextColor: '#999999', hintText: '最高价格', onTap: (val) => _onClickSXPriceSort(data, model)), | |||
| ], | |||
| ), | |||
| ], | |||
| @@ -266,7 +421,7 @@ class _SearchResultSortWidgetState extends State<SearchResultSortWidget> { | |||
| } | |||
| /// 只看自营 | |||
| Widget _getStoryType() { | |||
| Widget _getStoryType(SearchResultItemSort data, SearchResultSortSelect model) { | |||
| return Row( | |||
| mainAxisAlignment: MainAxisAlignment.spaceBetween, | |||
| children: <Widget>[ | |||
| @@ -274,15 +429,19 @@ class _SearchResultSortWidgetState extends State<SearchResultSortWidget> { | |||
| '商家类型', | |||
| style: TextStyle(color: HexColor.fromHex('#999999'), fontSize: 14), | |||
| ), | |||
| Container( | |||
| padding: const EdgeInsets.symmetric(horizontal: 21, vertical: 8.5), | |||
| child: Text( | |||
| '只看自营', | |||
| style: TextStyle(color: HexColor.fromHex('#999999'), fontSize: 12), | |||
| ), | |||
| decoration: BoxDecoration( | |||
| border: Border.all(color: HexColor.fromHex('#E7E7E7'), width: 0.5), | |||
| borderRadius: BorderRadius.circular(5), | |||
| GestureDetector( | |||
| behavior: HitTestBehavior.opaque, | |||
| onTap: () => _onClickZYSort(data, model), | |||
| child: Container( | |||
| padding: const EdgeInsets.symmetric(horizontal: 21, vertical: 8.5), | |||
| child: Text( | |||
| '只看自营', | |||
| style: TextStyle(color: HexColor.fromHex(model?.isSelect ?? false ? '#FF4242' : '#999999'), fontSize: 12), | |||
| ), | |||
| decoration: BoxDecoration( | |||
| border: Border.all(color: HexColor.fromHex(model?.isSelect ?? false ? '#FF4242' : '#E7E7E7'), width: 0.5), | |||
| borderRadius: BorderRadius.circular(5), | |||
| ), | |||
| ), | |||
| ), | |||
| ], | |||
| @@ -290,7 +449,7 @@ class _SearchResultSortWidgetState extends State<SearchResultSortWidget> { | |||
| } | |||
| /// 输入框 | |||
| Widget _getCustomTextField({TextEditingController controller, FocusNode focusNode, String hintText, String hintTextColor, double radius = 5}) { | |||
| Widget _getCustomTextField({TextEditingController controller, FocusNode focusNode, String hintText, String hintTextColor, double radius = 5, ValueChanged<String> onTap}) { | |||
| return Container( | |||
| width: 90, | |||
| height: 33.5, | |||
| @@ -302,9 +461,14 @@ class _SearchResultSortWidgetState extends State<SearchResultSortWidget> { | |||
| child: TextField( | |||
| controller: controller, | |||
| focusNode: focusNode, | |||
| textInputAction: TextInputAction.search, | |||
| textAlign: TextAlign.center, | |||
| keyboardType: TextInputType.number, | |||
| onSubmitted: onTap, | |||
| decoration: InputDecoration( | |||
| filled: true, | |||
| fillColor: Colors.transparent, | |||
| // contentPadding: const EdgeInsets.only(bottom: 6, left: ), | |||
| border: InputBorder.none, | |||
| focusedBorder: InputBorder.none, | |||
| focusedErrorBorder: InputBorder.none, | |||
| @@ -325,20 +489,28 @@ class _SearchResultSortWidgetState extends State<SearchResultSortWidget> { | |||
| child: Container( | |||
| child: Row( | |||
| children: <Widget>[ | |||
| Text(model?.name ?? '综合', | |||
| style: TextStyle( | |||
| color: HexColor.fromHex(model.isSelect ? widget?.model?.text_select_color ?? '#FF4242' : widget?.model?.text_no_select_color ?? '#333333'), fontSize: 14)), | |||
| Text( | |||
| model?.name ?? '综合', | |||
| style: TextStyle( | |||
| color: HexColor.fromHex( | |||
| model.type != 'sort' ? model.isSelect ? widget?.model?.text_select_color ?? '#FF4242' : widget?.model?.text_no_select_color ?? '#333333' : | |||
| model.state == '0' ? '#333333' : '#FF4242' | |||
| ), | |||
| fontSize: 14, | |||
| ), | |||
| ), | |||
| const SizedBox(width: 4), | |||
| Container( | |||
| width: 12, | |||
| height: 12, | |||
| alignment: Alignment.center, | |||
| color: Colors.white, | |||
| child: CachedNetworkImage( | |||
| imageUrl: model?.icon ?? '', | |||
| width: 12, | |||
| ) | |||
| ) | |||
| height: 12, | |||
| alignment: Alignment.center, | |||
| color: Colors.white, | |||
| child: CachedNetworkImage( | |||
| imageUrl: model.type != 'sort' | |||
| ? model?.isSelect ?? false ? model?.icon_2 ?? '' : model?.icon_1 ?? '' | |||
| : model.state == '0' ? model.icon_1 : model.state == '1' ? model.icon_2 : model.state == '2' ? model.icon_3 : model.icon_1, | |||
| width: 12, | |||
| )) | |||
| ], | |||
| ), | |||
| ), | |||
| @@ -1,16 +1,19 @@ | |||
| class SearchResultTabModel { | |||
| List<SearchResultTabItemModel> search_icon_list; | |||
| String keywords; | |||
| String type; | |||
| SearchResultTabModel({ | |||
| this.search_icon_list, | |||
| this.keywords, | |||
| this.type, | |||
| }); | |||
| factory SearchResultTabModel.fromJson(Map<String, dynamic> json) { | |||
| return SearchResultTabModel( | |||
| search_icon_list: json['search_icon_list'] != null ? (json['search_icon_list'] as List).map((i) => SearchResultTabItemModel.fromJson(i)).toList() : null, | |||
| keywords: json['keywords'], | |||
| type: json['type'], | |||
| ); | |||
| } | |||
| @@ -20,6 +23,7 @@ class SearchResultTabModel { | |||
| data['search_icon_list'] = this.search_icon_list.map((v) => v.toJson()).toList(); | |||
| } | |||
| data['keywords'] = keywords; | |||
| data['type'] = type; | |||
| return data; | |||
| } | |||
| } | |||
| @@ -3,11 +3,13 @@ import 'dart:convert'; | |||
| import 'package:flutter/material.dart'; | |||
| import 'package:cached_network_image/cached_network_image.dart'; | |||
| import 'package:tab_indicator_styler/tab_indicator_styler.dart'; | |||
| import 'package:zhiying_base_widget/pages/search_think_page/bloc/search_think_bloc.dart'; | |||
| import 'package:zhiying_base_widget/pages/search_think_page/model/search_think_model.dart'; | |||
| import 'package:zhiying_base_widget/widgets/home/home_quick_entry/cached_network_image_util.dart'; | |||
| import 'package:zhiying_base_widget/widgets/search/tabbar/search_tab_sk.dart'; | |||
| import 'package:zhiying_base_widget/widgets/search/widget/my_tab.dart'; | |||
| import 'package:zhiying_base_widget/widgets/search_result/sort/search_result_sort_widget.dart'; | |||
| import 'package:flutter_bloc/flutter_bloc.dart'; | |||
| import 'package:zhiying_comm/zhiying_comm.dart'; | |||
| @@ -19,6 +21,7 @@ class SearchResultTabWidget extends StatefulWidget { | |||
| SearchResultTabWidget(this.data, {Key key}) : super(key: key) { | |||
| try { | |||
| Logger.log('SearchResultTabWidget data = ${data.toString()}'); | |||
| model = SearchResultTabModel.fromJson(jsonDecode(data['data'])); | |||
| } catch (e) { | |||
| Logger.error(e.toString()); | |||
| @@ -40,7 +43,27 @@ class _SearchResultTabWidgetState extends State<SearchResultTabWidget> { | |||
| @override | |||
| void initState() { | |||
| _tabController = TabController(length: widget?.model?.search_icon_list?.length ?? 0, vsync: ScrollableState()); | |||
| int length = widget?.model?.search_icon_list?.length ?? 0; | |||
| int initIndex = 0; | |||
| try{ | |||
| for(int i = 0; i<length; i++){ | |||
| SearchResultTabItemModel item = widget.model.search_icon_list[i]; | |||
| if(item.type == widget.model.type.toString()){ | |||
| initIndex = i; | |||
| break; | |||
| } | |||
| } | |||
| }catch(_){} | |||
| _tabController = TabController(length: length, vsync: ScrollableState(), initialIndex: initIndex); | |||
| // ..addListener((){ | |||
| // String type = ''; | |||
| // try{ | |||
| // type = widget.model.search_icon_list[_tabController.index].type; | |||
| // }catch(_){} | |||
| // if(!EmptyUtil.isEmpty(type)) { | |||
| // BlocProvider.of<SearchThinkBloc>(context).add(SearchThinkChangeTypeEvent(type)); | |||
| // } | |||
| // }); | |||
| super.initState(); | |||
| } | |||
| @@ -117,10 +140,21 @@ class _SearchResultTabWidgetState extends State<SearchResultTabWidget> { | |||
| /// tabBraviwe | |||
| _getTabBarViewWidget(model), | |||
| Visibility( | |||
| visible: true, | |||
| child: Container(), | |||
| ), | |||
| // BlocConsumer<SearchThinkBloc, SearchThinkState>( | |||
| // listener: (context, state){}, | |||
| // buildWhen: (prev, current){ | |||
| // if(current is SearchThinkErrorState){ | |||
| // return false; | |||
| // } | |||
| // return true; | |||
| // }, | |||
| // builder: (context, state){ | |||
| // if(state is SearchThinkLoadedState){ | |||
| // return _getThinkListWidget(state.model); | |||
| // } | |||
| // return Container(); | |||
| // }, | |||
| // ), | |||
| ], | |||
| ); | |||
| @@ -129,22 +163,26 @@ class _SearchResultTabWidgetState extends State<SearchResultTabWidget> { | |||
| /// 联想列表 | |||
| Widget _getThinkListWidget(List<SearchThinkModel> model){ | |||
| return ListView.builder(itemBuilder: (context, index){ | |||
| SearchThinkModel item = model[index]; | |||
| return GestureDetector( | |||
| onTap: ()=> _onThinkItemClick(item), | |||
| child: Container( | |||
| decoration: BoxDecoration( | |||
| border: Border(bottom: BorderSide(width: 0.5, color: HexColor.fromHex('#EEEEEE'))) | |||
| return Container( | |||
| height: double.infinity, | |||
| color: Colors.white, | |||
| child: ListView.builder(itemBuilder: (context, index){ | |||
| SearchThinkModel item = model[index]; | |||
| return GestureDetector( | |||
| onTap: ()=> _onThinkItemClick(item), | |||
| child: Container( | |||
| decoration: BoxDecoration( | |||
| border: Border(bottom: BorderSide(width: 0.5, color: HexColor.fromHex('#EEEEEE'))) | |||
| ), | |||
| padding: const EdgeInsets.only(top: 13, bottom: 13), | |||
| child: Text('${item?.keywords}', style: TextStyle( color: HexColor.fromHex('#333333'), fontSize: 14),), | |||
| ), | |||
| padding: const EdgeInsets.only(top: 13, bottom: 13), | |||
| child: Text('${item?.keywords}', style: TextStyle( color: HexColor.fromHex('#333333'), fontSize: 14),), | |||
| ), | |||
| ); | |||
| }, | |||
| itemCount: model?.length ?? 0, | |||
| padding: const EdgeInsets.only(left: 12.5, right: 12.5), | |||
| shrinkWrap: true, | |||
| ); | |||
| }, | |||
| itemCount: model?.length ?? 0, | |||
| padding: const EdgeInsets.only(left: 12.5, right: 12.5), | |||
| shrinkWrap: true, | |||
| ), | |||
| ); | |||
| } | |||
| @@ -1,7 +1,7 @@ | |||
| import 'dart:convert'; | |||
| import 'package:flutter/material.dart'; | |||
| import 'package:zhiying_base_widget/widgets/home/home_quick_entry/cached_network_image_util.dart'; | |||
| import 'package:cached_network_image/cached_network_image.dart'; | |||
| import 'package:zhiying_base_widget/widgets/wallet/wallet_bil/model/wallet_bli_model.dart'; | |||
| import 'package:zhiying_base_widget/widgets/wallet/wallet_income/wallet_income_sk.dart'; | |||