Weller 4 лет назад
Родитель
Сommit
9929a04d96
45 измененных файлов: 4239 добавлений и 303 удалений
  1. +28
    -186
      lib/pages/bil_detail_page/bil_detail_page.dart
  2. +3
    -2
      lib/pages/bil_detail_page/bil_detail_page_bloc.dart
  3. +0
    -22
      lib/pages/favorite_page/favorite_page.dart
  4. +0
    -17
      lib/pages/favorite_page/preview_page.dart
  5. +49
    -0
      lib/pages/favorites_page/bloc/favorites_bloc.dart
  6. +7
    -0
      lib/pages/favorites_page/bloc/favorites_event.dart
  7. +39
    -0
      lib/pages/favorites_page/bloc/favorites_repository.dart
  8. +23
    -0
      lib/pages/favorites_page/bloc/favorites_state.dart
  9. +270
    -0
      lib/pages/favorites_page/favorites_page.dart
  10. +278
    -0
      lib/pages/favorites_page/model/favorites_style_model.dart
  11. +44
    -0
      lib/pages/favorites_page/notifier/favorites_page_notifier.dart
  12. +1
    -0
      lib/pages/home_page/home_page.dart
  13. +17
    -0
      lib/pages/message_notice_page/bloc/message_notice_bloc.dart
  14. +12
    -2
      lib/pages/message_notice_page/bloc/message_notice_event.dart
  15. +15
    -0
      lib/pages/message_notice_page/bloc/message_notice_repository.dart
  16. +10
    -5
      lib/pages/message_notice_page/message_notice_page.dart
  17. +1
    -0
      lib/pages/team_details_page/team_details_page.dart
  18. +21
    -2
      lib/register.dart
  19. +75
    -0
      lib/widgets/favorites/dialog/favorites_dialog_widget.dart
  20. +188
    -0
      lib/widgets/favorites/goods_list/bloc/favorites_goods_list_bloc.dart
  21. +45
    -0
      lib/widgets/favorites/goods_list/bloc/favorites_goods_list_event.dart
  22. +177
    -0
      lib/widgets/favorites/goods_list/bloc/favorites_goods_list_repository.dart
  23. +35
    -0
      lib/widgets/favorites/goods_list/bloc/favorites_goods_list_state.dart
  24. +376
    -0
      lib/widgets/favorites/goods_list/favorites_goods_list_widget.dart
  25. +37
    -0
      lib/widgets/favorites/goods_list/model/favorites_goods_list_model.dart
  26. +13
    -8
      lib/widgets/goods_details/detail_img/goods_details_img.dart
  27. +23
    -2
      lib/widgets/goods_details/footer/bloc/goods_details_footer_bloc.dart
  28. +15
    -0
      lib/widgets/goods_details/footer/bloc/goods_details_footer_event.dart
  29. +36
    -4
      lib/widgets/goods_details/footer/bloc/goods_details_footer_repository.dart
  30. +7
    -7
      lib/widgets/goods_details/footer/bloc/goods_details_footer_state.dart
  31. +10
    -3
      lib/widgets/goods_details/footer/goods_details_footer_widget.dart
  32. +153
    -19
      lib/widgets/goods_details/footer/model/goods_details_footer_model.dart
  33. +6
    -2
      lib/widgets/home/home_goods/home_goods_item_single.dart
  34. +15
    -0
      lib/widgets/home/home_goods/models/home_goods_model.dart
  35. +9
    -8
      lib/widgets/home/home_quick_entry/home_quick_entry_widget.dart
  36. +1
    -2
      lib/widgets/home/home_slide_banner/home_slide_banner.dart
  37. +1
    -0
      lib/widgets/team/appbar/team_app_bar_widget.dart
  38. +9
    -6
      lib/widgets/team/recommend/team_recommend_widget.dart
  39. +3
    -6
      lib/widgets/wallet/wallet_bil/wallet_bil.dart
  40. +287
    -0
      lib/widgets/wallet_bil_detail/model/wallet_style_model.dart
  41. +918
    -0
      lib/widgets/wallet_bil_detail/wallet_bil_detail.dart
  42. +163
    -0
      lib/widgets/wallet_bil_detail/wallet_bil_detail_widget_bloc.dart
  43. +211
    -0
      lib/widgets/wallet_bil_detail/wallet_bil_sk.dart
  44. +606
    -0
      lib/widgets/wallet_bil_detail/wallet_list_widget.dart
  45. +2
    -0
      pubspec.yaml

+ 28
- 186
lib/pages/bil_detail_page/bil_detail_page.dart Просмотреть файл

@@ -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;
}
}

+ 3
- 2
lib/pages/bil_detail_page/bil_detail_page_bloc.dart Просмотреть файл

@@ -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) {


+ 0
- 22
lib/pages/favorite_page/favorite_page.dart Просмотреть файл

@@ -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>[],
),
);
}
}

+ 0
- 17
lib/pages/favorite_page/preview_page.dart Просмотреть файл

@@ -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,
),
);
}
}

+ 49
- 0
lib/pages/favorites_page/bloc/favorites_bloc.dart Просмотреть файл

@@ -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();
}
}
}

+ 7
- 0
lib/pages/favorites_page/bloc/favorites_event.dart Просмотреть файл

@@ -0,0 +1,7 @@
part of 'favorites_bloc.dart';

@immutable
abstract class FavoritesEvent {}

/// 初始化数据
class FavoritesInitEvent extends FavoritesEvent {}

+ 39
- 0
lib/pages/favorites_page/bloc/favorites_repository.dart Просмотреть файл

