@@ -10,12 +10,15 @@ import 'package:zhiying_base_widget/pages/main_page/notifier/main_page_bg_notifi | |||
import 'package:zhiying_base_widget/pages/main_page/notifier/main_page_notifier.dart'; | |||
import 'package:zhiying_base_widget/utils/contants.dart'; | |||
import 'package:zhiying_base_widget/widgets/others/mine_header_bg_widget.dart'; | |||
import 'package:zhiying_base_widget/widgets/wallet/wallet_detail/wallet_detail_sk.dart'; | |||
import 'package:zhiying_base_widget/widgets/wallet_bil_detail/wallet_bil_sk.dart'; | |||
import 'package:zhiying_comm/zhiying_comm.dart'; | |||
import 'package:zhiying_comm/util/base_bloc.dart'; | |||
import 'package:zhiying_comm/util/custom_sliver_persistent_header_delegate.dart'; | |||
import 'package:zhiying_comm/zhiying_comm.dart'; | |||
import 'package:flutter_alibc/flutter_alibc.dart'; | |||
///钱包明细 | |||
class BilDetailPage extends StatefulWidget { | |||
final Map<String, dynamic> data; | |||
@@ -61,206 +64,45 @@ class _BilDetailPageContainerState extends State<BilDetailPageContainer> { | |||
@override | |||
void initState() { | |||
_bloc = BlocProvider.of<BilDetailPageBloc>(context); | |||
_bloc.loadData(widget.data[Constants.SkipIdentifierName]); | |||
showDate = DateFormat('yyyy-MM').format(DateTime.now()); | |||
super.initState(); | |||
} | |||
@override | |||
Widget build(BuildContext context) { | |||
return StreamBuilder( | |||
stream: _bloc.outData, | |||
builder: (context, sny) { | |||
if (sny.data == null) { | |||
return WalletBilDetailSkeleton(); | |||
} | |||
var model = sny.data; | |||
return Scaffold( | |||
appBar: AppBar( | |||
centerTitle: true, | |||
title: Text("明细"), | |||
), | |||
body: Container( | |||
child: ListView( | |||
shrinkWrap: true, | |||
children: <Widget>[_buildType(), _buildBottomItem()], | |||
), | |||
), | |||
child: Column( | |||
children: _buildItem(model), | |||
)), | |||
); | |||
}, | |||
); | |||
} | |||
_buildType() { | |||
return Row( | |||
children: <Widget>[ | |||
SizedBox(width: 12.5), | |||
InkWell( | |||
onTap: () { | |||
///显示日期选择弹窗 | |||
_selectDate(); | |||
}, | |||
child: Padding( | |||
padding: const EdgeInsets.only(top: 8, bottom: 8), | |||
child: Text(showDate ?? ""), | |||
), | |||
), | |||
Icon(Icons.arrow_drop_down), | |||
Expanded( | |||
child: Container( | |||
height: 50, | |||
child: ListView.builder( | |||
scrollDirection: Axis.horizontal, | |||
shrinkWrap: true, | |||
itemCount: 3, | |||
itemBuilder: (context, index) { | |||
return InkWell(child: Container( | |||
margin: | |||
EdgeInsets.only(top: 10, left: 8, right: 8, bottom: 10), | |||
decoration: BoxDecoration( | |||
color: Colors.grey[200], | |||
borderRadius: BorderRadius.circular(50)), | |||
child: Padding( | |||
padding: const EdgeInsets.only(left: 16, right: 16), | |||
child: Center( | |||
child: Text( | |||
"推广", | |||
style: TextStyle(color: Colors.grey), | |||
)), | |||
), | |||
),onTap: () async { | |||
print("ok"); | |||
await FlutterAlibc.loginTaoBao(); | |||
},); | |||
}), | |||
)) | |||
], | |||
); | |||
} | |||
void _selectDate() async { | |||
showDialog(context: context, builder: (context) => SelectDateYMDialog()); | |||
} | |||
_buildBottomItem() { | |||
return ListView.builder( | |||
shrinkWrap: true, itemCount: 10, itemBuilder: _buildItem); | |||
} | |||
Widget _buildItem(BuildContext context, int index) { | |||
return Container( | |||
margin: EdgeInsets.only(left: 12.5, right: 12.5, bottom: 4, top: 4), | |||
padding: | |||
EdgeInsets.only(left: 25.w, right: 25.w, top: 20.h, bottom: 20.h), | |||
child: Column( | |||
children: <Widget>[ | |||
Row( | |||
mainAxisAlignment: MainAxisAlignment.spaceBetween, | |||
children: <Widget>[ | |||
Row( | |||
children: <Widget>[ | |||
Container( | |||
decoration: BoxDecoration( | |||
borderRadius: BorderRadius.circular(4), | |||
color: Colors.red[100], | |||
border: Border.all(color: Colors.red)), | |||
child: Padding( | |||
padding: const EdgeInsets.only( | |||
left: 4, right: 4, top: 2, bottom: 2), | |||
child: Center( | |||
child: Text( | |||
"自购", | |||
style: TextStyle(color: Colors.red, fontSize: 20.sp), | |||
), | |||
), | |||
), | |||
), | |||
Container( | |||
width: 443.w, | |||
margin: EdgeInsets.only(left: 15.w), | |||
child: Text( | |||
"Segway Ninebot mini Pro智能代的卅饭店发生的范德萨地方撒发生", | |||
maxLines: 1, | |||
overflow: TextOverflow.ellipsis, | |||
style: TextStyle(fontSize: 28.sp), | |||
)) | |||
], | |||
), | |||
Row( | |||
children: <Widget>[ | |||
Text( | |||
"+", | |||
style: TextStyle(color: Colors.red), | |||
), | |||
Text( | |||
"¥8.00", | |||
style: TextStyle(color: Colors.red, fontSize: 30.sp), | |||
) | |||
], | |||
) | |||
], | |||
), | |||
SizedBox( | |||
height: 4, | |||
), | |||
Row( | |||
children: <Widget>[ | |||
Text( | |||
"订单编号:", | |||
style: TextStyle( | |||
color: HexColor.fromHex("#FF999999"), fontSize: 22.sp), | |||
), | |||
Text( | |||
"1233333333", | |||
style: TextStyle( | |||
color: HexColor.fromHex("#FF999999"), fontSize: 22.sp), | |||
), | |||
SizedBox( | |||
width: 28.w, | |||
), | |||
Container( | |||
decoration: BoxDecoration( | |||
borderRadius: BorderRadius.circular(4), | |||
color: HexColor.fromHex("#FFF5F5F5"), | |||
border: Border.all(color: HexColor.fromHex("#FFD6D6D6"))), | |||
child: Padding( | |||
padding: | |||
EdgeInsets.only(left: 16, right: 16, top: 1, bottom: 1), | |||
child: Text( | |||
"复制", | |||
style: TextStyle( | |||
color: HexColor.fromHex("#FF999999"), fontSize: 22.sp), | |||
), | |||
), | |||
) | |||
], | |||
), | |||
Row( | |||
children: <Widget>[ | |||
Text( | |||
"订单编号:", | |||
style: TextStyle( | |||
color: HexColor.fromHex("#FF999999"), fontSize: 22.sp), | |||
), | |||
Text( | |||
"1233333333", | |||
style: TextStyle( | |||
color: HexColor.fromHex("#FF999999"), fontSize: 22.sp), | |||
), | |||
], | |||
), | |||
Row( | |||
children: <Widget>[ | |||
Text( | |||
"订单编号:", | |||
style: TextStyle( | |||
color: HexColor.fromHex("#FF999999"), fontSize: 22.sp), | |||
), | |||
Text( | |||
"1233333333", | |||
style: TextStyle( | |||
color: HexColor.fromHex("#FF999999"), fontSize: 22.sp), | |||
), | |||
], | |||
) | |||
], | |||
), | |||
); | |||
///构建子模块 | |||
_buildItem(List<Map<String, dynamic>> model) { | |||
List<Widget> list = List(); | |||
for (var item in model) { | |||
WidgetModel widgetModel = | |||
WidgetModel.fromJson(Map<String, dynamic>.from(item)); | |||
if (widgetModel.modName == 'my_wallet_detail') { | |||
list.add(Expanded( | |||
child: WidgetFactory.create(widgetModel.modName, | |||
isSliver: false, model: item)[0])); | |||
continue; | |||
} | |||
list.addAll(WidgetFactory.create(widgetModel.modName, | |||
isSliver: false, model: item)); | |||
} | |||
return list; | |||
} | |||
} |
@@ -1,5 +1,6 @@ | |||
import 'dart:async'; | |||
import 'package:zhiying_base_widget/widgets/wallet_bil_detail/model/wallet_style_model.dart'; | |||
import 'package:zhiying_comm/util/base_bloc.dart'; | |||
import 'package:zhiying_comm/zhiying_comm.dart'; | |||
@@ -11,7 +12,7 @@ class BilDetailPageBloc extends BlocBase { | |||
Stream<List<Map<String, dynamic>>> get outData => _tabController.stream; | |||
BilDetailStyleModel bilDetailStyleModel; | |||
@override | |||
void dispose() { | |||
@@ -21,7 +22,7 @@ class BilDetailPageBloc extends BlocBase { | |||
loadData(String skipIdentifier) { | |||
NetUtil.request('/api/v1/mod/${skipIdentifier}', method: NetMethod.GET, | |||
NetUtil.request('/api/v1/mod/pub.flutter.my_wallet_detail', method: NetMethod.GET, | |||
onCache: (data) { | |||
_loadData(data); | |||
}, onSuccess: (data) { | |||
@@ -1,22 +0,0 @@ | |||
import 'package:flutter/material.dart'; | |||
class FavoritePage extends StatefulWidget { | |||
@override | |||
_FavoritePageState createState() => _FavoritePageState(); | |||
} | |||
class _FavoritePageState extends State<FavoritePage> { | |||
GlobalKey _globalKey = GlobalKey(); | |||
@override | |||
Widget build(BuildContext context) { | |||
return Scaffold( | |||
appBar: AppBar( | |||
title: Text('收藏夹'), | |||
), | |||
body: Column( | |||
children: <Widget>[], | |||
), | |||
); | |||
} | |||
} |
@@ -1,17 +0,0 @@ | |||
import 'package:flutter/material.dart'; | |||
class PreviewPage extends StatelessWidget { | |||
final Image image; | |||
const PreviewPage({Key key, this.image}) : super(key: key); | |||
@override | |||
Widget build(BuildContext context) { | |||
return Scaffold( | |||
appBar: AppBar(), | |||
body: Center( | |||
child: image, | |||
), | |||
); | |||
} | |||
} |
@@ -0,0 +1,49 @@ | |||
import 'dart:async'; | |||
import 'package:bloc/bloc.dart'; | |||
import 'package:equatable/equatable.dart'; | |||
import 'package:flutter/material.dart'; | |||
import 'package:meta/meta.dart'; | |||
import 'package:zhiying_base_widget/pages/favorites_page/bloc/favorites_repository.dart'; | |||
import 'package:zhiying_base_widget/pages/favorites_page/model/favorites_style_model.dart'; | |||
import 'package:zhiying_comm/util/empty_util.dart'; | |||
part 'favorites_event.dart'; | |||
part 'favorites_state.dart'; | |||
class FavoritesBloc extends Bloc<FavoritesEvent, FavoritesState> { | |||
// FavoritesBloc() : super(FavoritesInitial()); | |||
FavoritesRepository repository; | |||
FavoritesBloc(this.repository); | |||
@override | |||
// TODO: implement initialState | |||
FavoritesState get initialState => FavoritesInitial(); | |||
@override | |||
Stream<FavoritesState> mapEventToState( | |||
FavoritesEvent event, | |||
) async* { | |||
/// 初始化 | |||
if (event is FavoritesInitEvent) { | |||
yield* _mapInitEventToState(event); | |||
} | |||
} | |||
/// 初始化 | |||
Stream<FavoritesState> _mapInitEventToState(FavoritesInitEvent event) async* { | |||
var cache = await repository.fetchCachedStyle(); | |||
if (!EmptyUtil.isEmpty(cache)) { | |||
yield FavoritesLoadedState(model: cache); | |||
} | |||
var result = await repository.fetchNetStyle(); | |||
if (!EmptyUtil.isEmpty(result)) { | |||
yield FavoritesLoadedState(model: result); | |||
} else { | |||
yield FavoritesErrorState(); | |||
} | |||
} | |||
} |
@@ -0,0 +1,7 @@ | |||
part of 'favorites_bloc.dart'; | |||
@immutable | |||
abstract class FavoritesEvent {} | |||
/// 初始化数据 | |||
class FavoritesInitEvent extends FavoritesEvent {} |
@@ -0,0 +1,39 @@ | |||
import 'dart:convert'; | |||
import 'package:zhiying_base_widget/pages/favorites_page/model/favorites_style_model.dart'; | |||
import 'package:zhiying_base_widget/widgets/empty/empty_widget.dart'; | |||
import 'package:zhiying_comm/zhiying_comm.dart'; | |||
class FavoritesRepository { | |||
/// 请求网络样式 | |||
Future<FavoritesStyleModel> fetchNetStyle() async { | |||
try { | |||
var result = await NetUtil.post('/api/v1/mod/pub.flutter.my_fav', cache: true, method: NetMethod.GET); | |||
if (NetUtil.isSuccess(result) && !EmptyUtil.isEmpty(result[GlobalConfig.HTTP_RESPONSE_KEY_DATA])) { | |||
var modListData = result[GlobalConfig.HTTP_RESPONSE_KEY_DATA]['mod_list'][0]['data']; | |||
if(!EmptyUtil.isEmpty(modListData)){ | |||
return FavoritesStyleModel.fromJson(jsonDecode(modListData)); | |||
} | |||
} | |||
} catch (e, s) { | |||
Logger.log(e, s); | |||
} | |||
return null; | |||
} | |||
/// 获取缓存样式 | |||
Future<FavoritesStyleModel> fetchCachedStyle() async { | |||
try { | |||
var result = await NetUtil.getRequestCachedData(''); | |||
if(!EmptyUtil.isEmpty(result)){ | |||
var modListData = result['mod_list'][0]['data']; | |||
if(!EmptyUtil.isEmpty(modListData)){ | |||
return FavoritesStyleModel.fromJson(jsonDecode(modListData)); | |||
} | |||
} | |||
} catch (e, s) { | |||
Logger.log(e, s); | |||
} | |||
return null; | |||
} | |||
} |
@@ -0,0 +1,23 @@ | |||
part of 'favorites_bloc.dart'; | |||
@immutable | |||
abstract class FavoritesState extends Equatable { | |||
@override | |||
List<Object> get props => []; | |||
} | |||
/// 初始化状态(骨架图) | |||
class FavoritesInitial extends FavoritesState {} | |||
/// 数据加载成功 | |||
class FavoritesLoadedState extends FavoritesState { | |||
FavoritesStyleModel model; | |||
FavoritesLoadedState({@required this.model}); | |||
@override | |||
List<Object> get props => [this.model]; | |||
} | |||
/// 未知错误 | |||
class FavoritesErrorState extends FavoritesState {} |
@@ -0,0 +1,270 @@ | |||
import 'package:flutter/material.dart'; | |||
import 'package:flutter/services.dart'; | |||
import 'package:tab_indicator_styler/tab_indicator_styler.dart'; | |||
import 'package:zhiying_base_widget/pages/favorites_page/bloc/favorites_bloc.dart'; | |||
import 'package:zhiying_base_widget/pages/favorites_page/bloc/favorites_repository.dart'; | |||
import 'package:zhiying_base_widget/widgets/favorites/goods_list/favorites_goods_list_widget.dart'; | |||
import 'package:zhiying_comm/util/empty_util.dart'; | |||
import 'package:zhiying_comm/util/extension/color.dart'; | |||
import 'package:flutter_bloc/flutter_bloc.dart'; | |||
import 'package:provider/provider.dart'; | |||
import 'package:zhiying_comm/util/log/let_log.dart'; | |||
import 'package:fluttertoast/fluttertoast.dart'; | |||
import 'package:zhiying_comm/util/router_util.dart'; | |||
import 'model/favorites_style_model.dart'; | |||
import 'notifier/favorites_page_notifier.dart'; | |||
/// | |||
/// 收藏夹 | |||
/// | |||
class FavoritesPage extends StatelessWidget { | |||
@override | |||
Widget build(BuildContext context) { | |||
return MultiProvider( | |||
providers: [ | |||
ChangeNotifierProvider.value(value: FavoritesPageNotifier()), | |||
], | |||
child: BlocProvider<FavoritesBloc>( | |||
create: (_) => FavoritesBloc(FavoritesRepository())..add(FavoritesInitEvent()), | |||
child: _FavoritesPageContainer(), | |||
), | |||
); | |||
} | |||
} | |||
class _FavoritesPageContainer extends StatefulWidget { | |||
@override | |||
_FavoritesPageContainerState createState() => _FavoritesPageContainerState(); | |||
} | |||
class _FavoritesPageContainerState extends State<_FavoritesPageContainer> with TickerProviderStateMixin { | |||
TextEditingController _editingController; | |||
FocusNode _focusNode; | |||
TabController _tabController; | |||
bool _isNotEditing = true; | |||
/// 点击编辑 | |||
void _onClickEditing() { | |||
RouterUtil.hideKeyboard(context); | |||
setState(() { | |||
_isNotEditing = !_isNotEditing; | |||
}); | |||
Provider.of<FavoritesPageNotifier>(context, listen: false).editing(); | |||
} | |||
/// 点击搜索 | |||
void _onClickSearch() {} | |||
/// 执行搜索 | |||
void _submitSearch() { | |||
String keyword = _editingController?.text?.toString()?.trim(); | |||
// if (!EmptyUtil.isEmpty(keyword)) { | |||
_tabController.index = 0; | |||
Provider.of<FavoritesPageNotifier>(context, listen: false).search(keyword); | |||
// } else { | |||
// Fluttertoast.showToast(msg: '请输入需要搜索的内容~'); | |||
// } | |||
} | |||
/// tabBar的初始化 | |||
void _tabControllerInit(FavoritesStyleModel model) { | |||
if ((null == _tabController && !EmptyUtil.isEmpty(model?.tabList)) || | |||
(!EmptyUtil.isEmpty(model?.tabList) && null != _tabController && _tabController.length != model.tabList.length)) { | |||
_tabController = TabController(length: model.tabList.length, vsync: this) | |||
..addListener(() { | |||
if (!_tabController.indexIsChanging) { | |||
RouterUtil.hideKeyboard(context); | |||
Logger.log('tab index = ${_tabController.index}'); | |||
Provider.of<FavoritesPageNotifier>(context, listen: false).changeSelectIndex(_tabController.index); | |||
} | |||
}); | |||
} | |||
} | |||
@override | |||
void initState() { | |||
_editingController = TextEditingController(); | |||
_focusNode = FocusNode(); | |||
super.initState(); | |||
} | |||
@override | |||
void dispose() { | |||
_focusNode?.unfocus(); | |||
_focusNode?.dispose(); | |||
_editingController?.dispose(); | |||
super.dispose(); | |||
} | |||
@override | |||
Widget build(BuildContext context) { | |||
return BlocConsumer<FavoritesBloc, FavoritesState>( | |||
listener: (context, state) {}, | |||
buildWhen: (prev, current) { | |||
return true; | |||
}, | |||
builder: (context, state) { | |||
if (state is FavoritesLoadedState) { | |||
_tabControllerInit(state?.model); | |||
return _buildMainWidget(state?.model); | |||
} | |||
return _buildSkeletonWidget(); | |||
}, | |||
); | |||
} | |||
/// mainWidget | |||
Widget _buildMainWidget(FavoritesStyleModel model) { | |||
return Scaffold( | |||
resizeToAvoidBottomInset: false, | |||
resizeToAvoidBottomPadding: false, | |||
backgroundColor: HexColor.fromHex('#FFFFFF'), | |||
appBar: _buildAppBarWidget(model), | |||
body: Column( | |||
children: <Widget>[ | |||
/// 搜索框 | |||
Padding(padding: const EdgeInsets.only(left: 12.5, right: 12.5, top: 4), child: _buildSearchWidget(model)), | |||
/// tabBar | |||
Padding(padding: const EdgeInsets.only(top: 4), child: _buildTabBarWidget(model)), | |||
Expanded( | |||
child: _buildTabBarViewWidget(model), | |||
), | |||
], | |||
), | |||
); | |||
} | |||
/// TabBar | |||
Widget _buildTabBarWidget(FavoritesStyleModel model) { | |||
return Container( | |||
padding: const EdgeInsets.only(top: 12.5, bottom: 14.5), | |||
width: double.infinity, | |||
child: TabBar( | |||
isScrollable: true, | |||
labelStyle: TextStyle(fontSize: 14, fontWeight: FontWeight.bold), | |||
unselectedLabelStyle: TextStyle(fontWeight: FontWeight.w400, fontSize: 14), | |||
labelColor: HexColor.fromHex(model?.tabNameSelectedColor ?? '#FF0100'), | |||
unselectedLabelColor: HexColor.fromHex(model?.tabNameColor ?? '#333333'), | |||
indicatorSize: TabBarIndicatorSize.label, | |||
controller: _tabController, | |||
indicatorWeight: 5, | |||
indicator: MaterialIndicator( | |||
topLeftRadius: 1, | |||
topRightRadius: 1, | |||
bottomLeftRadius: 1, | |||
bottomRightRadius: 1, | |||
height: 2, | |||
color: HexColor.fromHex(model?.tabLineColor ?? '#FF0100'), | |||
horizontalPadding: 5, | |||
), | |||
tabs: model.tabList.map((e) => Text(e?.name ?? '')).toList(), | |||
), | |||
); | |||
} | |||
/// tabBarView | |||
Widget _buildTabBarViewWidget(FavoritesStyleModel model) { | |||
int length = model?.tabList?.length ?? 0; | |||
if (length > 0) { | |||
int index = -1; | |||
return TabBarView( | |||
physics: NeverScrollableScrollPhysics(), | |||
controller: _tabController, | |||
children: model.tabList.map((e) { | |||
++index; | |||
return FavoritesGoodsListWidget( | |||
model: model, | |||
type: e?.type, | |||
currentIndex: index, | |||
); | |||
}).toList(), | |||
); | |||
} | |||
return Container(color: HexColor.fromHex('#F9F9F9')); | |||
} | |||
/// 搜索框 | |||
Widget _buildSearchWidget(FavoritesStyleModel model) { | |||
return Container( | |||
alignment: Alignment.center, | |||
width: double.infinity, | |||
height: 35, | |||
decoration: BoxDecoration( | |||
borderRadius: BorderRadius.circular(35 / 2), | |||
color: HexColor.fromHex(model?.searchBarBgColor ?? '#F9F9F9'), | |||
), | |||
child: TextField( | |||
controller: _editingController, | |||
focusNode: _focusNode, | |||
onSubmitted: (text) => _submitSearch(), | |||
textInputAction: TextInputAction.search, | |||
style: TextStyle(color: HexColor.fromHex('#333333'), fontSize: 14, textBaseline: TextBaseline.alphabetic), | |||
textAlign: TextAlign.center, | |||
decoration: InputDecoration( | |||
fillColor: Colors.transparent, | |||
filled: true, | |||
isDense: true, | |||
contentPadding: EdgeInsets.zero, | |||
hintText: model?.searchBarText ?? '搜索商品', | |||
hintStyle: TextStyle(color: HexColor.fromHex(model?.searchBarTextColor ?? '#999999'), fontSize: 14, textBaseline: TextBaseline.alphabetic), | |||
border: InputBorder.none, | |||
enabledBorder: InputBorder.none, | |||
disabledBorder: InputBorder.none, | |||
errorBorder: InputBorder.none, | |||
focusedErrorBorder: InputBorder.none, | |||
focusedBorder: InputBorder.none, | |||
), | |||
), | |||
); | |||
} | |||
/// appbar | |||
Widget _buildAppBarWidget(FavoritesStyleModel model) { | |||
return AppBar( | |||
backgroundColor: HexColor.fromHex(model?.appBarBgColor ?? '#FFFFFF'), | |||
brightness: Brightness.light, | |||
leading: IconButton( | |||
icon: Icon( | |||
Icons.arrow_back_ios, | |||
size: 22, | |||
color: HexColor.fromHex('#333333'), | |||
), | |||
onPressed: () => Navigator.maybePop(context), | |||
), | |||
title: Text( | |||
model?.appBarName ?? '我的收藏', | |||
style: TextStyle(color: HexColor.fromHex(model?.appBarNameColor ?? '#333333'), fontSize: 15, fontWeight: FontWeight.bold), | |||
), | |||
centerTitle: true, | |||
elevation: 0, | |||
actions: <Widget>[ | |||
GestureDetector( | |||
onTap: () => _onClickEditing(), | |||
behavior: HitTestBehavior.opaque, | |||
child: Center( | |||
child: Padding( | |||
padding: const EdgeInsets.only(right: 12.5), | |||
child: Text( | |||
_isNotEditing ? model?.appBarRightText ?? '编辑' : model?.appBarRightEditingText ?? '完成', | |||
style: TextStyle( | |||
color: HexColor.fromHex(_isNotEditing ? model?.appBarRightTextColor ?? '#333333' : model?.appBarRightEditingColor ?? '#FF4242'), | |||
fontSize: 14, | |||
fontWeight: FontWeight.bold), | |||
), | |||
), | |||
), | |||
) | |||
], | |||
); | |||
} | |||
/// 骨架图 | |||
Widget _buildSkeletonWidget() { | |||
return Scaffold( | |||
body: Container(), | |||
); | |||
} | |||
} |
@@ -0,0 +1,278 @@ | |||
import 'package:zhiying_base_widget/widgets/home/home_goods/models/home_goods_list_style_model.dart'; | |||
class FavoritesStyleModel { | |||
String appBarName; | |||
String appBarNameColor; | |||
String appBarBgImg; | |||
String appBarBgColor; | |||
String appBarRightText; | |||
String appBarRightTextColor; | |||
String appBarRightEditingText; | |||
String appBarRightEditingColor; | |||
String searchBarIcon; | |||
String searchBarText; | |||
String searchBarTextColor; | |||
String searchBarBgColor; | |||
String tabLineColor; | |||
String tabItemNotFoundImg; | |||
List<TabList> tabList; | |||
HomeGoodsListStyleModel listStyle; | |||
String editLeftConfirmColor; | |||
String editLeftNoConfirmColor; | |||
Bottom bottom; | |||
ConfirmDialog confirmDialog; | |||
String tabNameColor; | |||
String tabNameSelectedColor; | |||
String editLeftConfirmIcon; | |||
String editLeftNoConfirmIcon; | |||
FavoritesStyleModel({ | |||
this.appBarName, | |||
this.appBarNameColor, | |||
this.appBarBgImg, | |||
this.appBarBgColor, | |||
this.appBarRightText, | |||
this.appBarRightTextColor, | |||
this.appBarRightEditingText, | |||
this.appBarRightEditingColor, | |||
this.searchBarIcon, | |||
this.searchBarText, | |||
this.searchBarTextColor, | |||
this.searchBarBgColor, | |||
this.tabLineColor, | |||
this.tabItemNotFoundImg, | |||
this.tabList, | |||
this.listStyle, | |||
this.editLeftConfirmColor, | |||
this.editLeftNoConfirmColor, | |||
this.bottom, | |||
this.confirmDialog, | |||
this.tabNameColor, | |||
this.tabNameSelectedColor, | |||
this.editLeftConfirmIcon, | |||
this.editLeftNoConfirmIcon, | |||
}); | |||
FavoritesStyleModel.fromJson(Map<String, dynamic> json) { | |||
appBarName = json['app_bar_name']; | |||
appBarNameColor = json['app_bar_name_color']; | |||
appBarBgImg = json['app_bar_bg_img']; | |||
appBarBgColor = json['app_bar_bg_color']; | |||
appBarRightText = json['app_bar_right_text']; | |||
appBarRightTextColor = json['app_bar_right_text_color']; | |||
appBarRightEditingText = json['app_bar_right_editing_text']; | |||
appBarRightEditingColor = json['app_bar_right_editing_color']; | |||
searchBarIcon = json['search_bar_icon']; | |||
searchBarText = json['search_bar_text']; | |||
searchBarTextColor = json['search_bar_text_color']; | |||
searchBarBgColor = json['search_bar_bg_color']; | |||
tabLineColor = json['tab_line_color']; | |||
tabItemNotFoundImg = json['tab_item_not_found_img']; | |||
if (json['tab_list'] != null) { | |||
tabList = new List<TabList>(); | |||
json['tab_list'].forEach((v) { | |||
tabList.add(new TabList.fromJson(v)); | |||
}); | |||
} | |||
listStyle = json['list_style'] != null ? new HomeGoodsListStyleModel.fromJson(json['list_style']) : null; | |||
editLeftConfirmColor = json['edit_left_confirm_color']; | |||
editLeftNoConfirmColor = json['edit_left_no_confirm_color']; | |||
bottom = json['bottom'] != null ? new Bottom.fromJson(json['bottom']) : null; | |||
confirmDialog = json['confirm_dialog'] != null ? new ConfirmDialog.fromJson(json['confirm_dialog']) : null; | |||
tabNameColor = json['tab_name_color']; | |||
tabNameSelectedColor = json['tab_name_selected_color']; | |||
editLeftConfirmIcon = json['edit_left_confirm_icon']; | |||
editLeftNoConfirmIcon = json['edit_left_no_confirm_icon']; | |||
} | |||
Map<String, dynamic> toJson() { | |||
final Map<String, dynamic> data = new Map<String, dynamic>(); | |||
data['app_bar_name'] = this.appBarName; | |||
data['app_bar_name_color'] = this.appBarNameColor; | |||
data['app_bar_bg_img'] = this.appBarBgImg; | |||
data['app_bar_bg_color'] = this.appBarBgColor; | |||
data['app_bar_right_text'] = this.appBarRightText; | |||
data['app_bar_right_text_color'] = this.appBarRightTextColor; | |||
data['app_bar_right_editing_text'] = this.appBarRightEditingText; | |||
data['app_bar_right_editing_color'] = this.appBarRightEditingColor; | |||
data['search_bar_icon'] = this.searchBarIcon; | |||
data['search_bar_text'] = this.searchBarText; | |||
data['search_bar_text_color'] = this.searchBarTextColor; | |||
data['search_bar_bg_color'] = this.searchBarBgColor; | |||
data['tab_line_color'] = this.tabLineColor; | |||
data['tab_item_not_found_img'] = this.tabItemNotFoundImg; | |||
if (this.tabList != null) { | |||
data['tab_list'] = this.tabList.map((v) => v.toJson()).toList(); | |||
} | |||
if (this.listStyle != null) { | |||
data['list_style'] = this.listStyle.toJson(); | |||
} | |||
data['edit_left_confirm_color'] = this.editLeftConfirmColor; | |||
data['edit_left_no_confirm_color'] = this.editLeftNoConfirmColor; | |||
if (this.bottom != null) { | |||
data['bottom'] = this.bottom.toJson(); | |||
} | |||
if (this.confirmDialog != null) { | |||
data['confirm_dialog'] = this.confirmDialog.toJson(); | |||
} | |||
data['tab_name_color'] = this.tabNameColor; | |||
data['tab_name_selected_color'] = this.tabNameSelectedColor; | |||
data['edit_left_confirm_icon'] = this.editLeftConfirmIcon; | |||
data['edit_left_no_confirm_icon'] = this.editLeftNoConfirmIcon; | |||
return data; | |||
} | |||
} | |||
class TabList { | |||
String type; | |||
String name; | |||
String nameColor; | |||
String nameSelectedColor; | |||
TabList({this.type, this.name, this.nameColor, this.nameSelectedColor}); | |||
TabList.fromJson(Map<String, dynamic> json) { | |||
type = json['type']; | |||
name = json['name']; | |||
nameColor = json['name_color']; | |||
nameSelectedColor = json['name_selected_color']; | |||
} | |||
Map<String, dynamic> toJson() { | |||
final Map<String, dynamic> data = new Map<String, dynamic>(); | |||
data['type'] = this.type; | |||
data['name'] = this.name; | |||
data['name_color'] = this.nameColor; | |||
data['name_selected_color'] = this.nameSelectedColor; | |||
return data; | |||
} | |||
} | |||
class Left { | |||
String couonText; | |||
String couponFontColor; | |||
String couponBgColor; | |||
String couponBgImg; | |||
String isImg; | |||
Left({this.couonText, this.couponFontColor, this.couponBgColor, this.couponBgImg, this.isImg}); | |||
Left.fromJson(Map<String, dynamic> json) { | |||
couonText = json['couon_text']; | |||
couponFontColor = json['coupon_font_color']; | |||
couponBgColor = json['coupon_bg_color']; | |||
couponBgImg = json['coupon_bg_img']; | |||
isImg = json['is_img']; | |||
} | |||
Map<String, dynamic> toJson() { | |||
final Map<String, dynamic> data = new Map<String, dynamic>(); | |||
data['couon_text'] = this.couonText; | |||
data['coupon_font_color'] = this.couponFontColor; | |||
data['coupon_bg_color'] = this.couponBgColor; | |||
data['coupon_bg_img'] = this.couponBgImg; | |||
data['is_img'] = this.isImg; | |||
return data; | |||
} | |||
} | |||
class Right { | |||
String commissionText; | |||
String commissionFontColor; | |||
String commissionBgColor; | |||
String commissionBgImg; | |||
String isImg; | |||
Right({this.commissionText, this.commissionFontColor, this.commissionBgColor, this.commissionBgImg, this.isImg}); | |||
Right.fromJson(Map<String, dynamic> json) { | |||
commissionText = json['commission_text']; | |||
commissionFontColor = json['commission_font_color']; | |||
commissionBgColor = json['commission_bg_color']; | |||
commissionBgImg = json['commission_bg_img']; | |||
isImg = json['is_img']; | |||
} | |||
Map<String, dynamic> toJson() { | |||
final Map<String, dynamic> data = new Map<String, dynamic>(); | |||
data['commission_text'] = this.commissionText; | |||
data['commission_font_color'] = this.commissionFontColor; | |||
data['commission_bg_color'] = this.commissionBgColor; | |||
data['commission_bg_img'] = this.commissionBgImg; | |||
data['is_img'] = this.isImg; | |||
return data; | |||
} | |||
} | |||
class Bottom { | |||
String bgColor; | |||
String leftText; | |||
String leftColor; | |||
String rightText; | |||
String rightColor; | |||
Bottom({this.bgColor, this.leftText, this.leftColor, this.rightText, this.rightColor}); | |||
Bottom.fromJson(Map<String, dynamic> json) { | |||
bgColor = json['bg_color']; | |||
leftText = json['left_text']; | |||
leftColor = json['left_color']; | |||
rightText = json['right_text']; | |||
rightColor = json['right_color']; | |||
} | |||
Map<String, dynamic> toJson() { | |||
final Map<String, dynamic> data = new Map<String, dynamic>(); | |||
data['bg_color'] = this.bgColor; | |||
data['left_text'] = this.leftText; | |||
data['left_color'] = this.leftColor; | |||
data['right_text'] = this.rightText; | |||
data['right_color'] = this.rightColor; | |||
return data; | |||
} | |||
} | |||
class ConfirmDialog { | |||
String bgText; | |||
String bgTextColor; | |||
String bgColor; | |||
String leftText; | |||
String leftTextColor; | |||
String leftBtnBgColor; | |||
String rightText; | |||
String rightTextColor; | |||
String rightBtnBgColor; | |||
ConfirmDialog({this.bgText, this.bgTextColor, this.bgColor, this.leftText, this.leftTextColor, this.leftBtnBgColor, this.rightText, this.rightTextColor, this.rightBtnBgColor}); | |||
ConfirmDialog.fromJson(Map<String, dynamic> json) { | |||
bgText = json['bg_text']; | |||
bgTextColor = json['bg_text_color']; | |||
bgColor = json['bg_color']; | |||
leftText = json['left_text']; | |||
leftTextColor = json['left_text_color']; | |||
leftBtnBgColor = json['left_btn_bg_color']; | |||
rightText = json['right_text']; | |||
rightTextColor = json['right_text_color']; | |||
rightBtnBgColor = json['right_btn_bg_color']; | |||
} | |||
Map<String, dynamic> toJson() { | |||
final Map<String, dynamic> data = new Map<String, dynamic>(); | |||
data['bg_text'] = this.bgText; | |||
data['bg_text_color'] = this.bgTextColor; | |||
data['bg_color'] = this.bgColor; | |||
data['left_text'] = this.leftText; | |||
data['left_text_color'] = this.leftTextColor; | |||
data['left_btn_bg_color'] = this.leftBtnBgColor; | |||
data['right_text'] = this.rightText; | |||
data['right_text_color'] = this.rightTextColor; | |||
data['right_btn_bg_color'] = this.rightBtnBgColor; | |||
return data; | |||
} | |||
} |
@@ -0,0 +1,44 @@ | |||
import 'package:flutter/material.dart'; | |||
import 'package:zhiying_comm/util/empty_util.dart'; | |||
class FavoritesPageNotifier with ChangeNotifier { | |||
/// 是否是编辑中 | |||
bool isEditing = false; | |||
/// 搜索关键字 | |||
String keyword; | |||
int selectIndex = 0; | |||
/// 用于区分是编辑还是搜索 | |||
bool editingTypeTag = true; | |||
/// 用于区分是否修改 | |||
// int changeVal = 0; | |||
/// 选中的下标 | |||
void changeSelectIndex(int index){ | |||
this.selectIndex = index; | |||
// ++changeVal; | |||
notifyListeners(); | |||
} | |||
/// 编辑 | |||
void editing() { | |||
this.editingTypeTag = true; | |||
this.isEditing = !isEditing; | |||
// ++changeVal; | |||
notifyListeners(); | |||
} | |||
/// 搜索 | |||
void search(String keyword) { | |||
// if (!EmptyUtil.isEmpty(keyword)) { | |||
this.editingTypeTag = false; | |||
this.keyword = keyword; | |||
// ++changeVal; | |||
notifyListeners(); | |||
// } | |||
} | |||
} |
@@ -72,6 +72,7 @@ class _HomePageState extends State<HomePage> { | |||
String selectedIcon = ImageUtil.getUrl(model.chooseIcon ?? model.icon); | |||
String textColor = model.fontColor; | |||
String chooseColor = model.chooseColor ?? textColor; | |||
items.add(BottomNavigationBarItem( | |||
icon: Container( | |||
width: 24, | |||
@@ -2,6 +2,7 @@ import 'dart:async'; | |||
import 'package:bloc/bloc.dart'; | |||
import 'package:equatable/equatable.dart'; | |||
import 'package:flutter/cupertino.dart'; | |||
import 'package:zhiying_base_widget/pages/message_notice_page/bloc/message_notice_repository.dart'; | |||
import 'package:zhiying_base_widget/pages/message_notice_page/model/message_notice_data_model.dart'; | |||
import 'package:zhiying_base_widget/pages/message_notice_page/model/message_notice_style_model.dart'; | |||
@@ -31,6 +32,11 @@ class MessageNoticeBloc extends Bloc<MessageNoticeEvent, MessageNoticeState> { | |||
yield* _mapInitEventToState(event); | |||
} | |||
/// 消除红点 | |||
if (event is MessageNoticeClearPointEvent) { | |||
yield* _mapClearPointEventToState(event); | |||
} | |||
/// 下拉刷新 | |||
if (event is MessageNoticeOnRefreshEvent) { | |||
yield* _mapOnRefreshEventToState(event); | |||
@@ -61,6 +67,17 @@ class MessageNoticeBloc extends Bloc<MessageNoticeEvent, MessageNoticeState> { | |||
} | |||
} | |||
/// 消除消息右上角红点 | |||
Stream<MessageNoticeState> _mapClearPointEventToState(MessageNoticeClearPointEvent event) async* { | |||
var style = repository.getStyleModel(); | |||
var data = await repository.fetchClearPointData(event.selectId); | |||
if (!EmptyUtil.isEmpty(data)) { | |||
yield MessageNoticeLoadedState(styleModel: style, dataModel: data); | |||
}else{ | |||
yield MessageNoticeOnRefreshErrorState(); | |||
} | |||
} | |||
/// 下拉刷新 | |||
Stream<MessageNoticeState> _mapOnRefreshEventToState(MessageNoticeOnRefreshEvent event) async* { | |||
var style = repository.getStyleModel(); | |||
@@ -11,7 +11,17 @@ abstract class MessageNoticeEvent extends Equatable { | |||
class MessageNoticeInitEvent extends MessageNoticeEvent {} | |||
/// 下拉刷新 | |||
class MessageNoticeOnRefreshEvent extends MessageNoticeEvent{} | |||
class MessageNoticeOnRefreshEvent extends MessageNoticeEvent {} | |||
/// 上拉更多 | |||
class MessageNoticeOnLoadEvent extends MessageNoticeEvent{} | |||
class MessageNoticeOnLoadEvent extends MessageNoticeEvent {} | |||
/// 消除消息红点 | |||
class MessageNoticeClearPointEvent extends MessageNoticeEvent { | |||
final String selectId; | |||
MessageNoticeClearPointEvent({@required this.selectId}); | |||
@override | |||
List<Object> get props => [this.selectId]; | |||
} |
@@ -79,6 +79,21 @@ class MessageNoticeRepository { | |||
return null; | |||
} | |||
/// 消除消息红点 | |||
Future<MessageNoticeDataModel> fetchClearPointData(String selectId) async{ | |||
try{ | |||
_oldData.forEach((element){ | |||
if(element.id == selectId) { | |||
element.unread_count = ''; | |||
} | |||
}); | |||
return MessageNoticeDataModel()..list = _oldData; | |||
}catch(e, s){ | |||
Logger.error(e,s); | |||
} | |||
return null; | |||
} | |||
/// 下拉刷新 | |||
Future<MessageNoticeDataModel> fetchRefreshData() async { | |||
return fetchInitData(); | |||
@@ -51,7 +51,11 @@ class __MessageNoticePageContainerState extends State<_MessageNoticePageContaine | |||
} | |||
/// 子item点击事件 | |||
void _onMainItemClick(MainNotificationStyleItem styleModel) { | |||
void _onMainItemClick(MainNotificationStyleItem styleModel, MessageNoticeDataItemModel dataModel) { | |||
/// 消除消息红点 | |||
BlocProvider.of<MessageNoticeBloc>(context).add(MessageNoticeClearPointEvent(selectId: dataModel?.id)); | |||
/// 如果是消息中心,则重新打开页面加载 | |||
Navigator.push(context, CupertinoPageRoute(builder: (_) => MessageNoticePage({'type': styleModel?.type, 'title': styleModel?.name}))); | |||
} | |||
@@ -221,14 +225,14 @@ class __MessageNoticePageContainerState extends State<_MessageNoticePageContaine | |||
return GestureDetector( | |||
behavior: HitTestBehavior.opaque, | |||
onTap: () => _onMainItemClick(styleModel), | |||
onTap: () => _onMainItemClick(styleModel, dataModel), | |||
child: Container( | |||
decoration: BoxDecoration(color: HexColor.fromHex(styleModel?.bg_color ?? '#FFFFFF'), borderRadius: borderRadius), | |||
padding: const EdgeInsets.only(left: 15, right: 15, top: 16), | |||
child: Column( | |||
children: <Widget>[ | |||
Container( | |||
height: 30, | |||
// height: 30, | |||
width: double.infinity, | |||
child: Row( | |||
children: <Widget>[ | |||
@@ -527,6 +531,7 @@ class __MessageNoticePageContainerState extends State<_MessageNoticePageContaine | |||
/// APPBar | |||
Widget _buildAppBarWidget(MessageNoticeStyleModel styleModel) { | |||
return AppBar( | |||
brightness: Brightness.light, | |||
leading: IconButton( | |||
icon: Icon( | |||
Icons.arrow_back_ios, | |||
@@ -568,7 +573,7 @@ class __MessageNoticePageContainerState extends State<_MessageNoticePageContaine | |||
offset: Offset(5, -4.5), | |||
child: Container( | |||
// width: 17, | |||
height: 12, | |||
// height: 12, | |||
padding: const EdgeInsets.only(left: 3, right: 3, top: 1, bottom: 1), | |||
alignment: Alignment.center, | |||
decoration: BoxDecoration( | |||
@@ -576,7 +581,7 @@ class __MessageNoticePageContainerState extends State<_MessageNoticePageContaine | |||
borderRadius: BorderRadius.circular(6), | |||
border: Border.all(color: HexColor.fromHex('#FFFFFF'), width: 0.5)), | |||
child: Text( | |||
'18', | |||
value?? '', | |||
textAlign: TextAlign.center, | |||
style: TextStyle(fontSize: 9, color: HexColor.fromHex(unreadTextColor ?? '#FFFFFF')), | |||
), | |||
@@ -94,6 +94,7 @@ class _TeamDetailsPageState extends State<_TeamDetailsPage> { | |||
/// 头部Bar | |||
SliverAppBar( | |||
// expandedHeight: 200.0, | |||
brightness: Brightness.light, | |||
leading: IconButton( | |||
icon: Icon( | |||
Icons.arrow_back_ios, | |||
@@ -1,6 +1,6 @@ | |||
import 'package:sharesdk_plugin/sharesdk_interface.dart'; | |||
import 'package:sharesdk_plugin/sharesdk_register.dart'; | |||
import 'package:zhiying_base_widget/pages/favorite_page/favorite_page.dart'; | |||
import 'package:zhiying_base_widget/pages/bil_detail_page/bil_detail_page.dart'; | |||
import 'package:zhiying_base_widget/pages/feedback_page/feedback_page.dart'; | |||
import 'package:zhiying_base_widget/pages/goods_details_page/goods_details_page.dart'; | |||
import 'package:zhiying_base_widget/pages/home_page/home_page.dart'; | |||
@@ -49,9 +49,11 @@ import 'package:zhiying_base_widget/widgets/wallet/wallet_bil/wallet_bil.dart'; | |||
import 'package:zhiying_base_widget/widgets/wallet/wallet_data/wallet_data.dart'; | |||
import 'package:zhiying_base_widget/widgets/wallet/wallet_detail/wallet_detail.dart'; | |||
import 'package:zhiying_base_widget/widgets/wallet/wallet_income/wallet_income.dart'; | |||
import 'package:zhiying_base_widget/widgets/wallet_bil_detail/wallet_bil_detail.dart'; | |||
import 'package:zhiying_comm/util/defalut_widget_creater.dart'; | |||
import 'package:zhiying_comm/zhiying_comm.dart'; | |||
import 'pages/favorites_page/favorites_page.dart'; | |||
import 'pages/message_notice_page/message_notice_page.dart'; | |||
import 'pages/search_page/search_page.dart'; | |||
import 'pages/wallet_page/wallet_page.dart'; | |||
@@ -142,7 +144,7 @@ class BaseWidgetRegister { | |||
// 邀请好友 | |||
PageFactory.regist( | |||
'pub.flutter.invite_friends', (model) => InvitedFriendsPage(model)); | |||
PageFactory.regist('pub.flutter.fav', (model) => FavoritePage()); | |||
/// 我的团队 | |||
PageFactory.regist('pub.flutter.my_team', (model) => TeamPage(model)); | |||
@@ -154,6 +156,18 @@ class BaseWidgetRegister { | |||
/// 消息中心 | |||
PageFactory.regist( | |||
'pub.flutter.message_center', (model) => MessageNoticePage(model)); | |||
PageFactory.regist( | |||
'pub.flutter.message_notice', (model) => MessageNoticePage(model)); | |||
/// TODO 首页的消息中心标识和我的页面不一致,需要改 | |||
PageFactory.regist( | |||
'pub.flutter.message', (model) => MessageNoticePage(model)); | |||
/// 我的收藏 | |||
PageFactory.regist('pub.flutter.my_fav', (model) => FavoritesPage()); | |||
///钱包明细 | |||
PageFactory.regist('pub.flutter.my_bil', (model) => BilDetailPage(model)); | |||
} | |||
// 注册控件 | |||
@@ -320,6 +334,11 @@ class BaseWidgetRegister { | |||
'wallet_income', DefaultWidgetCreater((model) => WalletIncome())); | |||
//======================= 账单明细 | |||
WidgetFactory.regist( | |||
'my_wallet_detail', | |||
DefaultWidgetCreater((model) => WalletBilDetail( | |||
data: model, | |||
))); | |||
//======================== 热榜 | |||
WidgetFactory.regist('hot_rank_appbar', | |||
@@ -0,0 +1,75 @@ | |||
import 'package:flutter/material.dart'; | |||
import 'package:zhiying_base_widget/pages/favorites_page/model/favorites_style_model.dart'; | |||
import 'package:zhiying_comm/zhiying_comm.dart'; | |||
class FavoritesDialogWidget extends StatelessWidget { | |||
ConfirmDialog styleModel; | |||
FavoritesDialogWidget({@required this.styleModel}); | |||
@override | |||
Widget build(BuildContext context) { | |||
return Scaffold( | |||
backgroundColor: Colors.transparent, | |||
body: Column( | |||
mainAxisAlignment: MainAxisAlignment.center, | |||
crossAxisAlignment: CrossAxisAlignment.center, | |||
children: <Widget>[ | |||
Container( | |||
width: double.infinity, | |||
padding: const EdgeInsets.only(top: 30, left: 17, right: 17, bottom: 12.5), | |||
decoration: BoxDecoration(color: HexColor.fromHex(styleModel?.bgColor ?? '#FFFFFF'), borderRadius: BorderRadius.circular(8)), | |||
margin: EdgeInsets.only(left: 46, right: 46), | |||
child: Column( | |||
children: <Widget>[ | |||
/// 标题 | |||
Text(styleModel?.bgText ?? '', style: TextStyle(fontSize: 15, fontWeight: FontWeight.bold, color: HexColor.fromHex(styleModel?.bgTextColor ?? '#333333'))), | |||
const SizedBox(height: 44), | |||
Row( | |||
children: <Widget>[ | |||
Flexible(flex: 1, child: _buildCustomerButtonWidget( | |||
text: styleModel?.leftText ?? '我在想想', | |||
textColor:styleModel?.leftTextColor ?? '#FF4242', | |||
bgColor: styleModel?.leftBtnBgColor ?? '#FFFFFF', | |||
borderColor: styleModel?.leftTextColor ?? '#FF4242', | |||
callback: ()=> Navigator.maybePop(context, 0), | |||
)), | |||
const SizedBox(width: 14), | |||
Flexible(flex: 1, child: _buildCustomerButtonWidget( | |||
text: styleModel?.rightText ?? '确认删除', | |||
textColor: styleModel?.rightTextColor ?? '#FFFFFF', | |||
borderColor: styleModel?.rightTextColor ?? '#FFFFFF', | |||
bgColor: styleModel?.rightBtnBgColor ?? '#FF4242', | |||
callback: ()=> Navigator.maybePop(context, 1), | |||
)), | |||
], | |||
) | |||
], | |||
), | |||
) | |||
], | |||
), | |||
); | |||
} | |||
Widget _buildCustomerButtonWidget({String text, String textColor, String bgColor, String borderColor,GestureTapCallback callback, double height = 30}) { | |||
return GestureDetector( | |||
behavior: HitTestBehavior.opaque, | |||
onTap: callback, | |||
child: Container( | |||
alignment: Alignment.center, | |||
height: height, | |||
width: double.infinity, | |||
decoration: BoxDecoration( | |||
color: HexColor.fromHex(bgColor), | |||
borderRadius: BorderRadius.circular(height / 2), | |||
border: Border.all(color: HexColor.fromHex(borderColor), width: 0.5), | |||
), | |||
child: Text( | |||
text ?? '', | |||
style: TextStyle(color: HexColor.fromHex(textColor), fontSize: 13), | |||
), | |||
), | |||
); | |||
} | |||
} |
@@ -0,0 +1,188 @@ | |||
import 'dart:async'; | |||
import 'package:bloc/bloc.dart'; | |||
import 'package:flutter/material.dart'; | |||
import 'package:meta/meta.dart'; | |||
import 'package:zhiying_base_widget/widgets/favorites/goods_list/model/favorites_goods_list_model.dart'; | |||
import 'package:zhiying_base_widget/widgets/home/home_goods/models/home_goods_model.dart'; | |||
import 'package:zhiying_comm/util/empty_util.dart'; | |||
import 'favorites_goods_list_repository.dart'; | |||
part 'favorites_goods_list_event.dart'; | |||
part 'favorites_goods_list_state.dart'; | |||
class FavoritesGoodsListBloc extends Bloc<FavoritesGoodsListEvent, FavoritesGoodsListState> { | |||
@override | |||
FavoritesGoodsListState get initialState => FavoritesGoodsListInitial(); | |||
FavoritesGoodsListRepository repository; | |||
FavoritesGoodsListBloc(this.repository); | |||
@override | |||
Stream<FavoritesGoodsListState> mapEventToState( | |||
FavoritesGoodsListEvent event, | |||
) async* { | |||
/// 初始化数据 | |||
if (event is FavoritesGoodsListInitEvent) { | |||
yield* _mapInitEventToState(event); | |||
} | |||
/// 下拉刷新 | |||
if (event is FavoritesGoodsListOnRefreshEvent) { | |||
yield* _mapOnRefreshEventToState(event); | |||
} | |||
/// 上拉更多 | |||
if (event is FavoritesGoodsListOnLoadEvent) { | |||
yield* _mapOnLoadEventToState(event); | |||
} | |||
/// 删除 | |||
if (event is FavoritesGoodsListDeleteEvent) { | |||
yield* _mapDeleteEventToState(event); | |||
} | |||
/// 搜索 | |||
if (event is FavoritesGoodsListSearchEvent) { | |||
yield* _mapSearchEventToState(event); | |||
} | |||
/// 单个商品选中 | |||
if(event is FavoritesGoodsListSignGoodsSelectEvent){ | |||
yield* _mapSelectSignEventToState(event); | |||
} | |||
/// 所有商品选中 | |||
if(event is FavoritesGoodsListGoodsSelectAllEvent){ | |||
yield* _mapSelectAllEventToState(event); | |||
} | |||
/// 取消选中所有商品 | |||
if(event is FavoritesGoodsListGoodsCancelAllEvent){ | |||
yield* _mapCancelAllEventToState(event); | |||
} | |||
/// 右滑删除单个商品 | |||
if(event is FavoritesGoodsListSlideDeleteEvent){ | |||
yield* _mapSlideDeleteEventToState(event); | |||
} | |||
// /// 切换样式 | |||
// if (event is FavoritesGoodsListChangeStyleEvent) { | |||
// yield* _mapChangeStyleEventToState(event); | |||
// } | |||
} | |||
/// 初始化数据 | |||
Stream<FavoritesGoodsListState> _mapInitEventToState(FavoritesGoodsListInitEvent event) async* { | |||
var result = await repository.fetchInit(); | |||
if (!EmptyUtil.isEmpty(result)) { | |||
yield FavoritesGoodsListLoadedState(dataModel: result); | |||
} else { | |||
yield FavoritesGoodsListInitErrorState(); | |||
} | |||
} | |||
/// 下拉刷新 | |||
Stream<FavoritesGoodsListState> _mapOnRefreshEventToState(FavoritesGoodsListOnRefreshEvent event) async* { | |||
var result = await repository.fetchRefresh(); | |||
if (!EmptyUtil.isEmpty(result)) { | |||
yield FavoritesGoodsListRefreshSuccessState(); | |||
yield FavoritesGoodsListLoadedState(dataModel: result); | |||
} else { | |||
yield FavoritesGoodsListRefreshErrorState(); | |||
yield FavoritesGoodsListErrorState(); | |||
} | |||
} | |||
/// 上拉更多 | |||
Stream<FavoritesGoodsListState> _mapOnLoadEventToState(FavoritesGoodsListOnLoadEvent event) async* { | |||
var result = await repository.fetchLoad(); | |||
if (!EmptyUtil.isEmpty(result)) { | |||
yield FavoritesGoodsListLoadSuccessState(); | |||
yield FavoritesGoodsListLoadedState(dataModel: result); | |||
} else { | |||
yield FavoritesGoodsListLoadErrorState(); | |||
yield FavoritesGoodsListErrorState(); | |||
} | |||
} | |||
/// 删除 | |||
Stream<FavoritesGoodsListState> _mapDeleteEventToState(FavoritesGoodsListDeleteEvent event) async* { | |||
int length = repository.getSelectLength(); | |||
if(length > 0) { | |||
var result = await repository.delete(); | |||
if (!EmptyUtil.isEmpty(result)) { | |||
yield FavoritesGoodsListLoadedState(dataModel: result); | |||
} else { | |||
yield FavoritesGoodsListErrorState(); | |||
} | |||
}else{ | |||
yield FavoritesGoodsListNotSelectState(); | |||
} | |||
} | |||
/// 搜索 | |||
Stream<FavoritesGoodsListState> _mapSearchEventToState(FavoritesGoodsListSearchEvent event) async* { | |||
var result = await repository.search(event.keyword); | |||
if (!EmptyUtil.isEmpty(result)) { | |||
yield FavoritesGoodsListLoadedState(dataModel: result); | |||
} else { | |||
yield FavoritesGoodsListInitErrorState(); | |||
} | |||
} | |||
/// 所有商品选中 | |||
Stream<FavoritesGoodsListState> _mapSelectAllEventToState(FavoritesGoodsListGoodsSelectAllEvent event) async*{ | |||
var result = await repository.selectAllData(); | |||
if (!EmptyUtil.isEmpty(result)) { | |||
yield FavoritesGoodsListLoadedState(dataModel: result); | |||
} else { | |||
yield FavoritesGoodsListErrorState(); | |||
} | |||
} | |||
/// 商品的全部取消 | |||
Stream<FavoritesGoodsListState> _mapCancelAllEventToState(FavoritesGoodsListGoodsCancelAllEvent event) async*{ | |||
var result = await repository.cancelSelectAllData(); | |||
if (!EmptyUtil.isEmpty(result)) { | |||
yield FavoritesGoodsListLoadedState(dataModel: result); | |||
} else { | |||
yield FavoritesGoodsListErrorState(); | |||
} | |||
} | |||
/// 单个商品选中 | |||
Stream<FavoritesGoodsListState> _mapSelectSignEventToState(FavoritesGoodsListSignGoodsSelectEvent event) async*{ | |||
var result = await repository.signSelectData(event.index); | |||
if (!EmptyUtil.isEmpty(result)) { | |||
yield FavoritesGoodsListLoadedState(dataModel: result); | |||
} else { | |||
yield FavoritesGoodsListErrorState(); | |||
} | |||
} | |||
/// 右滑动删除商品 | |||
Stream<FavoritesGoodsListState> _mapSlideDeleteEventToState(FavoritesGoodsListSlideDeleteEvent event) async*{ | |||
var result = await repository.slideDeleteData(event.index); | |||
if (!EmptyUtil.isEmpty(result)) { | |||
yield FavoritesGoodsListLoadedState(dataModel: result); | |||
} else { | |||
yield FavoritesGoodsListErrorState(); | |||
} | |||
} | |||
// /// 切换样式 | |||
// Stream<FavoritesGoodsListState> _mapChangeStyleEventToState(FavoritesGoodsListChangeStyleEvent event) async* { | |||
// var result = await repository.fetchInit(); | |||
// if (!EmptyUtil.isEmpty(result)) { | |||
// yield FavoritesGoodsListLoadedState(dataModel: result); | |||
// } else { | |||
// yield FavoritesGoodsListInitErrorState(); | |||
// } | |||
// } | |||
} |
@@ -0,0 +1,45 @@ | |||
part of 'favorites_goods_list_bloc.dart'; | |||
@immutable | |||
abstract class FavoritesGoodsListEvent {} | |||
/// 初始化数据 | |||
class FavoritesGoodsListInitEvent extends FavoritesGoodsListEvent {} | |||
/// 下拉刷新 | |||
class FavoritesGoodsListOnRefreshEvent extends FavoritesGoodsListEvent {} | |||
/// 上拉更多 | |||
class FavoritesGoodsListOnLoadEvent extends FavoritesGoodsListEvent {} | |||
/// 关键字搜索 | |||
class FavoritesGoodsListSearchEvent extends FavoritesGoodsListEvent { | |||
final String keyword; | |||
FavoritesGoodsListSearchEvent(this.keyword); | |||
} | |||
/// 右滑动删除 | |||
class FavoritesGoodsListSlideDeleteEvent extends FavoritesGoodsListEvent{ | |||
final int index; | |||
FavoritesGoodsListSlideDeleteEvent(this.index); | |||
} | |||
/// 删除 | |||
class FavoritesGoodsListDeleteEvent extends FavoritesGoodsListEvent {} | |||
/// 切换样式 | |||
class FavoritesGoodsListChangeStyleEvent extends FavoritesGoodsListEvent{} | |||
/// 商品的当个选中 | |||
class FavoritesGoodsListSignGoodsSelectEvent extends FavoritesGoodsListEvent{ | |||
// final FavoritesGoodsListItemModel model; | |||
final int index; | |||
FavoritesGoodsListSignGoodsSelectEvent(this.index); | |||
} | |||
/// 商品的全选 | |||
class FavoritesGoodsListGoodsSelectAllEvent extends FavoritesGoodsListEvent{} | |||
/// 商品的全部取消 | |||
class FavoritesGoodsListGoodsCancelAllEvent extends FavoritesGoodsListEvent{} |
@@ -0,0 +1,177 @@ | |||
import 'package:flutter/cupertino.dart'; | |||
import 'package:zhiying_base_widget/widgets/favorites/goods_list/model/favorites_goods_list_model.dart'; | |||
import 'package:zhiying_base_widget/widgets/home/home_goods/models/home_goods_model.dart'; | |||
import 'package:zhiying_comm/zhiying_comm.dart'; | |||
class FavoritesGoodsListRepository { | |||
String type; | |||
final int _MAX = 5; | |||
int _currentPage = 1; | |||
bool _hasMoreData = true; | |||
FavoritesGoodsListDataModel _oldData = new FavoritesGoodsListDataModel(); | |||
Map<int, int> _selectIndex = {}; | |||
FavoritesGoodsListRepository({this.type = 'all'}); | |||
String keyword; | |||
/// 返回选中的商品长度 | |||
int getSelectLength() { | |||
return _selectIndex.length; | |||
} | |||
/// 右滑动删除当个商品 | |||
Future<FavoritesGoodsListDataModel> slideDeleteData(int index) async{ | |||
_selectIndex.clear(); | |||
_oldData.lists.forEach((element) { | |||
element.isSelect = false; | |||
}); | |||
_oldData.isAllSelect = false; | |||
_selectIndex[index] = index; | |||
return delete(); | |||
} | |||
/// 选中所有 | |||
Future<FavoritesGoodsListDataModel> selectAllData() async { | |||
try { | |||
_selectIndex.clear(); | |||
int index = 0; | |||
_oldData.lists.forEach((element) { | |||
element.isSelect = true; | |||
_selectIndex[index] = index; | |||
++index; | |||
}); | |||
_oldData.isAllSelect = true; | |||
return _oldData; | |||
}catch(e, s){ | |||
Logger.error(e,s); | |||
} | |||
return null; | |||
} | |||
/// 单个选中状态 | |||
Future<FavoritesGoodsListDataModel> signSelectData(final int selectIndex) async { | |||
_oldData.lists[selectIndex].isSelect = !_oldData.lists[selectIndex].isSelect; | |||
if (_oldData.lists[selectIndex].isSelect) { | |||
// 新增 | |||
_selectIndex[selectIndex] = selectIndex; | |||
} else { | |||
// 移除 | |||
_selectIndex.remove(selectIndex); | |||
} | |||
_oldData.isAllSelect = false; | |||
if (_selectIndex.length == _oldData.lists.length) { | |||
_oldData.isAllSelect = true; | |||
} | |||
return _oldData; | |||
} | |||
/// 取消选中所有 or 重置选中状态 | |||
Future<FavoritesGoodsListDataModel> cancelSelectAllData() async { | |||
_selectIndex.clear(); | |||
_oldData.lists.forEach((element) { | |||
element.isSelect = false; | |||
}); | |||
_oldData.isAllSelect = false; | |||
return _oldData; | |||
} | |||
/// 关键字搜索 | |||
Future<FavoritesGoodsListDataModel> search(String keyword) async { | |||
try { | |||
_selectIndex.clear(); | |||
_oldData.lists.clear(); | |||
_currentPage = 1; | |||
_hasMoreData = true; | |||
this.keyword = keyword; | |||
return _baseRequest(); | |||
} catch (e, s) { | |||
Logger.error(e, s); | |||
} | |||
return null; | |||
} | |||
/// 删除数据 | |||
Future<FavoritesGoodsListDataModel> delete() async { | |||
try { | |||
// Logger.log('select Index length = ${_selectIndex.length}'); | |||
if (_selectIndex.length > 0) { | |||
List<String> gids = []; | |||
_selectIndex.forEach((key, value) { | |||
gids.add(_oldData.lists[value].goodId); | |||
}); | |||
var result = await NetUtil.post('/api/v1/user/myfav/delete', params: {'gids': gids}, method: NetMethod.POST); | |||
if (NetUtil.isSuccess(result)) { | |||
List<FavoritesGoodsListItemModel> tempList = []; | |||
// TODO 这里有问题:移除删除 | |||
for (int i = 0; i < _oldData.lists.length; i++) { | |||
if (!_selectIndex.containsKey(i)) { | |||
tempList.add(_oldData.lists[i]); | |||
} | |||
} | |||
_oldData.lists.clear(); | |||
_selectIndex.clear(); | |||
_oldData.isAllSelect = false; | |||
_oldData.lists = tempList; | |||
return _oldData; | |||
} | |||
} | |||
} catch (e, s) { | |||
Logger.error(e, s); | |||
} | |||
return null; | |||
} | |||
/// 初始化请求 | |||
Future<FavoritesGoodsListDataModel> fetchInit() async { | |||
_currentPage = 1; | |||
_hasMoreData = true; | |||
_oldData?.lists?.clear(); | |||
_selectIndex.clear(); | |||
_oldData.isAllSelect = false; | |||
return _baseRequest(); | |||
} | |||
/// 下拉刷新 | |||
Future<FavoritesGoodsListDataModel> fetchRefresh() async { | |||
return fetchInit(); | |||
} | |||
/// 上拉更多 | |||
Future<FavoritesGoodsListDataModel> fetchLoad() async { | |||
if (_hasMoreData) { | |||
return _baseRequest(); | |||
} | |||
return null; | |||
} | |||
/// 基础请求 | |||
Future<FavoritesGoodsListDataModel> _baseRequest() async { | |||
try { | |||
var result; | |||
if(EmptyUtil.isEmpty(keyword)) { | |||
result = await NetUtil.post('/api/v1/user/myfav/$type?page=${_currentPage.toString()}', params: {}, method: NetMethod.GET); | |||
}else{ | |||
result = await NetUtil.post('/api/v1/user/myfav/s', params: {'keyword': keyword}, method: NetMethod.POST); | |||
} | |||
if (NetUtil.isSuccess(result) && !EmptyUtil.isEmpty(result[GlobalConfig.HTTP_RESPONSE_KEY_DATA])) { | |||
List data = result[GlobalConfig.HTTP_RESPONSE_KEY_DATA]; | |||
data.forEach((element) { | |||
_oldData.lists.add(FavoritesGoodsListItemModel.fromJson(element)); | |||
}); | |||
++_currentPage; | |||
_hasMoreData = true; | |||
// _hasMoreData = data.length >= _MAX ? true : false; | |||
return _oldData; | |||
} | |||
_hasMoreData = false; | |||
} catch (e, s) { | |||
Logger.error(e, s); | |||
} | |||
return null; | |||
} | |||
} |
@@ -0,0 +1,35 @@ | |||
part of 'favorites_goods_list_bloc.dart'; | |||
@immutable | |||
abstract class FavoritesGoodsListState {} | |||
/// 初始化状态(骨架图) | |||
class FavoritesGoodsListInitial extends FavoritesGoodsListState {} | |||
/// 初始化失败状态(空数据) | |||
class FavoritesGoodsListInitErrorState extends FavoritesGoodsListState {} | |||
/// 下拉刷新失败状态 | |||
class FavoritesGoodsListRefreshErrorState extends FavoritesGoodsListState {} | |||
/// 下拉刷新成功状态 | |||
class FavoritesGoodsListRefreshSuccessState extends FavoritesGoodsListState {} | |||
/// 上拉更多失败状态 | |||
class FavoritesGoodsListLoadErrorState extends FavoritesGoodsListState {} | |||
/// 上拉更多成功状态 | |||
class FavoritesGoodsListLoadSuccessState extends FavoritesGoodsListState {} | |||
/// 数据加载成功 | |||
class FavoritesGoodsListLoadedState extends FavoritesGoodsListState { | |||
// List<FavoritesGoodsListItemModel> dataModel; | |||
FavoritesGoodsListDataModel dataModel; | |||
FavoritesGoodsListLoadedState({@required this.dataModel}); | |||
} | |||
/// 没选中 | |||
class FavoritesGoodsListNotSelectState extends FavoritesGoodsListState{} | |||
/// 未知错误 | |||
class FavoritesGoodsListErrorState extends FavoritesGoodsListState {} |
@@ -0,0 +1,376 @@ | |||
import 'package:flutter/cupertino.dart'; | |||
import 'package:flutter/material.dart'; | |||
import 'package:flutter/widgets.dart'; | |||
import 'package:flutter_slidable/flutter_slidable.dart'; | |||
import 'package:pull_to_refresh/pull_to_refresh.dart'; | |||
import 'package:zhiying_base_widget/dialog/tip_dialog/tip_dialog.dart'; | |||
import 'package:zhiying_base_widget/pages/favorites_page/model/favorites_style_model.dart'; | |||
import 'package:zhiying_base_widget/pages/favorites_page/notifier/favorites_page_notifier.dart'; | |||
import 'package:zhiying_base_widget/widgets/favorites/dialog/favorites_dialog_widget.dart'; | |||
import 'package:zhiying_base_widget/widgets/favorites/goods_list/bloc/favorites_goods_list_bloc.dart'; | |||
import 'package:zhiying_base_widget/widgets/favorites/goods_list/bloc/favorites_goods_list_repository.dart'; | |||
import 'package:zhiying_base_widget/widgets/home/home_goods/home_goods_item_single.dart'; | |||
import 'package:zhiying_base_widget/widgets/home/home_goods/models/home_goods_style_model.dart'; | |||
import 'package:zhiying_base_widget/widgets/home/home_goods/skeleton/home_goods_sk.dart'; | |||
import 'package:zhiying_comm/zhiying_comm.dart'; | |||
import 'package:flutter_bloc/flutter_bloc.dart'; | |||
import 'package:provider/provider.dart'; | |||
import 'package:fluttertoast/fluttertoast.dart'; | |||
import 'model/favorites_goods_list_model.dart'; | |||
class FavoritesGoodsListWidget extends StatelessWidget { | |||
FavoritesStyleModel model; | |||
String type; | |||
int currentIndex; | |||
FavoritesGoodsListWidget({@required this.model, @required this.type, this.currentIndex = 0}); | |||
@override | |||
Widget build(BuildContext context) { | |||
return BlocProvider<FavoritesGoodsListBloc>( | |||
create: (_) => FavoritesGoodsListBloc(FavoritesGoodsListRepository(type: type)), | |||
child: _FavoritesGoodsListWidgetContainer(model, currentIndex), | |||
); | |||
} | |||
} | |||
class _FavoritesGoodsListWidgetContainer extends StatefulWidget { | |||
FavoritesStyleModel styleModel; | |||
int currentIndex; | |||
_FavoritesGoodsListWidgetContainer(this.styleModel, this.currentIndex); | |||
@override | |||
__FavoritesGoodsListWidgetContainerState createState() => __FavoritesGoodsListWidgetContainerState(); | |||
} | |||
class __FavoritesGoodsListWidgetContainerState extends State<_FavoritesGoodsListWidgetContainer> with AutomaticKeepAliveClientMixin { | |||
RefreshController _refreshController; | |||
SlidableController _slidableController; | |||
// 是否编辑中 | |||
bool isEditing = false; | |||
int lastChangeVal = -1; | |||
/// 下拉刷新 | |||
void _onRefresh() async { | |||
BlocProvider.of<FavoritesGoodsListBloc>(context).add(FavoritesGoodsListOnRefreshEvent()); | |||
} | |||
/// 上拉更多 | |||
void _onLoad() async { | |||
BlocProvider.of<FavoritesGoodsListBloc>(context).add(FavoritesGoodsListOnLoadEvent()); | |||
} | |||
/// 右边划删除 | |||
void _onSlideDelete(ConfirmDialog styleModel,int index) async{ | |||
var result = await showDialog(context: context, child: FavoritesDialogWidget(styleModel: styleModel,)); | |||
if(result == 1){ | |||
BlocProvider.of<FavoritesGoodsListBloc>(context).add(FavoritesGoodsListSlideDeleteEvent(index)); | |||
// Slidable.of(context)?.renderingMode == SlidableRenderingMode.none ? Slidable.of(context)?.open() : Slidable.of(context)?.close(); | |||
// Slidable.of(context)?.close(); | |||
} | |||
} | |||
/// 分享商品 | |||
void _onSlideShare() async{ | |||
// TODO 分享商品还没弄 | |||
} | |||
/// 商品点击选中 | |||
void _onClickGoods(int index){ | |||
BlocProvider.of<FavoritesGoodsListBloc>(context).add(FavoritesGoodsListSignGoodsSelectEvent(index)); | |||
} | |||
/// 全选 | |||
void _onClickAllSelecct(FavoritesGoodsListDataModel dataModel) { | |||
if(!dataModel.isAllSelect) { | |||
BlocProvider.of<FavoritesGoodsListBloc>(context).add(FavoritesGoodsListGoodsSelectAllEvent()); | |||
}else{ | |||
BlocProvider.of<FavoritesGoodsListBloc>(context).add(FavoritesGoodsListGoodsCancelAllEvent()); | |||
} | |||
} | |||
/// 点击删除 | |||
void _onClickDelete(ConfirmDialog styleModel) async { | |||
// | |||
var result = await showDialog(context: context, child: FavoritesDialogWidget(styleModel: styleModel,)); | |||
if(result == 1){ | |||
BlocProvider.of<FavoritesGoodsListBloc>(context).add(FavoritesGoodsListDeleteEvent()); | |||
} | |||
} | |||
@override | |||
bool get wantKeepAlive => true; | |||
@override | |||
void initState() { | |||
_refreshController = RefreshController(); | |||
_slidableController = SlidableController(); | |||
BlocProvider.of<FavoritesGoodsListBloc>(context).add(FavoritesGoodsListInitEvent()); | |||
super.initState(); | |||
} | |||
@override | |||
void didChangeDependencies() { | |||
super.didChangeDependencies(); | |||
FavoritesPageNotifier favoritesPageNotifier = Provider.of<FavoritesPageNotifier>(context); | |||
if (null != favoritesPageNotifier) { | |||
isEditing = favoritesPageNotifier.isEditing; | |||
if(favoritesPageNotifier.editingTypeTag) { | |||
// BlocProvider.of<FavoritesGoodsListBloc>(context).add(FavoritesGoodsListGoodsCancelAllEvent()); | |||
}else{ | |||
// if(favoritesPageNotifier.selectIndex == widget.currentIndex) { | |||
BlocProvider.of<FavoritesGoodsListBloc>(context).add(FavoritesGoodsListSearchEvent(favoritesPageNotifier?.keyword)); | |||
// } | |||
} | |||
} | |||
} | |||
@override | |||
void dispose() { | |||
_refreshController?.dispose(); | |||
super.dispose(); | |||
} | |||
@override | |||
Widget build(BuildContext context) { | |||
return Listener( | |||
onPointerDown: (down)=> RouterUtil.hideKeyboard(context), | |||
child: Container( | |||
color: HexColor.fromHex('#F9F9F9'), | |||
child: BlocConsumer<FavoritesGoodsListBloc, FavoritesGoodsListState>( | |||
listener: (context, state) {}, | |||
buildWhen: (prev, current) { | |||
if (current is FavoritesGoodsListRefreshSuccessState) { | |||
_refreshController?.refreshCompleted(resetFooterState: true); | |||
return false; | |||
} | |||
if (current is FavoritesGoodsListRefreshErrorState) { | |||
_refreshController?.refreshFailed(); | |||
return false; | |||
} | |||
if (current is FavoritesGoodsListLoadSuccessState) { | |||
_refreshController?.loadComplete(); | |||
return false; | |||
} | |||
if (current is FavoritesGoodsListLoadErrorState) { | |||
_refreshController?.loadNoData(); | |||
return false; | |||
} | |||
if (current is FavoritesGoodsListErrorState) { | |||
return false; | |||
} | |||
if(current is FavoritesGoodsListNotSelectState){ | |||
Fluttertoast.showToast(msg: '请选择需要删除的商品~'); | |||
return false; | |||
} | |||
return true; | |||
}, | |||
builder: (context, state) { | |||
/// 初始化失败,空数据 | |||
if (state is FavoritesGoodsListInitErrorState) { | |||
return _buildEmptyWidget(widget?.styleModel); | |||
} | |||
/// 数据加载成功 | |||
if (state is FavoritesGoodsListLoadedState) { | |||
// Logger.log('__FavoritesGoodsListWidgetContainerState ==== 刷新 size = ${state?.dataModel?.lists?.length}'); | |||
return _buildGoodsListWidget(widget?.styleModel, state?.dataModel); | |||
} | |||
/// 骨架图 | |||
return _buildSkeletonWidget(widget?.styleModel); | |||
}, | |||
), | |||
), | |||
); | |||
} | |||
/// 有数据返回 | |||
Widget _buildGoodsListWidget(FavoritesStyleModel styleModel, FavoritesGoodsListDataModel dataModel) { | |||
/// 如果数据删除了,则返回空视图 | |||
int length = dataModel?.lists?.length ?? 0; | |||
if(length == 0) return _buildEmptyWidget(styleModel); | |||
return Stack( | |||
children: <Widget>[ | |||
/// 数据 | |||
SmartRefresher( | |||
controller: _refreshController, | |||
onRefresh: _onRefresh, | |||
onLoading: _onLoad, | |||
enablePullUp: true, | |||
enablePullDown: true, | |||
child: ListView.builder( | |||
padding: EdgeInsets.only(top: 7.5, left: 12.5, right: isEditing ? 0 : 12.5), | |||
itemCount: dataModel.lists.length, | |||
itemBuilder: (context, index) { | |||
FavoritesGoodsListItemModel item = dataModel.lists[index]; | |||
return Row( | |||
children: <Widget>[ | |||
Visibility( | |||
visible: isEditing , | |||
child: GestureDetector( | |||
onTap: ()=> _onClickGoods(index), | |||
behavior: HitTestBehavior.opaque, | |||
child: Container( | |||
height: 20, | |||
width: 20, | |||
margin: const EdgeInsets.only(right: 8), | |||
child: CachedNetworkImage( | |||
imageUrl: item.isSelect ? styleModel?.editLeftConfirmIcon : styleModel?.editLeftNoConfirmIcon, | |||
), | |||
), | |||
), | |||
), | |||
Expanded( | |||
child: Slidable( | |||
key: Key(index.toString()), | |||
controller: _slidableController, | |||
enabled: !isEditing, | |||
actionPane: SlidableDrawerActionPane(), | |||
actionExtentRatio: 0.25, | |||
closeOnScroll: false, | |||
secondaryActions: <Widget>[ | |||
/// 分享 | |||
Padding( | |||
padding: const EdgeInsets.only(bottom: 8), | |||
child: IconSlideAction( | |||
caption: '分享', | |||
color: Colors.deepOrange, | |||
icon: Icons.share, | |||
onTap: () => _onSlideShare(), | |||
closeOnTap: true, | |||
), | |||
), | |||
/// 删除 | |||
Padding( | |||
padding: const EdgeInsets.only(bottom: 8), | |||
child: IconSlideAction( | |||
caption: '删除', | |||
color: Colors.red, | |||
closeOnTap: true, | |||
icon: Icons.delete, | |||
onTap: () => _onSlideDelete(styleModel?.confirmDialog ,index), | |||
), | |||
), | |||
], | |||
child: HomeGoodsItemSingle( | |||
item, | |||
HomeGoodsStyleModel()..listStyle = styleModel?.listStyle, | |||
marginBottom: 8, | |||
marginLeft: 0, | |||
marginRight: 0, | |||
marginTop: 0 | |||
), | |||
), | |||
) | |||
], | |||
); | |||
}), | |||
), | |||
/// 编辑 | |||
_buildEditrWidget(widget?.styleModel, dataModel), | |||
], | |||
); | |||
} | |||
/// 编辑的底部Widget | |||
Widget _buildEditrWidget(FavoritesStyleModel styleModel, FavoritesGoodsListDataModel dataModel) { | |||
return Align( | |||
alignment: Alignment.bottomCenter, | |||
child: Visibility( | |||
visible: isEditing , | |||
child: Container( | |||
padding: const EdgeInsets.only(left: 12.5, right: 12.5, top: 15.5, bottom: 15.5), | |||
width: double.infinity, | |||
decoration: BoxDecoration( | |||
color: HexColor.fromHex(styleModel?.bottom?.bgColor ?? '#FFFFFF'), borderRadius: BorderRadius.only(topRight: Radius.circular(10), topLeft: Radius.circular(10))), | |||
child: Row( | |||
mainAxisAlignment: MainAxisAlignment.spaceBetween, | |||
children: <Widget>[ | |||
GestureDetector( | |||
onTap: () => _onClickAllSelecct(dataModel), | |||
behavior: HitTestBehavior.opaque, | |||
child: Row( | |||
children: <Widget>[ | |||
Visibility( | |||
visible: dataModel?.isAllSelect ?? false, | |||
replacement: Container( | |||
width: 20, | |||
height: 20, | |||
decoration: BoxDecoration(borderRadius: BorderRadius.circular(20), border: Border.all(color: HexColor.fromHex('#DCDCDC'), width: 0.5)), | |||
), | |||
child: Container( | |||
height: 20, | |||
width: 20, | |||
child: CachedNetworkImage(imageUrl: styleModel?.editLeftConfirmIcon ?? '',), | |||
), | |||
), | |||
const SizedBox(width: 8), | |||
Text( | |||
styleModel?.bottom?.leftText ?? '全选', | |||
style: TextStyle( | |||
fontSize: 15, | |||
color: HexColor.fromHex(styleModel?.bottom?.leftColor ?? '#333333'), | |||
fontWeight: FontWeight.bold, | |||
), | |||
), | |||
], | |||
), | |||
), | |||
GestureDetector( | |||
onTap: () => _onClickDelete(styleModel?.confirmDialog), | |||
behavior: HitTestBehavior.opaque, | |||
child: Text( | |||
styleModel?.bottom?.rightText ?? '删除', | |||
style: TextStyle( | |||
fontSize: 15, | |||
color: HexColor.fromHex(styleModel?.bottom?.rightColor ?? '#FF4242'), | |||
fontWeight: FontWeight.bold, | |||
), | |||
), | |||
), | |||
], | |||
), | |||
), | |||
), | |||
); | |||
} | |||
/// 空数据 | |||
Widget _buildEmptyWidget(FavoritesStyleModel styleModel) { | |||
return SmartRefresher( | |||
controller: _refreshController, | |||
onRefresh: _onRefresh, | |||
enablePullDown: true, | |||
enablePullUp: false, | |||
child: Column( | |||
children: <Widget>[ | |||
const SizedBox(height: 80), | |||
CachedNetworkImage(imageUrl: styleModel?.tabItemNotFoundImg ?? '', width: 188), | |||
const SizedBox(height: 22), | |||
Text( | |||
'暂时没有商品噢\n快去浏览收藏吧', | |||
style: TextStyle(fontSize: 15, color: HexColor.fromHex('#999999')), | |||
) | |||
], | |||
), | |||
); | |||
} | |||
/// 骨架图 | |||
Widget _buildSkeletonWidget(FavoritesStyleModel styleModel) { | |||
return HomeGoodsSkeleton(); | |||
} | |||
} |
@@ -0,0 +1,37 @@ | |||
import 'package:zhiying_base_widget/widgets/home/home_goods/models/home_goods_model.dart'; | |||
// ignore: must_be_immutable | |||
class FavoritesGoodsListDataModel { | |||
// 是否全选 | |||
bool isAllSelect = false; | |||
List<FavoritesGoodsListItemModel> lists = []; | |||
// FavoritesGoodsListDataModel({this.isEditing, this.isAllSelect, this.lists }); | |||
FavoritesGoodsListDataModel(); | |||
FavoritesGoodsListDataModel.fromJson(Map<String, dynamic> json) { | |||
isAllSelect = json['isAllSelect'] ?? false; | |||
if(json['data'] != null){ | |||
json['data'].forEach((v){ | |||
lists.add(new FavoritesGoodsListItemModel.fromJson(v)); | |||
}); | |||
} | |||
} | |||
} | |||
class FavoritesGoodsListItemModel extends HomeGoodsModel { | |||
bool isSelect; | |||
FavoritesGoodsListItemModel.fromJson(Map<String, dynamic> json) { | |||
super.fromJson(json); | |||
isSelect = json['isSelect'] ?? false; | |||
} | |||
Map<String, dynamic> toJson() { | |||
final Map<String, dynamic> data = super.toJson(); | |||
data['isSelect'] = this.isSelect; | |||
return data; | |||
} | |||
} |
@@ -84,14 +84,19 @@ class _GoodsDetailsImgWidgetContainerState extends State<GoodsDetailsImgWidgetCo | |||
/// 图片列表 | |||
Widget _getImgListWidget(GoodsDetailsImgModel model){ | |||
return Column( | |||
children: model.image_detail_list.map((item){ | |||
return CachedNetworkImage( | |||
imageUrl: item ?? '', | |||
fit: BoxFit.fitWidth, | |||
); | |||
}).toList(), | |||
); | |||
int length = model?.image_detail_list?.length ?? 0; | |||
if(length > 0) { | |||
return Column( | |||
children: model.image_detail_list.map((item) { | |||
return CachedNetworkImage( | |||
imageUrl: item ?? '', | |||
fit: BoxFit.fitWidth, | |||
); | |||
}).toList(), | |||
); | |||
}else{ | |||
return Container(); | |||
} | |||
} | |||
/// 标题Widget | |||
@@ -27,11 +27,22 @@ class GoodsDetailsFooterBloc extends Bloc<GoodsDetailsFooterEvent, GoodsDetailsF | |||
if (event is GoodsDetailsFooterInitEvent) { | |||
yield* _mapInitEventToState(event); | |||
} | |||
/// 收藏 | |||
if(event is GoodsDetailsFooterCollectEvent){ | |||
yield* _mapCollectEventToState(event); | |||
} | |||
/// 取消收藏 | |||
if(event is GoodsDetailsFooterDeleteCollectEvent){ | |||
yield* _mapDeleteCollectEventToState(event); | |||
} | |||
} | |||
/// 初始化 | |||
Stream<GoodsDetailsFooterState> _mapInitEventToState(GoodsDetailsFooterInitEvent event) async* { | |||
var result = await repository.fetchParentData(event.model); | |||
var result = await repository.fetchParentData(event?.model); | |||
if (!EmptyUtil.isEmpty(result)) { | |||
print('result = ${result.toString()}'); | |||
yield GoodsDetailsFooterLoadedState(model: result); | |||
@@ -42,10 +53,20 @@ class GoodsDetailsFooterBloc extends Bloc<GoodsDetailsFooterEvent, GoodsDetailsF | |||
/// 点击收藏 | |||
Stream<GoodsDetailsFooterState> _mapCollectEventToState(GoodsDetailsFooterCollectEvent event) async* { | |||
var result = await repository.fetchCollect(); | |||
var result = await repository.fetchCollect(event?.model); | |||
if (!EmptyUtil.isEmpty(result)) | |||
yield GoodsDetailsFooterLoadedState(model: result); | |||
else | |||
yield GoodsDetailsFooterErrorState(); | |||
} | |||
/// 取消收藏 | |||
Stream<GoodsDetailsFooterState> _mapDeleteCollectEventToState(GoodsDetailsFooterDeleteCollectEvent event ) async*{ | |||
var result = await repository.fetchDeleteCollect(event?.model); | |||
if(!EmptyUtil.isEmpty(result)) | |||
yield GoodsDetailsFooterLoadedState(model: result); | |||
else | |||
yield GoodsDetailsFooterErrorState(); | |||
} | |||
} |
@@ -19,5 +19,20 @@ class GoodsDetailsFooterInitEvent extends GoodsDetailsFooterEvent { | |||
/// 点击收藏 | |||
class GoodsDetailsFooterCollectEvent extends GoodsDetailsFooterEvent { | |||
final Map<String, dynamic> model; | |||
GoodsDetailsFooterCollectEvent({@required this.model}); | |||
@override | |||
List<Object> get props => [this.model]; | |||
} | |||
/// 取消收藏 | |||
class GoodsDetailsFooterDeleteCollectEvent extends GoodsDetailsFooterEvent { | |||
final Map<String, dynamic> model; | |||
GoodsDetailsFooterDeleteCollectEvent({@required this.model}); | |||
@override | |||
List<Object> get props => [this.model]; | |||
} |
@@ -4,18 +4,50 @@ import 'package:zhiying_base_widget/widgets/goods_details/footer/model/goods_det | |||
import 'package:zhiying_comm/zhiying_comm.dart'; | |||
class GoodsDetailsFooterRepository { | |||
GoodsDetailsFooterModel _oldmodel; | |||
/// 初始化数据 | |||
Future<GoodsDetailsFooterModel> fetchParentData(final Map<String, dynamic> model) async { | |||
try { | |||
return GoodsDetailsFooterModel.fromJson(jsonDecode(model['data'])); | |||
} catch (e) { | |||
Logger.log('GoodsDetailsFooterRepository e = $e'); | |||
GoodsDetailsFooterModel data = GoodsDetailsFooterModel.fromJson(jsonDecode(model['data'])); | |||
_oldmodel = data; | |||
return data; | |||
} catch (e, s) { | |||
Logger.error(e, s); | |||
} | |||
return null; | |||
} | |||
/// 点击收藏 | |||
Future<GoodsDetailsFooterModel> fetchCollect() async{ | |||
Future<GoodsDetailsFooterModel> fetchCollect(final Map<String, dynamic> model) async { | |||
try { | |||
if (!EmptyUtil.isEmpty(model)) { | |||
var result = await NetUtil.post('/api/v1/user/myfav', params: model, method: NetMethod.POST); | |||
if(NetUtil.isSuccess(result)){ | |||
_oldmodel.isFav = '1'; | |||
return _oldmodel; | |||
} | |||
} | |||
} catch (e, s) { | |||
Logger.error(e, s); | |||
} | |||
return null; | |||
} | |||
/// 取消收藏 | |||
Future<GoodsDetailsFooterModel> fetchDeleteCollect(final Map<String, dynamic> model) async{ | |||
try{ | |||
if(!EmptyUtil.isEmpty(model)){ | |||
var result = await NetUtil.post('/api/v1/user/myfav/delete', params: {'gids':[model['good_id']]}, method: NetMethod.POST); | |||
if(NetUtil.isSuccess(result)){ | |||
_oldmodel.isFav = '0'; | |||
return _oldmodel; | |||
} | |||
} | |||
}catch(e, s){ | |||
Logger.error(e,s); | |||
} | |||
return null; | |||
} | |||
@@ -1,15 +1,15 @@ | |||
part of 'goods_details_footer_bloc.dart'; | |||
abstract class GoodsDetailsFooterState extends Equatable { | |||
abstract class GoodsDetailsFooterState { | |||
const GoodsDetailsFooterState(); | |||
@override | |||
List<Object> get props => []; | |||
// @override | |||
// List<Object> get props => []; | |||
} | |||
class GoodsDetailsFooterInitial extends GoodsDetailsFooterState { | |||
@override | |||
List<Object> get props => []; | |||
// @override | |||
// List<Object> get props => []; | |||
} | |||
/// 数据加载完毕 | |||
@@ -18,8 +18,8 @@ class GoodsDetailsFooterLoadedState extends GoodsDetailsFooterState { | |||
GoodsDetailsFooterLoadedState({@required this.model}); | |||
@override | |||
List<Object> get props => [this.model]; | |||
// @override | |||
// List<Object> get props => [this.model]; | |||
} | |||
/// 数据加载出错 | |||
@@ -75,7 +75,14 @@ class _GooddsDetailsFooterContainerState | |||
} | |||
/// 收藏 | |||
void _collectOnClick() {} | |||
void _collectOnClick(GoodsDetailsFooterModel model) { | |||
bool isCollect = model.isFav == '0'; | |||
if(isCollect){ // 收藏 | |||
BlocProvider.of<GoodsDetailsFooterBloc>(context).add(GoodsDetailsFooterCollectEvent(model: model?.favArgs?.toJson())); | |||
}else{ // 取消收藏 | |||
BlocProvider.of<GoodsDetailsFooterBloc>(context).add(GoodsDetailsFooterDeleteCollectEvent(model: model?.favArgs?.toJson())); | |||
} | |||
} | |||
/// 分享 | |||
void _shareOnClick(GoodsDetailsFooterModel model) async { | |||
@@ -221,13 +228,13 @@ class _GooddsDetailsFooterContainerState | |||
)), | |||
GestureDetector( | |||
behavior: HitTestBehavior.opaque, | |||
onTap: () => _collectOnClick(), | |||
onTap: () => _collectOnClick(model), | |||
child: Padding( | |||
padding: const EdgeInsets.only(right: 0), | |||
child: _getCustomWidget( | |||
model?.collect ?? '收藏', | |||
model?.collect_color ?? '999999', | |||
model?.collect_icon ?? ''))) | |||
model?.isFav == '0' ? model?.collect_icon ?? '' : model?.collected_icon ?? ''))) | |||
], | |||
); | |||
} | |||
@@ -2,6 +2,7 @@ class GoodsDetailsFooterModel { | |||
String collect; | |||
String collect_color; | |||
String collect_icon; | |||
String collected_icon; | |||
String home; | |||
String home_color; | |||
String home_icon; | |||
@@ -18,28 +19,46 @@ class GoodsDetailsFooterModel { | |||
String share_value; | |||
String self_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.self_buy_value}); | |||
String isFav; | |||
String buyUrl; | |||
String shareUrl; | |||
FavArgs favArgs; | |||
ShareUrlArgs shareUrlArgs; | |||
GoodsDetailsFooterModel({ | |||
this.buyUrl, | |||
this.favArgs, | |||
this.isFav, | |||
this.shareUrl, | |||
this.shareUrlArgs, | |||
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.self_buy_value, | |||
this.collected_icon, | |||
}); | |||
factory GoodsDetailsFooterModel.fromJson(Map<String, dynamic> json) { | |||
return GoodsDetailsFooterModel( | |||
isFav: json['is_fav'], | |||
buyUrl: json['buy_url'], | |||
shareUrl: json['share_url'], | |||
favArgs: json['fav_args'] != null ? new FavArgs.fromJson(json['fav_args']) : null, | |||
shareUrlArgs: json['share_url_args'] != null ? new ShareUrlArgs.fromJson(json['share_url_args']) : null, | |||
collect: json['collect'], | |||
collect_color: json['collect_color'], | |||
collect_icon: json['collect_icon'], | |||
@@ -58,6 +77,7 @@ class GoodsDetailsFooterModel { | |||
share_earn_val_color: json['share_earn_val_color'], | |||
share_value: json['share_value'], | |||
self_buy_value: json['self_buy_value'], | |||
collected_icon: json['collected_icon'], | |||
); | |||
} | |||
@@ -81,6 +101,120 @@ class GoodsDetailsFooterModel { | |||
data['share_earn_val_color'] = this.share_earn_val_color; | |||
data['share_value'] = this.share_value; | |||
data['self_buy_value'] = this.self_buy_value; | |||
data['collected_icon'] = this.collected_icon; | |||
data['is_fav'] = this.isFav; | |||
data['buy_url'] = this.buyUrl; | |||
data['share_url'] = this.shareUrl; | |||
if (this.favArgs != null) { | |||
data['fav_args'] = this.favArgs.toJson(); | |||
} | |||
if (this.shareUrlArgs != null) { | |||
data['share_url_args'] = this.shareUrlArgs.toJson(); | |||
} | |||
return data; | |||
} | |||
} | |||
class FavArgs { | |||
String provider; | |||
String providerName; | |||
String goodId; | |||
String goodImage; | |||
String goodTitle; | |||
String shopName; | |||
String coupon; | |||
String couponUrl; | |||
String commission; | |||
String marketPrice; | |||
String currentPrice; | |||
String inorderCount; | |||
Null detailData; | |||
FavArgs( | |||
{this.provider, | |||
this.providerName, | |||
this.goodId, | |||
this.goodImage, | |||
this.goodTitle, | |||
this.shopName, | |||
this.coupon, | |||
this.couponUrl, | |||
this.commission, | |||
this.marketPrice, | |||
this.currentPrice, | |||
this.inorderCount, | |||
this.detailData}); | |||
FavArgs.fromJson(Map<String, dynamic> json) { | |||
provider = json['provider']; | |||
providerName = json['provider_name']; | |||
goodId = json['good_id']; | |||
goodImage = json['good_image']; | |||
goodTitle = json['good_title']; | |||
shopName = json['shop_name']; | |||
coupon = json['coupon']; | |||
couponUrl = json['coupon_url']; | |||
commission = json['commission']; | |||
marketPrice = json['market_price']; | |||
currentPrice = json['current_price']; | |||
inorderCount = json['inorder_count']; | |||
detailData = json['detail_data']; | |||
} | |||
Map<String, dynamic> toJson() { | |||
final Map<String, dynamic> data = new Map<String, dynamic>(); | |||
data['provider'] = this.provider; | |||
data['provider_name'] = this.providerName; | |||
data['good_id'] = this.goodId; | |||
data['good_image'] = this.goodImage; | |||
data['good_title'] = this.goodTitle; | |||
data['shop_name'] = this.shopName; | |||
data['coupon'] = this.coupon; | |||
data['coupon_url'] = this.couponUrl; | |||
data['commission'] = this.commission; | |||
data['market_price'] = this.marketPrice; | |||
data['current_price'] = this.currentPrice; | |||
data['inorder_count'] = this.inorderCount; | |||
data['detail_data'] = this.detailData; | |||
return data; | |||
} | |||
} | |||
class ShareUrlArgs { | |||
String buyUrl; | |||
String coupon; | |||
String couponPrice; | |||
String marketPrice; | |||
String posterImage; | |||
String selfbuyCommission; | |||
String title; | |||
String type; | |||
ShareUrlArgs({this.buyUrl, this.coupon, this.couponPrice, this.marketPrice, this.posterImage, this.selfbuyCommission, this.title, this.type}); | |||
ShareUrlArgs.fromJson(Map<String, dynamic> json) { | |||
buyUrl = json['buy_url']; | |||
coupon = json['coupon']; | |||
couponPrice = json['coupon_price']; | |||
marketPrice = json['market_price']; | |||
posterImage = json['poster_image']; | |||
selfbuyCommission = json['selfbuy_commission']; | |||
title = json['title']; | |||
type = json['type']; | |||
} | |||
Map<String, dynamic> toJson() { | |||
final Map<String, dynamic> data = new Map<String, dynamic>(); | |||
data['buy_url'] = this.buyUrl; | |||
data['coupon'] = this.coupon; | |||
data['coupon_price'] = this.couponPrice; | |||
data['market_price'] = this.marketPrice; | |||
data['poster_image'] = this.posterImage; | |||
data['selfbuy_commission'] = this.selfbuyCommission; | |||
data['title'] = this.title; | |||
data['type'] = this.type; | |||
return data; | |||
} | |||
} |
@@ -14,8 +14,12 @@ class HomeGoodsItemSingle extends StatelessWidget { | |||
final HomeGoodsModel goods; | |||
final HomeGoodsStyleModel style; | |||
Map<String, dynamic> data; | |||
final double marginLeft; | |||
final double marginRight; | |||
final double marginTop; | |||
final double marginBottom; | |||
HomeGoodsItemSingle(this.goods, this.style, {Key key, this.data}) | |||
HomeGoodsItemSingle(this.goods, this.style, {Key key, this.data, this.marginBottom = 4, this.marginTop = 4, this.marginLeft= 12.5, this.marginRight = 12.5}) | |||
: super(key: key) { | |||
if (this.data != null && this.data.containsKey('data')) { | |||
String data = this.data['data']; | |||
@@ -36,7 +40,7 @@ class HomeGoodsItemSingle extends StatelessWidget { | |||
return GestureDetector( | |||
onTap: () => _onJumpGoodsDetails(context, goods), | |||
child: Container( | |||
margin: EdgeInsets.only(left: 12.5, right: 12.5, top: 4, bottom: 4), | |||
margin: EdgeInsets.only(left: marginLeft, right: marginRight, top: marginTop, bottom: marginBottom), | |||
padding: EdgeInsets.all(7.5), | |||
decoration: BoxDecoration( | |||
color: Colors.white, | |||
@@ -44,6 +44,21 @@ class HomeGoodsModel extends Equatable { | |||
detailData = json['detail_data']; | |||
} | |||
void fromJson(Map<String, dynamic> json) { | |||
provider = json['provider']; | |||
providerName = json['provider_name']; | |||
goodId = json['good_id']; | |||
goodImage = json['good_image']; | |||
goodTitle = json['good_title']; | |||
shopName = json['shop_name']; | |||
coupon = json['coupon']; | |||
commission = json['commission']; | |||
marketPrice = json['market_price']; | |||
currentPrice = json['current_price']; | |||
inorderCount = json['inorder_count']; | |||
detailData = json['detail_data']; | |||
} | |||
Map<String, dynamic> toJson() { | |||
final Map<String, dynamic> data = new Map<String, dynamic>(); | |||
data['provider'] = this.provider; | |||
@@ -59,10 +59,11 @@ class _HomeQuickEntryWidgetContianerState | |||
); | |||
} | |||
/// 主视图 | |||
Widget _getMainWidget(HomeQuickEntryModel model) { | |||
int dataSize = 15; //model?.type_normal?.length ?? 0; // 总数 | |||
int columSize = 5; //int.parse(model?.colum_size ?? '5'); // 列数 | |||
int rowSize = 2; //int.parse(model?.row_size ?? '2'); // 行数 | |||
int dataSize = model?.type_normal?.length ?? 0; // 总数 | |||
int columSize = int.parse(model?.colum_size ?? '5'); // 列数 | |||
int rowSize = int.parse(model?.row_size ?? '2'); // 行数 | |||
rowSize = columSize * rowSize <= dataSize | |||
? rowSize | |||
: dataSize % columSize == 0 | |||
@@ -84,9 +85,9 @@ class _HomeQuickEntryWidgetContianerState | |||
const double titleHeight = 20; | |||
// 总体的高度 == 行数 * (图片高度 + 标题高度 + 元素之间的边距) + 上下内边距 | |||
double containerHeight = | |||
rowSize * (iconHeight + titleHeight + itemPadding * 2) + | |||
(bottomSize * 2); | |||
double containerHeight = rowSize * (iconHeight + titleHeight + itemPadding * 2) + (bottomSize * 2); | |||
return Container( | |||
// padding: const EdgeInsets.only(bottom: bottomSize, top: bottomSize), | |||
@@ -121,7 +122,7 @@ class _HomeQuickEntryWidgetContianerState | |||
itemPadding: itemPadding, | |||
); | |||
}, | |||
pagination: _SwiperCustomPagination(pageCount), | |||
pagination: pageCount > 1 ? _SwiperCustomPagination(pageCount) : null, | |||
), | |||
), | |||
) | |||
@@ -130,7 +131,7 @@ class _HomeQuickEntryWidgetContianerState | |||
); | |||
} | |||
// 自定义进度条 | |||
/// 自定义进度条 | |||
SwiperPlugin _SwiperCustomPagination(int pageCount) { | |||
List list = []; | |||
for (int i = 0; i < pageCount; i++) { | |||
@@ -54,8 +54,7 @@ class _HomeSlideBannerContainerState extends State<HomeSlideBannerContainer> { | |||
// )); | |||
// Navigator.push(context, CupertinoPageRoute(builder: (_)=> TeamPage())); | |||
Navigator.push( | |||
context, CupertinoPageRoute(builder: (_) => MessageNoticePage(null))); | |||
// Navigator.push(context, CupertinoPageRoute(builder: (_) => VipCenterPage(null))); | |||
} | |||
@override | |||
@@ -13,6 +13,7 @@ class TeamAppBarWidget extends StatelessWidget { | |||
return SliverAppBar( | |||
// expandedHeight: 200.0, | |||
brightness: Brightness.light, | |||
leading: IconButton( | |||
icon: Icon( | |||
Icons.arrow_back_ios, | |||
@@ -251,12 +251,15 @@ class __TeamRecommendWidgetState extends State<_TeamRecommendWidgetContainer> { | |||
/// 头像widget | |||
Widget _getAvatarWidget(TeamDataModel dataModel) { | |||
return Container( | |||
width: 55, | |||
// height: 55, | |||
// color: Colors.red, | |||
child: CachedNetworkImage( | |||
imageUrl: dataModel?.referrerAvatar ?? '', | |||
return ClipRRect( | |||
borderRadius: BorderRadius.circular(55/2), | |||
child: Container( | |||
width: 55, | |||
// height: 55, | |||
// color: Colors.red, | |||
child: CachedNetworkImage( | |||
imageUrl: dataModel?.referrerAvatar ?? '', | |||
), | |||
), | |||
); | |||
} | |||
@@ -3,6 +3,7 @@ import 'dart:convert'; | |||
import 'package:cached_network_image/cached_network_image.dart'; | |||
import 'package:flutter/cupertino.dart'; | |||
import 'package:flutter/material.dart'; | |||
import 'package:zhiying_base_widget/pages/bil_detail_page/bil_detail_page.dart'; | |||
import 'package:zhiying_base_widget/pages/wallet_page/wallet_detail_page.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'; | |||
@@ -24,12 +25,8 @@ class WalletBil extends StatelessWidget { | |||
? WalletIncomeSkeleton() | |||
: GestureDetector( | |||
onTap: () { | |||
Navigator.push( | |||
context, | |||
CupertinoPageRoute( | |||
builder: (context) => WalletDetailPage(), | |||
), | |||
); | |||
RouterUtil.route( | |||
SkipModel.fromJson(json.decode(data['data'])), data, context); | |||
}, | |||
child: Container( | |||
decoration: BoxDecoration( | |||
@@ -0,0 +1,287 @@ | |||
class BilDetailStyleModel { | |||
String appBarName; | |||
String appBarNameColor; | |||
String appBarBgImg; | |||
String appBarBgColor; | |||
String tabLineColor; | |||
String tabNoSeletedColor; | |||
String tabSeletedColor; | |||
List<TabList> tabList; | |||
String timeSelectColor; | |||
String btnNoSelectedColor; | |||
String btnSelectedColor; | |||
List<InputTabViewBtns> inputTabViewBtns; | |||
List<InputTabViewBtns> outTabViewBtns; | |||
InputItemStyle inputItemStyle; | |||
OutputItemStyle outputItemStyle; | |||
BilDetailStyleModel( | |||
{this.appBarName, | |||
this.appBarNameColor, | |||
this.appBarBgImg, | |||
this.appBarBgColor, | |||
this.tabLineColor, | |||
this.tabNoSeletedColor, | |||
this.tabSeletedColor, | |||
this.tabList, | |||
this.timeSelectColor, | |||
this.btnNoSelectedColor, | |||
this.btnSelectedColor, | |||
this.inputTabViewBtns, | |||
this.outTabViewBtns, | |||
this.inputItemStyle, | |||
this.outputItemStyle}); | |||
BilDetailStyleModel.fromJson(Map<String, dynamic> json) { | |||
appBarName = json['app_bar_name']; | |||
appBarNameColor = json['app_bar_name_color']; | |||
appBarBgImg = json['app_bar_bg_img']; | |||
appBarBgColor = json['app_bar_bg_color']; | |||
tabLineColor = json['tab_line_color']; | |||
tabNoSeletedColor = json['tab_no_seleted_color']; | |||
tabSeletedColor = json['tab_seleted_color']; | |||
if (json['tab_list'] != null) { | |||
tabList = new List<TabList>(); | |||
json['tab_list'].forEach((v) { | |||
tabList.add(new TabList.fromJson(v)); | |||
}); | |||
} | |||
timeSelectColor = json['time_select_color']; | |||
btnNoSelectedColor = json['btn_no_selected_color']; | |||
btnSelectedColor = json['btn_selected_color']; | |||
if (json['input_tab_view_btns'] != null) { | |||
inputTabViewBtns = new List<InputTabViewBtns>(); | |||
json['input_tab_view_btns'].forEach((v) { | |||
inputTabViewBtns.add(new InputTabViewBtns.fromJson(v)); | |||
}); | |||
} | |||
if (json['out_tab_view_btns'] != null) { | |||
outTabViewBtns = new List<InputTabViewBtns>(); | |||
json['out_tab_view_btns'].forEach((v) { | |||
outTabViewBtns.add(new InputTabViewBtns.fromJson(v)); | |||
}); | |||
} | |||
inputItemStyle = json['input_item_style'] != null | |||
? new InputItemStyle.fromJson(json['input_item_style']) | |||
: null; | |||
outputItemStyle = json['output_item_style'] != null | |||
? new OutputItemStyle.fromJson(json['output_item_style']) | |||
: null; | |||
} | |||
Map<String, dynamic> toJson() { | |||
final Map<String, dynamic> data = new Map<String, dynamic>(); | |||
data['app_bar_name'] = this.appBarName; | |||
data['app_bar_name_color'] = this.appBarNameColor; | |||
data['app_bar_bg_img'] = this.appBarBgImg; | |||
data['app_bar_bg_color'] = this.appBarBgColor; | |||
data['tab_line_color'] = this.tabLineColor; | |||
data['tab_no_seleted_color'] = this.tabNoSeletedColor; | |||
data['tab_seleted_color'] = this.tabSeletedColor; | |||
if (this.tabList != null) { | |||
data['tab_list'] = this.tabList.map((v) => v.toJson()).toList(); | |||
} | |||
data['time_select_color'] = this.timeSelectColor; | |||
data['btn_no_selected_color'] = this.btnNoSelectedColor; | |||
data['btn_selected_color'] = this.btnSelectedColor; | |||
if (this.inputTabViewBtns != null) { | |||
data['input_tab_view_btns'] = | |||
this.inputTabViewBtns.map((v) => v.toJson()).toList(); | |||
} | |||
if (this.outTabViewBtns != null) { | |||
data['out_tab_view_btns'] = | |||
this.outTabViewBtns.map((v) => v.toJson()).toList(); | |||
} | |||
if (this.inputItemStyle != null) { | |||
data['input_item_style'] = this.inputItemStyle.toJson(); | |||
} | |||
if (this.outputItemStyle != null) { | |||
data['output_item_style'] = this.outputItemStyle.toJson(); | |||
} | |||
return data; | |||
} | |||
} | |||
class TabList { | |||
String type; | |||
String name; | |||
TabList({this.type, this.name}); | |||
TabList.fromJson(Map<String, dynamic> json) { | |||
type = json['type']; | |||
name = json['name']; | |||
} | |||
Map<String, dynamic> toJson() { | |||
final Map<String, dynamic> data = new Map<String, dynamic>(); | |||
data['type'] = this.type; | |||
data['name'] = this.name; | |||
return data; | |||
} | |||
} | |||
class InputItemStyle { | |||
String typeNameColor; | |||
String titleColor; | |||
String amountColor; | |||
String contentColor; | |||
String copyBtnText; | |||
String copyBtnTextColor; | |||
String copyBtnBgColor; | |||
String orderIdText; | |||
String orderTypeText; | |||
String amountText; | |||
String timeText; | |||
String settleTimeText; | |||
List<String> keys; | |||
InputItemStyle( | |||
{this.typeNameColor, | |||
this.titleColor, | |||
this.amountColor, | |||
this.contentColor, | |||
this.copyBtnText, | |||
this.copyBtnTextColor, | |||
this.copyBtnBgColor, | |||
this.orderIdText, | |||
this.orderTypeText, | |||
this.amountText, | |||
this.timeText, | |||
this.settleTimeText, | |||
this.keys}); | |||
InputItemStyle.fromJson(Map<String, dynamic> json) { | |||
typeNameColor = json['type_name_color']; | |||
titleColor = json['title_color']; | |||
amountColor = json['amount_color']; | |||
contentColor = json['content_color']; | |||
copyBtnText = json['copy_btn_text']; | |||
copyBtnTextColor = json['copy_btn_text_color']; | |||
copyBtnBgColor = json['copy_btn_bg_color']; | |||
orderIdText = json['order_id_text']; | |||
orderTypeText = json['order_type_text']; | |||
amountText = json['amount_text']; | |||
timeText = json['time_text']; | |||
settleTimeText = json['settle_time_text']; | |||
keys = json['keys'].cast<String>(); | |||
} | |||
Map<String, dynamic> toJson() { | |||
final Map<String, dynamic> data = new Map<String, dynamic>(); | |||
data['type_name_color'] = this.typeNameColor; | |||
data['title_color'] = this.titleColor; | |||
data['amount_color'] = this.amountColor; | |||
data['content_color'] = this.contentColor; | |||
data['copy_btn_text'] = this.copyBtnText; | |||
data['copy_btn_text_color'] = this.copyBtnTextColor; | |||
data['copy_btn_bg_color'] = this.copyBtnBgColor; | |||
data['order_id_text'] = this.orderIdText; | |||
data['order_type_text'] = this.orderTypeText; | |||
data['amount_text'] = this.amountText; | |||
data['time_text'] = this.timeText; | |||
data['settle_time_text'] = this.settleTimeText; | |||
data['keys'] = this.keys; | |||
return data; | |||
} | |||
} | |||
class OutputItemStyle { | |||
String typeNameColor; | |||
String titleColor; | |||
String amountColor; | |||
String contentColor; | |||
String copyBtnTextColor; | |||
String copyBtnText; | |||
String copyBtnBgColor; | |||
String orderIdText; | |||
String withdrawAccountText; | |||
String withdrawAmountText; | |||
String withdrawTimeText; | |||
String withdrawOrderStatusText; | |||
String consumeOrderTypeText; | |||
String consumeAmountText; | |||
String consumeTimeText; | |||
List<String> withdrawKeys; | |||
List<String> consumeKeys; | |||
OutputItemStyle( | |||
{this.typeNameColor, | |||
this.titleColor, | |||
this.amountColor, | |||
this.contentColor, | |||
this.copyBtnTextColor, | |||
this.copyBtnBgColor, | |||
this.orderIdText, | |||
this.withdrawAccountText, | |||
this.withdrawAmountText, | |||
this.withdrawTimeText, | |||
this.withdrawOrderStatusText, | |||
this.consumeOrderTypeText, | |||
this.consumeAmountText, | |||
this.consumeTimeText, | |||
this.withdrawKeys, | |||
this.consumeKeys}); | |||
OutputItemStyle.fromJson(Map<String, dynamic> json) { | |||
typeNameColor = json['type_name_color']; | |||
titleColor = json['title_color']; | |||
amountColor = json['amount_color']; | |||
contentColor = json['content_color']; | |||
copyBtnTextColor = json['copy_btn_text_color']; | |||
copyBtnText=json['copy_btn_text']; | |||
copyBtnBgColor = json['copy_btn_bg_color']; | |||
orderIdText = json['order_id_text']; | |||
withdrawAccountText = json['withdraw_account_text']; | |||
withdrawAmountText = json['withdraw_amount_text']; | |||
withdrawTimeText = json['withdraw_time_text']; | |||
withdrawOrderStatusText = json['withdraw_order_status_text']; | |||
consumeOrderTypeText = json['consume_order_type_text']; | |||
consumeAmountText = json['consume_amount_text']; | |||
consumeTimeText = json['consume_time_text']; | |||
withdrawKeys = json['withdraw_keys'].cast<String>(); | |||
consumeKeys = json['consume_keys'].cast<String>(); | |||
} | |||
Map<String, dynamic> toJson() { | |||
final Map<String, dynamic> data = new Map<String, dynamic>(); | |||
data['type_name_color'] = this.typeNameColor; | |||
data['title_color'] = this.titleColor; | |||
data['amount_color'] = this.amountColor; | |||
data['content_color'] = this.contentColor; | |||
data['copy_btn_text_color'] = this.copyBtnTextColor; | |||
data['copy_btn_bg_color'] = this.copyBtnBgColor; | |||
data['order_id_text'] = this.orderIdText; | |||
data['withdraw_account_text'] = this.withdrawAccountText; | |||
data['withdraw_amount_text'] = this.withdrawAmountText; | |||
data['withdraw_time_text'] = this.withdrawTimeText; | |||
data['withdraw_order_status_text'] = this.withdrawOrderStatusText; | |||
data['consume_order_type_text'] = this.consumeOrderTypeText; | |||
data['consume_amount_text'] = this.consumeAmountText; | |||
data['consume_time_text'] = this.consumeTimeText; | |||
data['withdraw_keys'] = this.withdrawKeys; | |||
data['consume_keys'] = this.consumeKeys; | |||
return data; | |||
} | |||
} | |||
class InputTabViewBtns { | |||
String type; | |||
String name; | |||
InputTabViewBtns( | |||
{this.type,this.name}); | |||
InputTabViewBtns.fromJson(Map<String, dynamic> json) { | |||
type=json['type']; | |||
name=json['name']; | |||
} | |||
Map<String, dynamic> toJson() { | |||
final Map<String, dynamic> data = new Map<String, dynamic>(); | |||
data['name']=name; | |||
data['type']=type; | |||
return data; | |||
} | |||
} |
@@ -0,0 +1,918 @@ | |||
import 'dart:convert'; | |||
import 'package:flutter/material.dart'; | |||
import 'package:flutter/services.dart'; | |||
import 'package:intl/intl.dart'; | |||
import 'package:pull_to_refresh/pull_to_refresh.dart'; | |||
import 'package:zhiying_base_widget/dialog/select_date_ym_dialog/select_date_ym_dialog.dart'; | |||
import 'package:zhiying_base_widget/widgets/wallet/wallet_detail/wallet_detail_bloc.dart'; | |||
import 'package:zhiying_base_widget/widgets/wallet_bil_detail/wallet_bil_detail_widget_bloc.dart'; | |||
import 'package:zhiying_comm/util/base_bloc.dart'; | |||
import 'package:zhiying_comm/util/extension/color.dart'; | |||
import 'package:flutter_screenutil/flutter_screenutil.dart'; | |||
import 'model/wallet_style_model.dart'; | |||
import 'package:fluttertoast/fluttertoast.dart'; | |||
////钱包明细页面 | |||
class WalletBilDetail extends StatefulWidget { | |||
final Map<String, dynamic> data; | |||
const WalletBilDetail({Key key, this.data}) : super(key: key); | |||
@override | |||
_WalletBilDetailState createState() => _WalletBilDetailState(); | |||
} | |||
class _WalletBilDetailState extends State<WalletBilDetail> | |||
with TickerProviderStateMixin, AutomaticKeepAliveClientMixin { | |||
WalletBilDetailWidgetBloc _bloc; | |||
TabController _tabController; | |||
@override | |||
void initState() { | |||
_bloc = WalletBilDetailWidgetBloc(); | |||
_bloc.initStyleData(json.decode(widget.data['data'])); | |||
_tabController = | |||
TabController(length: _bloc.styleData.tabList.length, vsync: this); | |||
_bloc.loadInputData(_bloc.inPutCurrentPage, _bloc.inputShowDate); | |||
_bloc.loadOutputData(_bloc.outPutCurrentPage, _bloc.outputShowDate); | |||
super.initState(); | |||
} | |||
@override | |||
Widget build(BuildContext context) { | |||
return BlocProvider( | |||
bloc: _bloc, | |||
child: Container( | |||
child: Column( | |||
children: <Widget>[ | |||
AppBar( | |||
brightness: Brightness.light, | |||
backgroundColor: | |||
HexColor.fromHex(_bloc.styleData.appBarBgColor), | |||
centerTitle: true, | |||
leading: IconButton( | |||
icon: Icon( | |||
Icons.arrow_back_ios, | |||
size: 18, | |||
color: HexColor.fromHex(_bloc.styleData.appBarNameColor), | |||
), | |||
onPressed: () { | |||
Navigator.pop(context); | |||
}), | |||
title: Text( | |||
_bloc.styleData.appBarName ?? "", | |||
style: TextStyle( | |||
color: HexColor.fromHex(_bloc.styleData.appBarNameColor)), | |||
), | |||
), | |||
Container( | |||
color: Colors.white, | |||
child: TabBar( | |||
controller: _tabController, | |||
tabs: _buildTabBarItem(), | |||
indicatorWeight: 3, | |||
labelStyle: TextStyle(fontSize: 30.sp), | |||
labelColor: HexColor.fromHex(_bloc.styleData.tabSeletedColor), | |||
unselectedLabelColor: | |||
HexColor.fromHex(_bloc.styleData.tabNoSeletedColor), | |||
indicatorColor: | |||
HexColor.fromHex(_bloc.styleData.tabLineColor), | |||
indicatorSize: TabBarIndicatorSize.label, | |||
), | |||
), | |||
Expanded( | |||
child: TabBarView( | |||
controller: _tabController, | |||
children: _buildTabViewPage())) | |||
], | |||
), | |||
)); | |||
} | |||
///创建tabbar按键 | |||
_buildTabBarItem() { | |||
List<Widget> listWidget = List(); | |||
for (var item in _bloc.styleData.tabList) { | |||
listWidget.add(Tab( | |||
text: item.name ?? "", | |||
)); | |||
} | |||
return listWidget; | |||
} | |||
_buildType(List<InputTabViewBtns> tabViewBtns, TabList tabList) { | |||
var selectType; | |||
if (tabList.type == 'input') { | |||
selectType = _bloc.inputSelectType; | |||
} else { | |||
selectType = _bloc.outputSelectType; | |||
; | |||
} | |||
return Row( | |||
children: <Widget>[ | |||
SizedBox(width: 12.5), | |||
InkWell( | |||
onTap: () { | |||
///显示日期选择弹窗 | |||
_selectDate(tabList); | |||
}, | |||
child: Padding( | |||
padding: const EdgeInsets.only(top: 8, bottom: 8), | |||
child: Text( | |||
tabList.type == "input" | |||
? _bloc.inputShowDate | |||
: _bloc.outputShowDate, | |||
style: TextStyle( | |||
fontSize: 28.sp, | |||
color: | |||
HexColor.fromHex(_bloc.styleData.timeSelectColor)))), | |||
), | |||
Icon( | |||
Icons.arrow_drop_down, | |||
color: HexColor.fromHex(_bloc.styleData.timeSelectColor), | |||
), | |||
Expanded( | |||
child: Container( | |||
height: 50, | |||
child: ListView.builder( | |||
scrollDirection: Axis.horizontal, | |||
shrinkWrap: true, | |||
itemCount: tabViewBtns.length, | |||
itemBuilder: (context, index) { | |||
return InkWell( | |||
onTap: () async { | |||
if (tabList.type == 'input') { | |||
_bloc.inputSelectType = tabViewBtns[index].type; | |||
_bloc.inPutCurrentPage=1; | |||
_bloc.loadInputData( | |||
_bloc.inPutCurrentPage, _bloc.inputShowDate, | |||
type: _bloc.inputSelectType); | |||
} else { | |||
_bloc.outputSelectType = tabViewBtns[index].type; | |||
_bloc.outPutCurrentPage=1; | |||
_bloc.loadOutputData( | |||
_bloc.outPutCurrentPage, _bloc.outputShowDate, | |||
type: _bloc.outputSelectType); | |||
} | |||
_bloc.refresh(); | |||
}, | |||
child: Container( | |||
margin: EdgeInsets.only( | |||
top: 10, left: 8, right: 8, bottom: 10), | |||
decoration: BoxDecoration( | |||
border: Border.all( | |||
color: HexColor.fromHex( | |||
selectType == tabViewBtns[index].type | |||
? _bloc.styleData.btnSelectedColor | |||
: _bloc.styleData.btnNoSelectedColor), | |||
), | |||
borderRadius: BorderRadius.circular(50)), | |||
child: Padding( | |||
padding: EdgeInsets.only(left: 16, right: 16), | |||
child: Center( | |||
child: Text( | |||
tabViewBtns[index].name ?? "", | |||
style: TextStyle( | |||
color: HexColor.fromHex( | |||
selectType == tabViewBtns[index].type | |||
? _bloc.styleData.btnSelectedColor | |||
: _bloc.styleData.btnNoSelectedColor)), | |||
)), | |||
), | |||
)); | |||
}), | |||
)) | |||
], | |||
); | |||
} | |||
_selectDate(TabList tabList) async { | |||
var result = await showDialog( | |||
context: context, builder: (context) => SelectDateYMDialog()); | |||
if (result != null) { | |||
var dataTime = DateFormat('yyyy-MM').format( | |||
DateTime(int.parse(result['year']), int.parse(result['month']))); | |||
if (tabList.type == "input") { | |||
_bloc.inputShowDate = dataTime; | |||
_bloc.loadInputData(_bloc.inPutCurrentPage, _bloc.inputShowDate); | |||
} else { | |||
_bloc.outputShowDate = dataTime; | |||
_bloc.loadOutputData(_bloc.outPutCurrentPage, _bloc.outputShowDate); | |||
} | |||
_bloc.refresh(); | |||
} | |||
} | |||
_buildBottomItem(TabList tabList) { | |||
return ListView.builder( | |||
shrinkWrap: true, | |||
itemCount: tabList.type == 'input' | |||
? _bloc.inputDataVM.length | |||
: _bloc.outputDataVM.length, | |||
itemBuilder: (context, index) { | |||
return _buildItem(context, index, tabList); | |||
}); | |||
} | |||
Widget _buildItem(BuildContext context, int index, TabList tabList) { | |||
if (tabList.type == 'input') { | |||
InputItemStyle inputItemStyle = _bloc.styleData.inputItemStyle; | |||
var modelItem = _bloc.inputDataVM[index]; | |||
return Container( | |||
margin: EdgeInsets.only(left: 12.5, right: 12.5, bottom: 4, top: 4), | |||
padding: | |||
EdgeInsets.only(left: 25.w, right: 25.w, top: 20.h, bottom: 20.h), | |||
decoration: BoxDecoration( | |||
color: HexColor.fromHex("#FFFFFF"), | |||
borderRadius: BorderRadius.circular(8)), | |||
child: Column( | |||
children: <Widget>[ | |||
Row( | |||
mainAxisAlignment: MainAxisAlignment.spaceBetween, | |||
children: <Widget>[ | |||
Row( | |||
children: <Widget>[ | |||
Container( | |||
decoration: BoxDecoration( | |||
borderRadius: BorderRadius.circular(4), | |||
color: HexColor.fromHex("#FFFFF3F3"), | |||
border: Border.all( | |||
color: HexColor.fromHex( | |||
inputItemStyle.typeNameColor))), | |||
child: Padding( | |||
padding: const EdgeInsets.only( | |||
left: 4, right: 4, top: 2, bottom: 2), | |||
child: Center( | |||
child: Text( | |||
modelItem['type'] ?? "", | |||
style: TextStyle( | |||
color: HexColor.fromHex( | |||
inputItemStyle.typeNameColor), | |||
fontSize: 20.sp), | |||
), | |||
), | |||
), | |||
), | |||
Container( | |||
width: 353.w, | |||
margin: EdgeInsets.only(left: 15.w), | |||
child: Text( | |||
modelItem['title'] ?? "", | |||
maxLines: 1, | |||
overflow: TextOverflow.ellipsis, | |||
style: TextStyle(fontSize: 28.sp), | |||
)) | |||
], | |||
), | |||
Row( | |||
children: <Widget>[ | |||
Text( | |||
"+ ", | |||
style: TextStyle( | |||
color: HexColor.fromHex(inputItemStyle.amountColor)), | |||
), | |||
Text( | |||
"¥ " + modelItem['amount'], | |||
style: TextStyle( | |||
color: HexColor.fromHex(inputItemStyle.amountColor), | |||
fontSize: 30.sp), | |||
) | |||
], | |||
) | |||
], | |||
), | |||
SizedBox( | |||
height: 4, | |||
), | |||
///订单编号 | |||
Row( | |||
children: <Widget>[ | |||
Text( | |||
inputItemStyle.orderIdText, | |||
style: TextStyle( | |||
color: HexColor.fromHex(inputItemStyle.contentColor), | |||
fontSize: 22.sp), | |||
), | |||
SizedBox( | |||
width: 4, | |||
), | |||
Text( | |||
modelItem['order_id'], | |||
style: TextStyle( | |||
color: HexColor.fromHex(inputItemStyle.contentColor), | |||
fontSize: 22.sp), | |||
), | |||
SizedBox( | |||
width: 28.w, | |||
), | |||
GestureDetector( | |||
onTap: () { | |||
Clipboard.setData( | |||
ClipboardData(text: modelItem['order_id'])); | |||
Fluttertoast.showToast(msg: "已复制"); | |||
}, | |||
child: Container( | |||
decoration: BoxDecoration( | |||
borderRadius: BorderRadius.circular(4), | |||
color: HexColor.fromHex(inputItemStyle.copyBtnBgColor), | |||
border: Border.all( | |||
color: | |||
HexColor.fromHex(inputItemStyle.contentColor))), | |||
child: Padding( | |||
padding: EdgeInsets.only( | |||
left: 16, right: 16, top: 1, bottom: 1), | |||
child: Text( | |||
inputItemStyle.copyBtnText, | |||
style: TextStyle( | |||
color: | |||
HexColor.fromHex(inputItemStyle.contentColor), | |||
fontSize: 22.sp), | |||
), | |||
), | |||
), | |||
) | |||
], | |||
), | |||
SizedBox( | |||
height: 4, | |||
), | |||
Row( | |||
children: <Widget>[ | |||
Expanded( | |||
child: Row( | |||
children: <Widget>[ | |||
Text( | |||
inputItemStyle.orderTypeText, | |||
style: TextStyle( | |||
color: HexColor.fromHex(inputItemStyle.contentColor), | |||
fontSize: 22.sp), | |||
), | |||
SizedBox( | |||
width: 4, | |||
), | |||
Text( | |||
modelItem['order_type'] ?? "", | |||
style: TextStyle( | |||
color: HexColor.fromHex("#FF999999"), | |||
fontSize: 22.sp), | |||
), | |||
], | |||
)), | |||
Expanded( | |||
child: Row( | |||
children: <Widget>[ | |||
Text( | |||
inputItemStyle.amountText + " ¥" + modelItem['amount'], | |||
style: TextStyle( | |||
color: HexColor.fromHex(inputItemStyle.contentColor), | |||
fontSize: 22.sp), | |||
), | |||
], | |||
)) | |||
], | |||
), | |||
SizedBox( | |||
height: 4, | |||
), | |||
Row( | |||
children: <Widget>[ | |||
Expanded( | |||
child: Row( | |||
children: <Widget>[ | |||
Text( | |||
inputItemStyle.timeText, | |||
style: TextStyle( | |||
color: HexColor.fromHex(inputItemStyle.contentColor), | |||
fontSize: 22.sp), | |||
), | |||
SizedBox( | |||
width: 4, | |||
), | |||
Text( | |||
modelItem['time'] ?? "", | |||
style: TextStyle( | |||
color: HexColor.fromHex("#FF999999"), | |||
fontSize: 22.sp), | |||
), | |||
], | |||
)), | |||
Expanded( | |||
child: Row( | |||
children: <Widget>[ | |||
Text( | |||
inputItemStyle.settleTimeText + | |||
" " + | |||
modelItem['settle_time'] ?? | |||
"", | |||
style: TextStyle( | |||
color: HexColor.fromHex(inputItemStyle.contentColor), | |||
fontSize: 22.sp), | |||
), | |||
], | |||
)) | |||
], | |||
), | |||
], | |||
), | |||
); | |||
} else if (tabList.type == 'output') { | |||
OutputItemStyle outputItemStyle = _bloc.styleData.outputItemStyle; | |||
var modelItem = _bloc.outputDataVM[index]; | |||
if (modelItem['type'] == '消费') { | |||
///消费返回的Item | |||
return Container( | |||
margin: EdgeInsets.only(left: 12.5, right: 12.5, bottom: 4, top: 4), | |||
padding: | |||
EdgeInsets.only(left: 25.w, right: 25.w, top: 20.h, bottom: 20.h), | |||
decoration: BoxDecoration( | |||
color: HexColor.fromHex("#FFFFFF"), | |||
borderRadius: BorderRadius.circular(8)), | |||
child: Column( | |||
children: <Widget>[ | |||
Row( | |||
mainAxisAlignment: MainAxisAlignment.spaceBetween, | |||
children: <Widget>[ | |||
Row( | |||
children: <Widget>[ | |||
Container( | |||
decoration: BoxDecoration( | |||
borderRadius: BorderRadius.circular(4), | |||
color: HexColor.fromHex("#FFFFF3F3"), | |||
border: Border.all( | |||
color: HexColor.fromHex( | |||
outputItemStyle.typeNameColor))), | |||
child: Padding( | |||
padding: const EdgeInsets.only( | |||
left: 4, right: 4, top: 2, bottom: 2), | |||
child: Center( | |||
child: Text( | |||
modelItem['type'] ?? "", | |||
style: TextStyle( | |||
color: HexColor.fromHex( | |||
outputItemStyle.typeNameColor), | |||
fontSize: 20.sp), | |||
), | |||
), | |||
), | |||
), | |||
Container( | |||
width: 353.w, | |||
margin: EdgeInsets.only(left: 15.w), | |||
child: Text( | |||
modelItem['title'] ?? "", | |||
maxLines: 1, | |||
overflow: TextOverflow.ellipsis, | |||
style: TextStyle(fontSize: 28.sp), | |||
)) | |||
], | |||
), | |||
Row( | |||
children: <Widget>[ | |||
Text( | |||
"- ", | |||
style: TextStyle( | |||
color: | |||
HexColor.fromHex(outputItemStyle.amountColor)), | |||
), | |||
Text( | |||
"¥ " + modelItem['amount'], | |||
style: TextStyle( | |||
color: | |||
HexColor.fromHex(outputItemStyle.amountColor), | |||
fontSize: 30.sp), | |||
) | |||
], | |||
) | |||
], | |||
), | |||
SizedBox( | |||
height: 4, | |||
), | |||
///订单编号 | |||
Row( | |||
children: <Widget>[ | |||
Text( | |||
outputItemStyle.orderIdText, | |||
style: TextStyle( | |||
color: HexColor.fromHex(outputItemStyle.contentColor), | |||
fontSize: 22.sp), | |||
), | |||
SizedBox( | |||
width: 4, | |||
), | |||
Text( | |||
modelItem['order_id'], | |||
style: TextStyle( | |||
color: HexColor.fromHex(outputItemStyle.contentColor), | |||
fontSize: 22.sp), | |||
), | |||
SizedBox( | |||
width: 28.w, | |||
), | |||
GestureDetector( | |||
onTap: () { | |||
Clipboard.setData( | |||
ClipboardData(text: modelItem['order_id'])); | |||
Fluttertoast.showToast(msg: "已复制"); | |||
}, | |||
child: Container( | |||
decoration: BoxDecoration( | |||
borderRadius: BorderRadius.circular(4), | |||
color: HexColor.fromHex(outputItemStyle.copyBtnBgColor), | |||
border: Border.all( | |||
color: HexColor.fromHex( | |||
outputItemStyle.contentColor))), | |||
child: Padding( | |||
padding: EdgeInsets.only( | |||
left: 16, right: 16, top: 1, bottom: 1), | |||
child: Text( | |||
outputItemStyle.copyBtnText ?? "", | |||
style: TextStyle( | |||
color: | |||
HexColor.fromHex(outputItemStyle.contentColor), | |||
fontSize: 22.sp), | |||
), | |||
), | |||
), | |||
) | |||
], | |||
), | |||
SizedBox( | |||
height: 4, | |||
), | |||
Row( | |||
children: <Widget>[ | |||
Expanded( | |||
child: Row( | |||
children: <Widget>[ | |||
Text( | |||
outputItemStyle.consumeOrderTypeText, | |||
style: TextStyle( | |||
color: | |||
HexColor.fromHex(outputItemStyle.contentColor), | |||
fontSize: 22.sp), | |||
), | |||
SizedBox( | |||
width: 4, | |||
), | |||
Text( | |||
modelItem['order_type'] ?? "", | |||
style: TextStyle( | |||
color: HexColor.fromHex("#FF999999"), | |||
fontSize: 22.sp), | |||
), | |||
], | |||
)), | |||
Expanded( | |||
child: Row( | |||
children: <Widget>[ | |||
Text( | |||
outputItemStyle.consumeAmountText + | |||
" ¥" + | |||
modelItem['amount'], | |||
style: TextStyle( | |||
color: | |||
HexColor.fromHex(outputItemStyle.contentColor), | |||
fontSize: 22.sp), | |||
), | |||
], | |||
)) | |||
], | |||
), | |||
SizedBox( | |||
height: 4, | |||
), | |||
Row( | |||
children: <Widget>[ | |||
Expanded( | |||
child: Row( | |||
children: <Widget>[ | |||
Text( | |||
outputItemStyle.consumeTimeText, | |||
style: TextStyle( | |||
color: | |||
HexColor.fromHex(outputItemStyle.contentColor), | |||
fontSize: 22.sp), | |||
), | |||
SizedBox( | |||
width: 4, | |||
), | |||
Text( | |||
modelItem['time'] ?? "", | |||
style: TextStyle( | |||
color: HexColor.fromHex("#FF999999"), | |||
fontSize: 22.sp), | |||
), | |||
], | |||
)), | |||
// Expanded( | |||
// child: Row( | |||
// children: <Widget>[ | |||
// Text( | |||
// inputItemStyle.consumeTimeText + | |||
// " " + | |||
// modelItem['settle_time'] ?? | |||
// "", | |||
// style: TextStyle( | |||
// color: HexColor.fromHex(inputItemStyle.contentColor), | |||
// fontSize: 22.sp), | |||
// ), | |||
// ], | |||
// )) | |||
], | |||
), | |||
], | |||
), | |||
); | |||
} else if (modelItem['type'] == '提现') { | |||
return Container( | |||
margin: EdgeInsets.only(left: 12.5, right: 12.5, bottom: 4, top: 4), | |||
padding: | |||
EdgeInsets.only(left: 25.w, right: 25.w, top: 20.h, bottom: 20.h), | |||
decoration: BoxDecoration( | |||
color: HexColor.fromHex("#FFFFFF"), | |||
borderRadius: BorderRadius.circular(8)), | |||
child: Column( | |||
children: <Widget>[ | |||
Row( | |||
mainAxisAlignment: MainAxisAlignment.spaceBetween, | |||
children: <Widget>[ | |||
Row( | |||
children: <Widget>[ | |||
Container( | |||
decoration: BoxDecoration( | |||
borderRadius: BorderRadius.circular(4), | |||
color: HexColor.fromHex("#FFFFF3F3"), | |||
border: Border.all( | |||
color: HexColor.fromHex( | |||
outputItemStyle.typeNameColor))), | |||
child: Padding( | |||
padding: const EdgeInsets.only( | |||
left: 4, right: 4, top: 2, bottom: 2), | |||
child: Center( | |||
child: Text( | |||
modelItem['type'] ?? "", | |||
style: TextStyle( | |||
color: HexColor.fromHex( | |||
outputItemStyle.typeNameColor), | |||
fontSize: 20.sp), | |||
), | |||
), | |||
), | |||
), | |||
Container( | |||
width: 353.w, | |||
margin: EdgeInsets.only(left: 15.w), | |||
child: Text( | |||
modelItem['title'] ?? "", | |||
maxLines: 1, | |||
overflow: TextOverflow.ellipsis, | |||
style: TextStyle(fontSize: 28.sp), | |||
)) | |||
], | |||
), | |||
Row( | |||
children: <Widget>[ | |||
Text( | |||
"- ", | |||
style: TextStyle( | |||
color: | |||
HexColor.fromHex(outputItemStyle.amountColor)), | |||
), | |||
Text( | |||
"¥ " + modelItem['amount'], | |||
style: TextStyle( | |||
color: | |||
HexColor.fromHex(outputItemStyle.amountColor), | |||
fontSize: 30.sp), | |||
) | |||
], | |||
) | |||
], | |||
), | |||
SizedBox( | |||
height: 4, | |||
), | |||
///订单编号 | |||
Row( | |||
children: <Widget>[ | |||
Text( | |||
outputItemStyle.orderIdText, | |||
style: TextStyle( | |||
color: HexColor.fromHex(outputItemStyle.contentColor), | |||
fontSize: 22.sp), | |||
), | |||
SizedBox( | |||
width: 4, | |||
), | |||
Text( | |||
modelItem['order_id'], | |||
style: TextStyle( | |||
color: HexColor.fromHex(outputItemStyle.contentColor), | |||
fontSize: 22.sp), | |||
), | |||
SizedBox( | |||
width: 28.w, | |||
), | |||
GestureDetector( | |||
onTap: () { | |||
Clipboard.setData( | |||
ClipboardData(text: modelItem['order_id'])); | |||
Fluttertoast.showToast(msg: "已复制"); | |||
}, | |||
child: Container( | |||
decoration: BoxDecoration( | |||
borderRadius: BorderRadius.circular(4), | |||
color: HexColor.fromHex(outputItemStyle.copyBtnBgColor), | |||
border: Border.all( | |||
color: HexColor.fromHex( | |||
outputItemStyle.contentColor))), | |||
child: Padding( | |||
padding: EdgeInsets.only( | |||
left: 16, right: 16, top: 1, bottom: 1), | |||
child: Text( | |||
outputItemStyle.copyBtnText ?? "", | |||
style: TextStyle( | |||
color: | |||
HexColor.fromHex(outputItemStyle.contentColor), | |||
fontSize: 22.sp), | |||
), | |||
), | |||
), | |||
) | |||
], | |||
), | |||
SizedBox( | |||
height: 4, | |||
), | |||
Row( | |||
children: <Widget>[ | |||
Expanded( | |||
child: Row( | |||
children: <Widget>[ | |||
Text( | |||
outputItemStyle.withdrawAccountText, | |||
style: TextStyle( | |||
color: | |||
HexColor.fromHex(outputItemStyle.contentColor), | |||
fontSize: 22.sp), | |||
), | |||
SizedBox( | |||
width: 4, | |||
), | |||
Text( | |||
modelItem['account'] ?? "", | |||
style: TextStyle( | |||
color: | |||
HexColor.fromHex(outputItemStyle.contentColor), | |||
fontSize: 22.sp), | |||
), | |||
], | |||
)), | |||
Expanded( | |||
child: Row( | |||
children: <Widget>[ | |||
Text( | |||
outputItemStyle.withdrawAmountText + | |||
" ¥" + | |||
modelItem['amount'], | |||
style: TextStyle( | |||
color: | |||
HexColor.fromHex(outputItemStyle.contentColor), | |||
fontSize: 22.sp), | |||
), | |||
], | |||
)) | |||
], | |||
), | |||
SizedBox( | |||
height: 4, | |||
), | |||
Row( | |||
children: <Widget>[ | |||
Expanded( | |||
child: Row( | |||
children: <Widget>[ | |||
Text( | |||
outputItemStyle.withdrawTimeText, | |||
style: TextStyle( | |||
color: | |||
HexColor.fromHex(outputItemStyle.contentColor), | |||
fontSize: 22.sp), | |||
), | |||
SizedBox( | |||
width: 4, | |||
), | |||
Text( | |||
modelItem['time'] ?? "", | |||
style: TextStyle( | |||
color: HexColor.fromHex("#FF999999"), | |||
fontSize: 22.sp), | |||
), | |||
], | |||
)), | |||
Expanded( | |||
child: Row( | |||
children: <Widget>[ | |||
Text( | |||
outputItemStyle.withdrawOrderStatusText + | |||
" " + | |||
modelItem['order_status'] ?? | |||
"", | |||
style: TextStyle( | |||
color: | |||
HexColor.fromHex(outputItemStyle.contentColor), | |||
fontSize: 22.sp), | |||
), | |||
], | |||
)) | |||
], | |||
), | |||
], | |||
), | |||
); | |||
} | |||
} | |||
} | |||
_buildTabViewPage() { | |||
List<Widget> listWidget = List(); | |||
for (var item in _bloc.styleData.tabList) { | |||
List<InputTabViewBtns> tabViewBtns; | |||
if (item.type == 'input') { | |||
tabViewBtns = _bloc.styleData.inputTabViewBtns; | |||
listWidget.add(StreamBuilder( | |||
stream: _bloc.inputOutData, | |||
builder: (context, asny) { | |||
// dataVM = asny.data; | |||
return Container( | |||
child: Column( | |||
children: <Widget>[ | |||
_buildType(tabViewBtns, item), | |||
Expanded( | |||
child: SmartRefresher( | |||
controller: _bloc.inputRefreshController, | |||
enablePullDown: true, | |||
enablePullUp: true, | |||
onLoading: () { | |||
_bloc.inputLoad(); | |||
}, | |||
onRefresh: () { | |||
_bloc.inputRefresh(); | |||
}, | |||
child: _bloc.inputDataVM == null | |||
? Container() | |||
: _buildBottomItem(item)), | |||
) | |||
], | |||
), | |||
); | |||
})); | |||
} else { | |||
tabViewBtns = _bloc.styleData.outTabViewBtns; | |||
listWidget.add(StreamBuilder( | |||
stream: _bloc.outputOutData, | |||
builder: (context, asny) { | |||
// dataVM = asny.data; | |||
return Container( | |||
child: Column( | |||
children: <Widget>[ | |||
_buildType(tabViewBtns, item), | |||
Expanded( | |||
child: SmartRefresher( | |||
controller: _bloc.outputRefreshController, | |||
enablePullDown: true, | |||
enablePullUp: true, | |||
onLoading: () { | |||
_bloc.outputLoad(); | |||
}, | |||
onRefresh: () { | |||
_bloc.outputRefresh(); | |||
}, | |||
child: _bloc.outputDataVM == null | |||
? Container() | |||
: _buildBottomItem(item)), | |||
) | |||
], | |||
), | |||
); | |||
})); | |||
} | |||
} | |||
return listWidget; | |||
} | |||
@override | |||
// TODO: implement wantKeepAlive | |||
bool get wantKeepAlive => true; | |||
} |
@@ -0,0 +1,163 @@ | |||
import 'dart:async'; | |||
import 'package:intl/intl.dart'; | |||
import 'package:pull_to_refresh/pull_to_refresh.dart'; | |||
import 'package:zhiying_comm/util/base_bloc.dart'; | |||
import 'package:zhiying_comm/zhiying_comm.dart'; | |||
import 'model/wallet_style_model.dart'; | |||
class WalletBilDetailWidgetBloc extends BlocBase { | |||
StreamController<List<Map<String, dynamic>>> inputDataController = | |||
StreamController.broadcast(); | |||
Stream get inputOutData => inputDataController.stream; | |||
StreamController<List<Map<String, dynamic>>> outputDataController = | |||
StreamController.broadcast(); | |||
Stream get outputOutData => outputDataController.stream; | |||
List<Map<String, dynamic>> inputDataVM; | |||
List<Map<String, dynamic>> outputDataVM; | |||
///样式model | |||
BilDetailStyleModel styleData; | |||
///支出当前页数 | |||
int outPutCurrentPage = 1; | |||
///收入当前页数 | |||
int inPutCurrentPage = 1; | |||
///收入显示时间 | |||
String inputShowDate; | |||
///支出显示时间 | |||
String outputShowDate; | |||
//收入显示类型 | |||
String inputSelectType = 'all'; | |||
///支出显示类型 | |||
String outputSelectType = 'all'; | |||
///收入下啦刷新 | |||
RefreshController inputRefreshController = RefreshController(); | |||
///支出页面下拉刷新 | |||
RefreshController outputRefreshController = RefreshController(); | |||
@override | |||
void dispose() { | |||
inputDataController.close(); | |||
outputDataController.close(); | |||
inputRefreshController.dispose(); | |||
outputRefreshController.dispose(); | |||
} | |||
initStyleData(Map<String, dynamic> data) { | |||
try { | |||
inputShowDate = DateFormat("yyyy-MM").format(DateTime.now()); | |||
outputShowDate = DateFormat("yyyy-MM").format(DateTime.now()); | |||
styleData = BilDetailStyleModel.fromJson(data); | |||
} catch (e, s) { | |||
print(e); | |||
print(s); | |||
} | |||
} | |||
///加载收入数据 | |||
loadInputData(int page, String date, {String type}) async { | |||
type = inputSelectType; | |||
String paramsStr = "?page=" + page.toString() + "&time=" + date; | |||
if (type != null && type != "all") { | |||
paramsStr += "&type=" + type; | |||
} | |||
NetUtil.request("/api/v1/user/wallet_detail/input" + paramsStr, | |||
method: NetMethod.GET, onSuccess: (data) { | |||
inputRefreshController.refreshCompleted(); | |||
inputRefreshController.loadComplete(); | |||
var listmap = List.from(data).map((e) { | |||
return e as Map<String, dynamic>; | |||
}).toList(); | |||
if (inputDataVM == null) { | |||
inputDataVM = List<Map<String, dynamic>>(); | |||
} | |||
if (listmap == null || listmap.length == 0) { | |||
inputRefreshController.loadNoData(); | |||
} | |||
if (inPutCurrentPage == 1) { | |||
inputDataVM.clear(); | |||
inputDataVM.addAll(listmap); | |||
} else { | |||
inputDataVM.addAll(listmap); | |||
} | |||
refresh(); | |||
}); | |||
} | |||
///加载支出数据 | |||
loadOutputData(int page, String date, {String type}) async { | |||
type = outputSelectType; | |||
String paramsStr = "?page=" + page.toString() + "&time=" + date; | |||
if (type != null && type != "all") { | |||
paramsStr += "&type=" + type; | |||
} | |||
NetUtil.request("/api/v1/user/wallet_detail/output" + paramsStr, | |||
method: NetMethod.GET, onSuccess: (data) { | |||
outputRefreshController.refreshCompleted(); | |||
outputRefreshController.loadComplete(); | |||
var listMap = List.from(data).map((e) { | |||
return e as Map<String, dynamic>; | |||
}).toList(); | |||
if (listMap == null || listMap.length == 0) { | |||
outputRefreshController.loadNoData(); | |||
} | |||
if (outputDataVM == null) { | |||
outputDataVM = List(); | |||
} | |||
if (outPutCurrentPage == 1) { | |||
outputDataVM.clear(); | |||
outputDataVM.addAll(listMap); | |||
} else { | |||
outputDataVM.addAll(listMap); | |||
} | |||
refresh(); | |||
}, onError: (e) { | |||
outputRefreshController.refreshCompleted(); | |||
outputRefreshController.loadComplete(); | |||
}); | |||
} | |||
inputRefresh() { | |||
inPutCurrentPage = 1; | |||
loadInputData(inPutCurrentPage, inputShowDate); | |||
} | |||
inputLoad() { | |||
inPutCurrentPage++; | |||
loadInputData(inPutCurrentPage, inputShowDate); | |||
} | |||
outputRefresh() { | |||
outPutCurrentPage = 1; | |||
loadOutputData(outPutCurrentPage, outputShowDate); | |||
} | |||
outputLoad() { | |||
outPutCurrentPage++; | |||
loadOutputData(outPutCurrentPage, outputShowDate); | |||
} | |||
///全刷新 | |||
refresh() { | |||
inputDataController.add(inputDataVM); | |||
outputDataController.add(outputDataVM); | |||
} | |||
} |
@@ -0,0 +1,211 @@ | |||
import 'package:flutter/material.dart'; | |||
import 'package:shimmer/shimmer.dart'; | |||
class WalletBilDetailSkeleton extends StatelessWidget { | |||
@override | |||
Widget build(BuildContext context) { | |||
return Container( | |||
child: Shimmer.fromColors( | |||
baseColor: Colors.grey[300], | |||
highlightColor: Colors.grey[100], | |||
child: Column( | |||
children: <Widget>[ | |||
Container( | |||
color: Colors.white, | |||
height: 80, | |||
), | |||
SizedBox( | |||
height: 32, | |||
), | |||
Row( | |||
mainAxisAlignment: MainAxisAlignment.spaceEvenly, | |||
children: <Widget>[ | |||
Container( | |||
color: Colors.white, | |||
height: 40, | |||
width: 100, | |||
), | |||
Container( | |||
color: Colors.white, | |||
height: 40, | |||
width: 100, | |||
) | |||
], | |||
), | |||
SizedBox( | |||
height: 16, | |||
), | |||
Row( | |||
mainAxisAlignment: MainAxisAlignment.start, | |||
children: <Widget>[ | |||
SizedBox( | |||
width: 16, | |||
), | |||
Container( | |||
color: Colors.white, | |||
height: 40, | |||
width: 80, | |||
), | |||
SizedBox( | |||
width: 16, | |||
), | |||
Container( | |||
color: Colors.white, | |||
height: 40, | |||
width: 80, | |||
), | |||
SizedBox( | |||
width: 16, | |||
), | |||
Container( | |||
color: Colors.white, | |||
height: 40, | |||
width: 80, | |||
), | |||
SizedBox( | |||
width: 16, | |||
), | |||
Container( | |||
color: Colors.white, | |||
height: 40, | |||
width: 80, | |||
) | |||
], | |||
), | |||
Expanded( | |||
child: ListView.builder( | |||
itemCount: 3, | |||
itemBuilder: _buildItem, | |||
)) | |||
], | |||
)), | |||
); | |||
} | |||
Widget _buildItem(BuildContext context, int index) { | |||
return Container( | |||
margin: EdgeInsets.all(16), | |||
child: Column( | |||
children: <Widget>[ | |||
Row( | |||
children: <Widget>[ | |||
Container( | |||
color: Colors.white, | |||
height: 20, | |||
width: 40, | |||
), | |||
SizedBox( | |||
width: 16, | |||
), | |||
Container( | |||
color: Colors.white, | |||
height: 20, | |||
width: 100, | |||
) | |||
], | |||
), | |||
SizedBox( | |||
height: 8, | |||
), | |||
Row( | |||
children: <Widget>[ | |||
Container( | |||
color: Colors.white, | |||
height: 20, | |||
width: 40, | |||
), | |||
SizedBox( | |||
width: 16, | |||
), | |||
Container( | |||
color: Colors.white, | |||
height: 20, | |||
width: 120, | |||
), | |||
SizedBox( | |||
width: 16, | |||
), | |||
Container( | |||
color: Colors.white, | |||
height: 20, | |||
width: 40, | |||
) | |||
], | |||
), | |||
SizedBox( | |||
height: 8, | |||
), | |||
Row( | |||
children: <Widget>[ | |||
Container( | |||
color: Colors.white, | |||
height: 20, | |||
width: 40, | |||
), | |||
SizedBox( | |||
width: 16, | |||
), | |||
Container( | |||
color: Colors.white, | |||
height: 20, | |||
width: 100, | |||
), | |||
SizedBox( | |||
width: 16, | |||
), | |||
Container( | |||
color: Colors.white, | |||
height: 20, | |||
width: 40, | |||
), | |||
SizedBox( | |||
width: 16, | |||
), | |||
Container( | |||
color: Colors.white, | |||
height: 20, | |||
width: 100, | |||
), | |||
], | |||
), | |||
SizedBox( | |||
height: 8, | |||
), | |||
Row( | |||
children: <Widget>[ | |||
Container( | |||
color: Colors.white, | |||
height: 20, | |||
width: 40, | |||
), | |||
SizedBox( | |||
width: 16, | |||
), | |||
Container( | |||
color: Colors.white, | |||
height: 20, | |||
width: 100, | |||
), | |||
SizedBox( | |||
width: 16, | |||
), | |||
Container( | |||
color: Colors.white, | |||
height: 20, | |||
width: 40, | |||
), | |||
SizedBox( | |||
width: 16, | |||
), | |||
Container( | |||
color: Colors.white, | |||
height: 20, | |||
width: 100, | |||
), | |||
], | |||
) | |||
], | |||
), | |||
); | |||
} | |||
} |
@@ -0,0 +1,606 @@ | |||
import 'package:flutter/material.dart'; | |||
import 'package:intl/intl.dart'; | |||
import 'package:pull_to_refresh/pull_to_refresh.dart'; | |||
import 'package:zhiying_base_widget/dialog/select_date_ym_dialog/select_date_ym_dialog.dart'; | |||
import 'package:zhiying_base_widget/widgets/wallet/wallet_detail/wallet_detail_bloc.dart'; | |||
import 'package:zhiying_base_widget/widgets/wallet_bil_detail/wallet_bil_detail_widget_bloc.dart'; | |||
import 'package:zhiying_comm/util/base_bloc.dart'; | |||
import 'package:zhiying_comm/zhiying_comm.dart'; | |||
import 'model/wallet_style_model.dart'; | |||
class WalletListWidget extends StatefulWidget { | |||
final TabList tabList; | |||
final List<InputTabViewBtns> tabViewBtns; | |||
const WalletListWidget({Key key,this.tabViewBtns, this.tabList}) : super(key: key); | |||
@override | |||
_WalletListWidgetState createState() => _WalletListWidgetState(); | |||
} | |||
class _WalletListWidgetState extends State<WalletListWidget> with AutomaticKeepAliveClientMixin { | |||
WalletBilDetailWidgetBloc _bloc; | |||
List<InputTabViewBtns> tabViewBtns; | |||
TabList item; | |||
@override | |||
void initState() { | |||
item=widget.tabList; | |||
tabViewBtns=widget.tabViewBtns; | |||
super.initState(); | |||
} | |||
@override | |||
Widget build(BuildContext context) { | |||
_bloc = BlocProvider.of(context); | |||
if(item.type=='input'){ | |||
return StreamBuilder( | |||
stream: _bloc.inputOutData, | |||
builder: (context, asny) { | |||
// dataVM = asny.data; | |||
return Container( | |||
child: Column( | |||
children: <Widget>[ | |||
_buildType(tabViewBtns, item), | |||
Expanded( | |||
child: SmartRefresher( | |||
controller: _bloc.inputRefreshController, | |||
enablePullDown: true, | |||
enablePullUp: true, | |||
onLoading: _bloc.outputLoad(), | |||
onRefresh: _bloc.outputRefresh(), | |||
child: _bloc.inputDataVM == null | |||
? Container() | |||
: _buildBottomItem(item)), | |||
) | |||
], | |||
), | |||
); | |||
}); | |||
}else{ | |||
return StreamBuilder( | |||
stream: _bloc.outputOutData, | |||
builder: (context, asny) { | |||
// dataVM = asny.data; | |||
return Container( | |||
child: Column( | |||
children: <Widget>[ | |||
_buildType(tabViewBtns, item), | |||
Expanded( | |||
child: SmartRefresher( | |||
controller: _bloc.outputRefreshController, | |||
enablePullDown: true, | |||
enablePullUp: true, | |||
onLoading: _bloc.outputLoad(), | |||
onRefresh: _bloc.outputRefresh(), | |||
child: _bloc.outputDataVM == null | |||
? Container() | |||
: _buildBottomItem(item)), | |||
) | |||
], | |||
), | |||
); | |||
}); | |||
} | |||
} | |||
_buildType(List<InputTabViewBtns> tabViewBtns, TabList tabList) { | |||
var selectType; | |||
if (tabList.type == 'input') { | |||
selectType = _bloc.inputSelectType; | |||
} else { | |||
selectType = _bloc.outputSelectType; | |||
; | |||
} | |||
return Row( | |||
children: <Widget>[ | |||
SizedBox(width: 12.5), | |||
InkWell( | |||
onTap: () { | |||
///显示日期选择弹窗 | |||
_selectDate(tabList); | |||
}, | |||
child: Padding( | |||
padding: const EdgeInsets.only(top: 8, bottom: 8), | |||
child: Text( | |||
tabList.type == "input" | |||
? _bloc.inputShowDate | |||
: _bloc.outputShowDate, | |||
style: TextStyle( | |||
fontSize: 28.sp, | |||
color: | |||
HexColor.fromHex(_bloc.styleData.timeSelectColor)))), | |||
), | |||
Icon( | |||
Icons.arrow_drop_down, | |||
color: HexColor.fromHex(_bloc.styleData.timeSelectColor), | |||
), | |||
Expanded( | |||
child: Container( | |||
height: 50, | |||
child: ListView.builder( | |||
scrollDirection: Axis.horizontal, | |||
shrinkWrap: true, | |||
itemCount: tabViewBtns.length, | |||
itemBuilder: (context, index) { | |||
return InkWell( | |||
onTap: () async { | |||
if (tabList.type == 'input') { | |||
_bloc.inputSelectType = tabViewBtns[index].type; | |||
_bloc.loadInputData( | |||
_bloc.inPutCurrentPage, _bloc.inputShowDate, | |||
type: _bloc.inputSelectType); | |||
} else { | |||
_bloc.outputSelectType = tabViewBtns[index].type; | |||
_bloc.loadOutputData( | |||
_bloc.outPutCurrentPage, _bloc.outputShowDate, | |||
type: _bloc.outputSelectType); | |||
} | |||
_bloc.refresh(); | |||
}, | |||
child: Container( | |||
margin: EdgeInsets.only( | |||
top: 10, left: 8, right: 8, bottom: 10), | |||
decoration: BoxDecoration( | |||
border: Border.all( | |||
color: HexColor.fromHex( | |||
selectType == tabViewBtns[index].type | |||
? _bloc.styleData.btnSelectedColor | |||
: _bloc.styleData.btnNoSelectedColor), | |||
), | |||
borderRadius: BorderRadius.circular(50)), | |||
child: Padding( | |||
padding: EdgeInsets.only(left: 16, right: 16), | |||
child: Center( | |||
child: Text( | |||
tabViewBtns[index].name ?? "", | |||
style: TextStyle( | |||
color: HexColor.fromHex( | |||
selectType == tabViewBtns[index].type | |||
? _bloc.styleData.btnSelectedColor | |||
: _bloc.styleData.btnNoSelectedColor)), | |||
)), | |||
), | |||
)); | |||
}), | |||
)) | |||
], | |||
); | |||
} | |||
_selectDate(TabList tabList) async { | |||
var result = await showDialog( | |||
context: context, builder: (context) => SelectDateYMDialog()); | |||
if (result != null) { | |||
var dataTime = DateFormat('yyyy-MM').format( | |||
DateTime(int.parse(result['year']), int.parse(result['month']))); | |||
if (tabList.type == "input") { | |||
_bloc.inputShowDate = dataTime; | |||
_bloc.loadInputData(_bloc.inPutCurrentPage, _bloc.inputShowDate); | |||
} else { | |||
_bloc.outputShowDate = dataTime; | |||
_bloc.loadInputData(_bloc.outPutCurrentPage, _bloc.outputShowDate); | |||
} | |||
_bloc.refresh(); | |||
} | |||
} | |||
_buildBottomItem(TabList tabList) { | |||
return ListView.builder( | |||
shrinkWrap: true, | |||
itemCount: tabList.type == 'input' | |||
? _bloc.inputDataVM?.length??0 | |||
: _bloc.outputDataVM?.length??0, | |||
itemBuilder: (context, index) { | |||
return _buildItem(context, index, tabList); | |||
}); | |||
} | |||
Widget _buildItem(BuildContext context, int index, TabList tabList) { | |||
if (tabList.type == 'input') { | |||
InputItemStyle inputItemStyle = _bloc.styleData.inputItemStyle; | |||
var modelItem = _bloc.inputDataVM[index]; | |||
return Container( | |||
margin: EdgeInsets.only(left: 12.5, right: 12.5, bottom: 4, top: 4), | |||
padding: | |||
EdgeInsets.only(left: 25.w, right: 25.w, top: 20.h, bottom: 20.h), | |||
decoration: BoxDecoration( | |||
color: HexColor.fromHex("#FFFFFF"), | |||
borderRadius: BorderRadius.circular(8)), | |||
child: Column( | |||
children: <Widget>[ | |||
Row( | |||
mainAxisAlignment: MainAxisAlignment.spaceBetween, | |||
children: <Widget>[ | |||
Row( | |||
children: <Widget>[ | |||
Container( | |||
decoration: BoxDecoration( | |||
borderRadius: BorderRadius.circular(4), | |||
color: HexColor.fromHex("#FFFFF3F3"), | |||
border: Border.all( | |||
color: HexColor.fromHex( | |||
inputItemStyle.typeNameColor))), | |||
child: Padding( | |||
padding: const EdgeInsets.only( | |||
left: 4, right: 4, top: 2, bottom: 2), | |||
child: Center( | |||
child: Text( | |||
modelItem['type'] ?? "", | |||
style: TextStyle( | |||
color: HexColor.fromHex( | |||
inputItemStyle.typeNameColor), | |||
fontSize: 20.sp), | |||
), | |||
), | |||
), | |||
), | |||
Container( | |||
width: 353.w, | |||
margin: EdgeInsets.only(left: 15.w), | |||
child: Text( | |||
modelItem['title'] ?? "", | |||
maxLines: 1, | |||
overflow: TextOverflow.ellipsis, | |||
style: TextStyle(fontSize: 28.sp), | |||
)) | |||
], | |||
), | |||
Row( | |||
children: <Widget>[ | |||
Text( | |||
"+ ", | |||
style: TextStyle( | |||
color: HexColor.fromHex(inputItemStyle.amountColor)), | |||
), | |||
Text( | |||
"¥ " + modelItem['amount'], | |||
style: TextStyle( | |||
color: HexColor.fromHex(inputItemStyle.amountColor), | |||
fontSize: 30.sp), | |||
) | |||
], | |||
) | |||
], | |||
), | |||
SizedBox( | |||
height: 4, | |||
), | |||
///订单编号 | |||
Row( | |||
children: <Widget>[ | |||
Text( | |||
inputItemStyle.orderIdText, | |||
style: TextStyle( | |||
color: HexColor.fromHex(inputItemStyle.contentColor), | |||
fontSize: 22.sp), | |||
), | |||
SizedBox( | |||
width: 4, | |||
), | |||
Text( | |||
modelItem['order_id'], | |||
style: TextStyle( | |||
color: HexColor.fromHex(inputItemStyle.contentColor), | |||
fontSize: 22.sp), | |||
), | |||
SizedBox( | |||
width: 28.w, | |||
), | |||
Container( | |||
decoration: BoxDecoration( | |||
borderRadius: BorderRadius.circular(4), | |||
color: HexColor.fromHex(inputItemStyle.copyBtnBgColor), | |||
border: Border.all( | |||
color: | |||
HexColor.fromHex(inputItemStyle.contentColor))), | |||
child: Padding( | |||
padding: | |||
EdgeInsets.only(left: 16, right: 16, top: 1, bottom: 1), | |||
child: Text( | |||
inputItemStyle.copyBtnText, | |||
style: TextStyle( | |||
color: HexColor.fromHex(inputItemStyle.contentColor), | |||
fontSize: 22.sp), | |||
), | |||
), | |||
) | |||
], | |||
), | |||
SizedBox( | |||
height: 4, | |||
), | |||
Row( | |||
children: <Widget>[ | |||
Expanded( | |||
child: Row( | |||
children: <Widget>[ | |||
Text( | |||
inputItemStyle.orderTypeText, | |||
style: TextStyle( | |||
color: HexColor.fromHex(inputItemStyle.contentColor), | |||
fontSize: 22.sp), | |||
), | |||
SizedBox( | |||
width: 4, | |||
), | |||
Text( | |||
modelItem['order_type'] ?? "", | |||
style: TextStyle( | |||
color: HexColor.fromHex("#FF999999"), | |||
fontSize: 22.sp), | |||
), | |||
], | |||
)), | |||
Expanded( | |||
child: Row( | |||
children: <Widget>[ | |||
Text( | |||
inputItemStyle.amountText + " ¥" + modelItem['amount'], | |||
style: TextStyle( | |||
color: HexColor.fromHex(inputItemStyle.contentColor), | |||
fontSize: 22.sp), | |||
), | |||
], | |||
)) | |||
], | |||
), | |||
SizedBox( | |||
height: 4, | |||
), | |||
Row( | |||
children: <Widget>[ | |||
Expanded( | |||
child: Row( | |||
children: <Widget>[ | |||
Text( | |||
inputItemStyle.timeText, | |||
style: TextStyle( | |||
color: HexColor.fromHex(inputItemStyle.contentColor), | |||
fontSize: 22.sp), | |||
), | |||
SizedBox( | |||
width: 4, | |||
), | |||
Text( | |||
modelItem['time'] ?? "", | |||
style: TextStyle( | |||
color: HexColor.fromHex("#FF999999"), | |||
fontSize: 22.sp), | |||
), | |||
], | |||
)), | |||
Expanded( | |||
child: Row( | |||
children: <Widget>[ | |||
Text( | |||
inputItemStyle.settleTimeText + | |||
" " + | |||
modelItem['settle_time'] ?? | |||
"", | |||
style: TextStyle( | |||
color: HexColor.fromHex(inputItemStyle.contentColor), | |||
fontSize: 22.sp), | |||
), | |||
], | |||
)) | |||
], | |||
), | |||
], | |||
), | |||
); | |||
} else if (tabList.type == 'output') { | |||
OutputItemStyle inputItemStyle = _bloc.styleData.outputItemStyle; | |||
var modelItem = _bloc.outputDataVM[index]; | |||
if (modelItem['type'] == '消费') { | |||
///消费返回的Item | |||
return Container( | |||
margin: EdgeInsets.only(left: 12.5, right: 12.5, bottom: 4, top: 4), | |||
padding: | |||
EdgeInsets.only(left: 25.w, right: 25.w, top: 20.h, bottom: 20.h), | |||
decoration: BoxDecoration( | |||
color: HexColor.fromHex("#FFFFFF"), | |||
borderRadius: BorderRadius.circular(8)), | |||
child: Column( | |||
children: <Widget>[ | |||
Row( | |||
mainAxisAlignment: MainAxisAlignment.spaceBetween, | |||
children: <Widget>[ | |||
Row( | |||
children: <Widget>[ | |||
Container( | |||
decoration: BoxDecoration( | |||
borderRadius: BorderRadius.circular(4), | |||
color: HexColor.fromHex("#FFFFF3F3"), | |||
border: Border.all( | |||
color: HexColor.fromHex( | |||
inputItemStyle.typeNameColor))), | |||
child: Padding( | |||
padding: const EdgeInsets.only( | |||
left: 4, right: 4, top: 2, bottom: 2), | |||
child: Center( | |||
child: Text( | |||
modelItem['type'] ?? "", | |||
style: TextStyle( | |||
color: HexColor.fromHex( | |||
inputItemStyle.typeNameColor), | |||
fontSize: 20.sp), | |||
), | |||
), | |||
), | |||
), | |||
Container( | |||
width: 353.w, | |||
margin: EdgeInsets.only(left: 15.w), | |||
child: Text( | |||
modelItem['title'] ?? "", | |||
maxLines: 1, | |||
overflow: TextOverflow.ellipsis, | |||
style: TextStyle(fontSize: 28.sp), | |||
)) | |||
], | |||
), | |||
Row( | |||
children: <Widget>[ | |||
Text( | |||
"- ", | |||
style: TextStyle(color: Colors.red), | |||
), | |||
Text( | |||
"¥ " + modelItem['amount'], | |||
style: TextStyle(color: Colors.red, fontSize: 30.sp), | |||
) | |||
], | |||
) | |||
], | |||
), | |||
SizedBox( | |||
height: 4, | |||
), | |||
///订单编号 | |||
Row( | |||
children: <Widget>[ | |||
Text( | |||
inputItemStyle.orderIdText, | |||
style: TextStyle( | |||
color: HexColor.fromHex(inputItemStyle.contentColor), | |||
fontSize: 22.sp), | |||
), | |||
SizedBox( | |||
width: 4, | |||
), | |||
Text( | |||
modelItem['order_id'], | |||
style: TextStyle( | |||
color: HexColor.fromHex(inputItemStyle.contentColor), | |||
fontSize: 22.sp), | |||
), | |||
SizedBox( | |||
width: 28.w, | |||
), | |||
Container( | |||
decoration: BoxDecoration( | |||
borderRadius: BorderRadius.circular(4), | |||
color: HexColor.fromHex(inputItemStyle.copyBtnBgColor), | |||
border: Border.all( | |||
color: | |||
HexColor.fromHex(inputItemStyle.contentColor))), | |||
child: Padding( | |||
padding: EdgeInsets.only( | |||
left: 16, right: 16, top: 1, bottom: 1), | |||
child: Text( | |||
inputItemStyle.copyBtnText ?? "", | |||
style: TextStyle( | |||
color: | |||
HexColor.fromHex(inputItemStyle.contentColor), | |||
fontSize: 22.sp), | |||
), | |||
), | |||
) | |||
], | |||
), | |||
SizedBox( | |||
height: 4, | |||
), | |||
Row( | |||
children: <Widget>[ | |||
Expanded( | |||
child: Row( | |||
children: <Widget>[ | |||
Text( | |||
inputItemStyle.consumeOrderTypeText, | |||
style: TextStyle( | |||
color: | |||
HexColor.fromHex(inputItemStyle.contentColor), | |||
fontSize: 22.sp), | |||
), | |||
SizedBox( | |||
width: 4, | |||
), | |||
Text( | |||
modelItem['order_type'] ?? "", | |||
style: TextStyle( | |||
color: HexColor.fromHex("#FF999999"), | |||
fontSize: 22.sp), | |||
), | |||
], | |||
)), | |||
Expanded( | |||
child: Row( | |||
children: <Widget>[ | |||
Text( | |||
inputItemStyle.consumeAmountText + | |||
" ¥" + | |||
modelItem['amount'], | |||
style: TextStyle( | |||
color: | |||
HexColor.fromHex(inputItemStyle.contentColor), | |||
fontSize: 22.sp), | |||
), | |||
], | |||
)) | |||
], | |||
), | |||
SizedBox( | |||
height: 4, | |||
), | |||
Row( | |||
children: <Widget>[ | |||
Expanded( | |||
child: Row( | |||
children: <Widget>[ | |||
Text( | |||
inputItemStyle.consumeTimeText, | |||
style: TextStyle( | |||
color: | |||
HexColor.fromHex(inputItemStyle.contentColor), | |||
fontSize: 22.sp), | |||
), | |||
SizedBox( | |||
width: 4, | |||
), | |||
Text( | |||
modelItem['time'] ?? "", | |||
style: TextStyle( | |||
color: HexColor.fromHex("#FF999999"), | |||
fontSize: 22.sp), | |||
), | |||
], | |||
)), | |||
// Expanded( | |||
// child: Row( | |||
// children: <Widget>[ | |||
// Text( | |||
// inputItemStyle.consumeTimeText + | |||
// " " + | |||
// modelItem['settle_time'] ?? | |||
// "", | |||
// style: TextStyle( | |||
// color: HexColor.fromHex(inputItemStyle.contentColor), | |||
// fontSize: 22.sp), | |||
// ), | |||
// ], | |||
// )) | |||
], | |||
), | |||
], | |||
), | |||
); | |||
} else {} | |||
} | |||
} | |||
@override | |||
// TODO: implement wantKeepAlive | |||
bool get wantKeepAlive => true; | |||
} |
@@ -31,6 +31,8 @@ dependencies: | |||
flutter_native_image: ^0.0.5 | |||
#字符检测 | |||
string_validator: 0.1.4 | |||
# 列表滑动删除 | |||
flutter_slidable: 0.5.7 | |||
# image_gallery_saver: ^1.6.0 | |||
permission_handler: | |||