@@ -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;
}
}

+ 23
- 0
lib/pages/favorites_page/bloc/favorites_state.dart Просмотреть файл

@@ -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 {}

+ 270
- 0
lib/pages/favorites_page/favorites_page.dart Просмотреть файл

@@ -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(),
);
}
}

+ 278
- 0
lib/pages/favorites_page/model/favorites_style_model.dart Просмотреть файл

@@ -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;
}
}

+ 44
- 0
lib/pages/favorites_page/notifier/favorites_page_notifier.dart Просмотреть файл

@@ -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();
// }
}

}

+ 1
- 0
lib/pages/home_page/home_page.dart Просмотреть файл

@@ -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,


+ 17
- 0
lib/pages/message_notice_page/bloc/message_notice_bloc.dart Просмотреть файл

@@ -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();


+ 12
- 2
lib/pages/message_notice_page/bloc/message_notice_event.dart Просмотреть файл

@@ -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];
}

+ 15
- 0
lib/pages/message_notice_page/bloc/message_notice_repository.dart Просмотреть файл

@@ -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();


+ 10
- 5
lib/pages/message_notice_page/message_notice_page.dart Просмотреть файл

@@ -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')),
),


+ 1
- 0
lib/pages/team_details_page/team_details_page.dart Просмотреть файл

@@ -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,


+ 21
- 2
lib/register.dart Просмотреть файл

@@ -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',


+ 75
- 0
lib/widgets/favorites/dialog/favorites_dialog_widget.dart Просмотреть файл

@@ -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),
),
),
);
}
}

+ 188
- 0
lib/widgets/favorites/goods_list/bloc/favorites_goods_list_bloc.dart Просмотреть файл

@@ -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();
// }
// }
}

+ 45
- 0
lib/widgets/favorites/goods_list/bloc/favorites_goods_list_event.dart Просмотреть файл

@@ -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{}

+ 177
- 0
lib/widgets/favorites/goods_list/bloc/favorites_goods_list_repository.dart Просмотреть файл

@@ -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;
}
}

+ 35
- 0
lib/widgets/favorites/goods_list/bloc/favorites_goods_list_state.dart Просмотреть файл

@@ -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 {}

+ 376
- 0
lib/widgets/favorites/goods_list/favorites_goods_list_widget.dart Просмотреть файл

@@ -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();
}
}

+ 37
- 0
lib/widgets/favorites/goods_list/model/favorites_goods_list_model.dart Просмотреть файл

@@ -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;
}
}

+ 13
- 8
lib/widgets/goods_details/detail_img/goods_details_img.dart Просмотреть файл

@@ -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


+ 23
- 2
lib/widgets/goods_details/footer/bloc/goods_details_footer_bloc.dart Просмотреть файл

@@ -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();
}
}

+ 15
- 0
lib/widgets/goods_details/footer/bloc/goods_details_footer_event.dart Просмотреть файл

@@ -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];
}

+ 36
- 4
lib/widgets/goods_details/footer/bloc/goods_details_footer_repository.dart Просмотреть файл

@@ -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;
}



+ 7
- 7
lib/widgets/goods_details/footer/bloc/goods_details_footer_state.dart Просмотреть файл

@@ -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];
}

/// 数据加载出错


+ 10
- 3
lib/widgets/goods_details/footer/goods_details_footer_widget.dart Просмотреть файл

@@ -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 ?? '')))
],
);
}


+ 153
- 19
lib/widgets/goods_details/footer/model/goods_details_footer_model.dart Просмотреть файл

@@ -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;
}
}

+ 6
- 2
lib/widgets/home/home_goods/home_goods_item_single.dart Просмотреть файл

@@ -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,


+ 15
- 0
lib/widgets/home/home_goods/models/home_goods_model.dart Просмотреть файл

@@ -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;


+ 9
- 8
lib/widgets/home/home_quick_entry/home_quick_entry_widget.dart Просмотреть файл

@@ -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++) {


+ 1
- 2
lib/widgets/home/home_slide_banner/home_slide_banner.dart Просмотреть файл

@@ -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


+ 1
- 0
lib/widgets/team/appbar/team_app_bar_widget.dart Просмотреть файл

@@ -13,6 +13,7 @@ class TeamAppBarWidget extends StatelessWidget {

return SliverAppBar(
// expandedHeight: 200.0,
brightness: Brightness.light,
leading: IconButton(
icon: Icon(
Icons.arrow_back_ios,


+ 9
- 6
lib/widgets/team/recommend/team_recommend_widget.dart Просмотреть файл

@@ -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
lib/widgets/wallet/wallet_bil/wallet_bil.dart Просмотреть файл

@@ -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(


+ 287
- 0
lib/widgets/wallet_bil_detail/model/wallet_style_model.dart Просмотреть файл

@@ -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;
}
}

+ 918
- 0
lib/widgets/wallet_bil_detail/wallet_bil_detail.dart Просмотреть файл

@@ -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;
}

+ 163
- 0
lib/widgets/wallet_bil_detail/wallet_bil_detail_widget_bloc.dart Просмотреть файл

@@ -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);
}
}

+ 211
- 0
lib/widgets/wallet_bil_detail/wallet_bil_sk.dart Просмотреть файл

@@ -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,
),
],
)
],
),
);
}
}

+ 606
- 0
lib/widgets/wallet_bil_detail/wallet_list_widget.dart Просмотреть файл

@@ -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;
}

+ 2
- 0
pubspec.yaml Просмотреть файл

@@ -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:


Загрузка…
Отмена
Сохранить