Weller před 4 roky
rodič
revize
3da27838b5
30 změnil soubory, kde provedl 1192 přidání a 145 odebrání
  1. +1
    -0
      lib/pages/goods_details_page/bloc/goods_details_page_repository.dart
  2. +49
    -0
      lib/pages/message_notice_page/bloc/message_notice_bloc.dart
  3. +17
    -0
      lib/pages/message_notice_page/bloc/message_notice_event.dart
  4. +45
    -0
      lib/pages/message_notice_page/bloc/message_notice_repository.dart
  5. +22
    -0
      lib/pages/message_notice_page/bloc/message_notice_state.dart
  6. +388
    -0
      lib/pages/message_notice_page/message_notice_page.dart
  7. +13
    -4
      lib/pages/team_details_page/bloc/team_details_bloc.dart
  8. +8
    -1
      lib/pages/team_details_page/bloc/team_details_event.dart
  9. +52
    -7
      lib/pages/team_details_page/bloc/team_details_repository.dart
  10. +9
    -1
      lib/pages/team_details_page/bloc/team_details_state.dart
  11. +1
    -0
      lib/pages/team_details_page/model/team_details_data_model.dart
  12. +220
    -0
      lib/pages/team_details_page/model/team_details_style_model.dart
  13. +42
    -24
      lib/pages/team_details_page/team_details_page.dart
  14. +5
    -2
      lib/pages/team_page/model/team_style_model.dart
  15. +33
    -0
      lib/pages/team_page/notifier/team_page_notifier.dart
  16. +45
    -11
      lib/pages/team_page/team_page.dart
  17. +6
    -0
      lib/register.dart
  18. +2
    -2
      lib/widgets/goods_details/price/goods_details_price_widget.dart
  19. +24
    -16
      lib/widgets/goods_details/price/model/goods_details_price_model.dart
  20. +2
    -1
      lib/widgets/home/home_slide_banner/home_slide_banner.dart
  21. +28
    -6
      lib/widgets/search/widget/text_tag_widget.dart
  22. +15
    -1
      lib/widgets/team/fans_list/bloc/team_list_fans_bloc.dart
  23. +9
    -1
      lib/widgets/team/fans_list/bloc/team_list_fans_event.dart
  24. +17
    -6
      lib/widgets/team/fans_list/bloc/team_list_fans_repository.dart
  25. +4
    -0
      lib/widgets/team/fans_list/model/team_fans_list_model.dart
  26. +3
    -1
      lib/widgets/team/fans_list/team_fans_item.dart
  27. +31
    -11
      lib/widgets/team/fans_list/team_fans_widget.dart
  28. +24
    -19
      lib/widgets/team/filter/team_filter_widget.dart
  29. +76
    -30
      lib/widgets/team/input/team_input_widget.dart
  30. +1
    -1
      lib/widgets/wallet/wallet_detail/wallet_detail.dart

+ 1
- 0
lib/pages/goods_details_page/bloc/goods_details_page_repository.dart Zobrazit soubor

@@ -81,6 +81,7 @@ class GoodsDetailsPageRepository {
List<dynamic> modLists = model['mod_list'];
for (int i = 0; i < modLists.length; i++) {
Map<String, dynamic> item = modLists[i];
// ⚠️这里之所以要判断是否是String类型,是因为修改的是父亲页面传进来的model -> data 类型了。把dynamic变成了String
Map<String, dynamic> data = item['data'] is String ? jsonDecode(item['data']) : item['data'];
Map<String, dynamic> style = jsonDecode(item['style']);
style.addAll(baseData);


+ 49
- 0
lib/pages/message_notice_page/bloc/message_notice_bloc.dart Zobrazit soubor

@@ -0,0 +1,49 @@
import 'dart:async';

import 'package:bloc/bloc.dart';
import 'package:equatable/equatable.dart';
import 'package:zhiying_base_widget/pages/message_notice_page/bloc/message_notice_repository.dart';

part 'message_notice_event.dart';

part 'message_notice_state.dart';

class MessageNoticeBloc extends Bloc<MessageNoticeEvent, MessageNoticeState> {
// MessageNoticeBloc() : super(MessageNoticeInitial());

MessageNoticeRepository repository;

MessageNoticeBloc(this.repository);

@override
MessageNoticeState get initialState => MessageNoticeInitial();

@override
Stream<MessageNoticeState> mapEventToState(
MessageNoticeEvent event,
) async* {
/// 初始化
if (event is MessageNoticeInitEvent) {
yield* _mapInitEventToState(event);
}

/// 下拉刷新
if (event is MessageNoticeOnRefreshEvent) {
yield* _mapOnRefreshEventToState(event);
}

/// 上拉更多
if (event is MessageNoticeOnLoadEvent) {
yield* _mapOnLoadEventToState(event);
}
}

/// 初始化
Stream<MessageNoticeState> _mapInitEventToState(MessageNoticeInitEvent event) async* {}

/// 下拉刷新
Stream<MessageNoticeState> _mapOnRefreshEventToState(MessageNoticeOnRefreshEvent event) async* {}

/// 上拉更多
Stream<MessageNoticeState> _mapOnLoadEventToState(MessageNoticeOnLoadEvent event) async* {}
}

+ 17
- 0
lib/pages/message_notice_page/bloc/message_notice_event.dart Zobrazit soubor

@@ -0,0 +1,17 @@
part of 'message_notice_bloc.dart';

abstract class MessageNoticeEvent extends Equatable {
const MessageNoticeEvent();

@override
List<Object> get props => [];
}

/// 初始化
class MessageNoticeInitEvent extends MessageNoticeEvent {}

/// 下拉刷新
class MessageNoticeOnRefreshEvent extends MessageNoticeEvent{}

/// 上拉更多
class MessageNoticeOnLoadEvent extends MessageNoticeEvent{}

+ 45
- 0
lib/pages/message_notice_page/bloc/message_notice_repository.dart Zobrazit soubor

@@ -0,0 +1,45 @@
import 'package:zhiying_comm/util/empty_util.dart';
import 'package:zhiying_comm/util/global_config.dart';
import 'package:zhiying_comm/util/log/let_log.dart';
import 'package:zhiying_comm/util/net_util.dart';

class MessageNoticeRepository {
final int _maxSize = 5;
int _currentPage = 1;
bool _hasMoreData = true;
List<dynamic> _oldData = [];

/// 下拉刷新
Future<dynamic> fetchRefreshData() async {
return fetchInitData();
}

/// 上拉更多
Future<dynamic> fetchLoadData() async {
if (_hasMoreData) {
return _baseRequest();
}
return null;
}

/// 数据初始化
Future<dynamic> fetchInitData() async {
_currentPage = 1;
_hasMoreData = true;
_oldData.clear();
return _baseRequest();
}

/// 基础请求
Future<dynamic> _baseRequest() async {
try {
var result = await NetUtil.post('', params: {'size': _maxSize.toString()});
if (NetUtil.isSuccess(result) && !EmptyUtil.isEmpty(result[GlobalConfig.HTTP_RESPONSE_KEY_DATA])) {
++_currentPage;
}
} catch (e, s) {
Logger.error(e, s);
}
return null;
}
}

+ 22
- 0
lib/pages/message_notice_page/bloc/message_notice_state.dart Zobrazit soubor

@@ -0,0 +1,22 @@
part of 'message_notice_bloc.dart';

abstract class MessageNoticeState extends Equatable {
const MessageNoticeState();

@override
List<Object> get props => [];
}

class MessageNoticeInitial extends MessageNoticeState {}

/// 数据加载成功
class MessageNoticeLoadedState extends MessageNoticeState {}

/// 下拉刷新失败
class MessageNoticeOnRefreshErrorState extends MessageNoticeState {}

/// 上拉更多失败
class MessageNoticeOnLoadErrorState extends MessageNoticeState {}

/// 数据初始化加载失败
class MessageNoticeErrorState extends MessageNoticeState {}

+ 388
- 0
lib/pages/message_notice_page/message_notice_page.dart Zobrazit soubor

@@ -0,0 +1,388 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:zhiying_base_widget/pages/message_notice_page/bloc/message_notice_bloc.dart';
import 'package:zhiying_base_widget/pages/message_notice_page/bloc/message_notice_repository.dart';
import 'package:zhiying_comm/zhiying_comm.dart';

///
/// 消息通知页
///
class MessageNoticePage extends StatelessWidget {
final Map<String, dynamic> data;

MessageNoticePage(this.data);

@override
Widget build(BuildContext context) {
return BlocProvider<MessageNoticeBloc>(
create: (_) => MessageNoticeBloc(MessageNoticeRepository())..add(MessageNoticeInitEvent()),
child: _MessageNoticePageContainer(),
);
}
}

class _MessageNoticePageContainer extends StatefulWidget {
@override
__MessageNoticePageContainerState createState() => __MessageNoticePageContainerState();
}

class __MessageNoticePageContainerState extends State<_MessageNoticePageContainer> {
@override
Widget build(BuildContext context) {
return _buildMainWidget();
}

/// 主视图
Widget _buildMainWidget() {
return Scaffold(
appBar: _buildAppBarWidget(),
backgroundColor: HexColor.fromHex('#F9F9F9'),
body: ListView.builder(
padding: const EdgeInsets.only(left: 12.5, right: 12.5, top: 8),
// shrinkWrap: true,
itemCount: 5,
itemBuilder: (context, index) {
return _buildOfficialActivitiesStyleWidget();
}));
}

/// 消息中心样式
Widget _buildMessageCenterStyleWidget(int index, int length) {
var borderRadius = index == 0
? BorderRadius.only(topLeft: Radius.circular(7.5), topRight: Radius.circular(7.5))
: index == length - 1 ? BorderRadius.only(bottomRight: Radius.circular(7.5), bottomLeft: Radius.circular(7.5)) : BorderRadius.only();

return Container(
decoration: BoxDecoration(color: HexColor.fromHex('#FFFFFF'), borderRadius: borderRadius),
padding: const EdgeInsets.only(left: 15, right: 15, top: 16),
child: Column(
children: <Widget>[
Container(
height: 30,
width: double.infinity,
child: Row(
children: <Widget>[
_buildCustomerAvatarWidget(),
const SizedBox(width: 10),
Expanded(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
/// 官方活动
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text('官方活动', style: TextStyle(color: HexColor.fromHex('#333333'), fontWeight: FontWeight.bold, fontSize: 13)),
Text('04-20 16:00', style: TextStyle(color: HexColor.fromHex('#D8D8D8'), fontSize: 12)),
],
),
Padding(
padding: const EdgeInsets.only(right: 22),
child: Text(
'2020年6月23日4:00至6月30日4:00关闭提现aaa',
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: TextStyle(color: HexColor.fromHex('#999999'), fontSize: 12),
),
),
],
),
)
],
),
),
Padding(padding: const EdgeInsets.only(top: 14.5), child: Divider(height: 0.5, color: HexColor.fromHex('#EFEFEF')))
],
),
);
}

/// 官方通知样式
Widget _buildOfficialNoticeStyleWidget() {
return Container(
padding: const EdgeInsets.only(left: 15, right: 15, top: 12.5, bottom: 10),
margin: const EdgeInsets.only(bottom: 7.5),
decoration: BoxDecoration(
color: HexColor.fromHex('#FFFFFF'),
borderRadius: BorderRadius.circular(7.5),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
_buildCustomerAvatarWidget(),
const SizedBox(width: 10),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
/// 标题
Text('关于关闭提现功能通知', style: TextStyle(color: HexColor.fromHex('#333333'), fontSize: 14, fontWeight: FontWeight.bold)),
const SizedBox(height: 5),

/// 内容
Text('由于微信官方的限制,我们暂时将嗨如意小程序内的提现功能进行关闭并进行维护,关闭功能时间为2020年6月23日4:00至6月30日4:00,请谅解',
maxLines: 3, overflow: TextOverflow.ellipsis, style: TextStyle(color: HexColor.fromHex('#999999'), fontSize: 11))
],
),
)
],
),

/// 时间
Padding(padding: const EdgeInsets.only(top: 16), child: Text('2020-06-23 01:00:06', style: TextStyle(color: HexColor.fromHex('#D8D8D8'), fontSize: 11)))
],
),
);
}

/// 官方活动样式
Widget _buildOfficialActivitiesStyleWidget() {
return Container(
padding: const EdgeInsets.only(left: 15, right: 15, top: 12.5, bottom: 10),
margin: const EdgeInsets.only(bottom: 7.5),
decoration: BoxDecoration(borderRadius: BorderRadius.circular(7.5), color: HexColor.fromHex('#FFFFFF')),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
/// 标题
Text(
'8.8淘宝会员节大促',
style: TextStyle(color: HexColor.fromHex('#333333'), fontWeight: FontWeight.bold, fontSize: 14),
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
const SizedBox(height: 6),

/// 图片海报
ClipRRect(
borderRadius: BorderRadius.circular(7.5),
child: CachedNetworkImage(imageUrl: 'http://ossq.izhyin.cn/index_carousel_1.png', width: double.infinity, )),
const SizedBox(height: 6.5),

/// 活动内容
Text(
'京东家电815周年庆,全场家电最低五折起,买一送一等超多优惠活动,点击查看活动详情',
maxLines: 2,
overflow: TextOverflow.ellipsis,
style: TextStyle(fontSize: 11, color: HexColor.fromHex('#999999')),
),

/// 时间
const SizedBox(height: 7),
Text('2020-06-23 01:00:06', style: TextStyle(color: HexColor.fromHex('#D8D8D8'), fontSize: 11))
],
),
);
}

/// 交易通知样式
Widget _buildTradeNoticeStyleWidget() {
return Container(
padding: const EdgeInsets.only(left: 15, right: 15, top: 12.5, bottom: 10),
margin: const EdgeInsets.only(bottom: 7.5),
decoration: BoxDecoration(
color: HexColor.fromHex('#FFFFFF'),
borderRadius: BorderRadius.circular(7.5),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
_buildCustomerAvatarWidget(),
const SizedBox(width: 10),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
/// 标题
Text('自购订单收益', style: TextStyle(color: HexColor.fromHex('#333333'), fontSize: 14, fontWeight: FontWeight.bold)),
const SizedBox(height: 5),

/// 内容
_buildCustomerTradeContentWidget(),
],
),
)
],
),

/// 时间
Padding(padding: const EdgeInsets.only(top: 16), child: Text('2020-06-23 01:00:06', style: TextStyle(color: HexColor.fromHex('#D8D8D8'), fontSize: 11)))
],
),
);
}

/// 推广通知样式
Widget _buildPromoteNoticeStyleWidget() {
return Container(
padding: const EdgeInsets.only(left: 15, right: 15, top: 12.5, bottom: 10),
margin: const EdgeInsets.only(bottom: 7.5),
decoration: BoxDecoration(
color: HexColor.fromHex('#FFFFFF'),
borderRadius: BorderRadius.circular(7.5),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
_buildCustomerAvatarWidget(),
const SizedBox(width: 10),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
/// 标题
Text('新增直推粉丝', style: TextStyle(color: HexColor.fromHex('#333333'), fontSize: 14, fontWeight: FontWeight.bold)),
const SizedBox(height: 5),

/// 内容
Text('恭喜您成功邀请152****5887加入您的团队,快带领小伙伴走向致富之路吧!',
maxLines: 3, overflow: TextOverflow.ellipsis, style: TextStyle(color: HexColor.fromHex('#999999'), fontSize: 11))
],
),
)
],
),

/// 时间
Padding(padding: const EdgeInsets.only(top: 16), child: Text('2020-06-23 01:00:06', style: TextStyle(color: HexColor.fromHex('#D8D8D8'), fontSize: 11)))
],
),
);
}

/// 反馈通知样式
Widget _buildFeedbackNoticeStyleWidget() {
return Container(
padding: const EdgeInsets.only(left: 15, right: 15, top: 14, bottom: 10),
margin: const EdgeInsets.only(bottom: 7.5),
decoration: BoxDecoration(
color: HexColor.fromHex('#FFFFFF'),
borderRadius: BorderRadius.circular(7.5),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
_buildCustomerAvatarWidget(),
const SizedBox(width: 10),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
/// 标题
Text('您的反馈有回复啦', style: TextStyle(color: HexColor.fromHex('#333333'), fontSize: 14, fontWeight: FontWeight.bold)),
const SizedBox(height: 3),
/// 内容
Text('点击查看回复详情',
maxLines: 1, overflow: TextOverflow.ellipsis, style: TextStyle(color: HexColor.fromHex('#999999'), fontSize: 11))
],
),
)
],
),

/// 时间
Padding(padding: const EdgeInsets.only(top: 16), child: Text('2020-06-23 01:00:06', style: TextStyle(color: HexColor.fromHex('#D8D8D8'), fontSize: 11)))
],
),
);
}

/// APPBar
Widget _buildAppBarWidget() {
return AppBar(
leading: IconButton(
icon: Icon(
Icons.arrow_back_ios,
size: 22,
color: HexColor.fromHex('#333333'),
),
onPressed: () => Navigator.maybePop(context),
),
title: Text(
'消息中心',
style: TextStyle(color: HexColor.fromHex('#333333'), fontSize: 15, fontWeight: FontWeight.bold),
),
centerTitle: true,
backgroundColor: HexColor.fromHex('#FFFFFF'),
elevation: 0,
);
}

/// ================================= 自定义View ================================= ///
Widget _buildCustomerAvatarWidget() {
return Container(
// width: 30,
// height: 30,
child: Stack(
alignment: AlignmentDirectional.topEnd,
// mainAxisAlignment: MainAxisAlignment.start,
// crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Container(
height: 30,
width: 30,
color: Colors.deepPurpleAccent,
),
Transform.translate(
offset: Offset(5, -4.5),
child: Container(
// width: 17,
height: 12,
padding: const EdgeInsets.only(left: 3, right: 3, top: 1, bottom: 1),
alignment: Alignment.center,
decoration:
BoxDecoration(color: HexColor.fromHex('#FF4242'), borderRadius: BorderRadius.circular(6), border: Border.all(color: HexColor.fromHex('#FFFFFF'), width: 0.5)),
child: Text(
'18',
textAlign: TextAlign.center,
style: TextStyle(fontSize: 9, color: HexColor.fromHex('#FFFFFF')),
),
),
)
],
),
);
}

Widget _buildCustomerTradeContentWidget(){
Map<String, String> datas= {
'订单编号:':'154547896541651464788',
'订单类型:':'京东',
'预估收益:': '8.00',
'下单时间:':'2020-08-14 11:35:39',
'预估结算:':'次月25日结算',
};
List<Widget> lists = [];
datas.forEach((key, value) {
lists.add(Padding(
padding: const EdgeInsets.only(bottom: 5),
child: RichText(
textAlign: TextAlign.start,
text: TextSpan(
children: [
TextSpan(text: key, style: TextStyle(fontSize: 11, color: HexColor.fromHex('#999999'))),
TextSpan(text: value, style: TextStyle(fontSize: 11, color: HexColor.fromHex('#999999'))),
]
),
),
));
});
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: lists,
);
}
}

+ 13
- 4
lib/pages/team_details_page/bloc/team_details_bloc.dart Zobrazit soubor

@@ -4,6 +4,8 @@ import 'package:bloc/bloc.dart';
import 'package:equatable/equatable.dart';
import 'package:flutter/cupertino.dart';
import 'package:zhiying_base_widget/pages/team_details_page/bloc/team_details_repository.dart';
import 'package:zhiying_base_widget/pages/team_details_page/model/team_details_data_model.dart';
import 'package:zhiying_base_widget/pages/team_details_page/model/team_details_style_model.dart';
import 'package:zhiying_comm/util/empty_util.dart';

part 'team_details_event.dart';
@@ -31,10 +33,17 @@ class TeamDetailsBloc extends Bloc<TeamDetailsEvent, TeamDetailsState> {

/// 初始化数据
Stream<TeamDetailsState> _mapInitEventToState(TeamDetailsInitEvent event) async* {
var cache = repository.fetchCacheData();
var result = repository.fetchNetData();
if (!EmptyUtil.isEmpty(result)) {
yield TeamDetailsLoadedState();
var cacheStyle = await repository.fetchCacheData();
if (!EmptyUtil.isEmpty(cacheStyle)) {
yield TeamDetailsLoadedState(styleModel: cacheStyle);
}
var resultStyle = await repository.fetchNetStyleModelData();
if (!EmptyUtil.isEmpty(resultStyle)) {
yield TeamDetailsLoadedState(styleModel: resultStyle);
}
var resultData = await repository.fetchNetData(event?.model);
if (!EmptyUtil.isEmpty(resultData) && (!EmptyUtil.isEmpty(resultStyle) || !EmptyUtil.isEmpty(cacheStyle))) {
yield TeamDetailsLoadedState(dataModel: resultData, styleModel: !EmptyUtil.isEmpty(resultStyle) ? resultStyle : cacheStyle);
} else {
yield TeamDetailsErrorState();
}


+ 8
- 1
lib/pages/team_details_page/bloc/team_details_event.dart Zobrazit soubor

@@ -2,9 +2,16 @@ part of 'team_details_bloc.dart';

abstract class TeamDetailsEvent extends Equatable {
const TeamDetailsEvent();

@override
List<Object> get props => [];
}

/// 初始化
class TeamDetailsInitEvent extends TeamDetailsEvent{}
class TeamDetailsInitEvent extends TeamDetailsEvent {
final Map<String, dynamic> model;

TeamDetailsInitEvent(this.model);
@override
List<Object> get props => [this.model];
}

+ 52
- 7
lib/pages/team_details_page/bloc/team_details_repository.dart Zobrazit soubor

@@ -1,15 +1,60 @@
import 'dart:convert';

class TeamDetailsRepository{
import 'package:zhiying_base_widget/pages/team_details_page/model/team_details_data_model.dart';
import 'package:zhiying_base_widget/pages/team_details_page/model/team_details_style_model.dart';
import 'package:zhiying_comm/zhiying_comm.dart';

class TeamDetailsRepository {
TeamDetailsStyleModel _styleModel;
TeamDetailsDataModel _dataModel;

/// 初始化数据
Future<dynamic> fetchNetData() async{
Future<dynamic> fetchNetData(final Map<String, dynamic> data) async {
try {
if (!EmptyUtil.isEmpty(data)) {
String fansId = data['uid'];
if (!EmptyUtil.isEmpty(fansId)) {
var result = await NetUtil.post('/api/v1/user/fan/$fansId', method: NetMethod.GET);
if (NetUtil.isSuccess(result) && !EmptyUtil.isEmpty(result[GlobalConfig.HTTP_RESPONSE_KEY_DATA])) {}
}
}
} catch (e, s) {
Logger.error(e, s);
}
return null;
}

/// 初始化Style数据
Future<TeamDetailsStyleModel> fetchNetStyleModelData() async {
try {
var result = await NetUtil.post('/api/v1/mod/pub.flutter.my_fan_detail', 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)) {
_styleModel = TeamDetailsStyleModel.fromJson(jsonDecode(modListData.toString()));
return _styleModel;
}
}
} catch (e, s) {
Logger.error(e, s);
}
return null;
}

/// 获取缓存数据
Future<dynamic> fetchCacheData() async{

Future<TeamDetailsStyleModel> fetchCacheData() async {
try {
var result = await NetUtil.getRequestCachedData('/api/v1/mod/pub.flutter.my_fan_detail');
if (!EmptyUtil.isEmpty(result)) {
var modListData = result['mod_list'][0]['data'];
if (!EmptyUtil.isEmpty(modListData)) {
_styleModel = TeamDetailsStyleModel.fromJson(jsonDecode(modListData.toString()));
return _styleModel;
}
}
} catch (e, s) {
Logger.error(e, s);
}
return null;
}


}
}

+ 9
- 1
lib/pages/team_details_page/bloc/team_details_state.dart Zobrazit soubor

@@ -10,7 +10,15 @@ abstract class TeamDetailsState extends Equatable {
class TeamDetailsInitial extends TeamDetailsState {}

/// 数据加载成功
class TeamDetailsLoadedState extends TeamDetailsState {}
class TeamDetailsLoadedState extends TeamDetailsState {
TeamDetailsStyleModel styleModel;
TeamDetailsDataModel dataModel;

TeamDetailsLoadedState({@required this.styleModel, this.dataModel});

@override
List<Object> get props => [this.styleModel, this.dataModel];
}

/// 数据加载失败
class TeamDetailsErrorState extends TeamDetailsState {}

+ 1
- 0
lib/pages/team_details_page/model/team_details_data_model.dart Zobrazit soubor

@@ -0,0 +1 @@
class TeamDetailsDataModel{}

+ 220
- 0
lib/pages/team_details_page/model/team_details_style_model.dart Zobrazit soubor

@@ -0,0 +1,220 @@
import 'package:zhiying_base_widget/pages/team_page/model/team_style_model.dart';
import 'package:meta/meta.dart';


@immutable
class TeamDetailsStyleModel {
String app_bar_bg_color;
String app_bar_bg_img;
String app_bar_name;
String app_bar_name_color;
String bg_color;
List<TeamDetailsStyleModelDashbord> dashbord;
List<TeamDetailsStyleModelDashbordItem> dashbord_items;
String dashbord_line_color;
TeamDetailsStyleModelHeaderReferrer header_referrer;
TeamViewItem self_info;

TeamDetailsStyleModel({
this.app_bar_bg_color,
this.app_bar_bg_img,
this.app_bar_name,
this.app_bar_name_color,
this.bg_color,
this.dashbord,
this.dashbord_items,
this.dashbord_line_color,
this.header_referrer,
this.self_info,
});

factory TeamDetailsStyleModel.fromJson(Map<String, dynamic> json) {
return TeamDetailsStyleModel(
app_bar_bg_color: json['app_bar_bg_color'],
app_bar_bg_img: json['app_bar_bg_img'],
app_bar_name: json['app_bar_name'],
app_bar_name_color: json['app_bar_name_color'],
bg_color: json['bg_color'],
dashbord: json['dashbord'] != null ? (json['dashbord'] as List).map((i) => TeamDetailsStyleModelDashbord.fromJson(i)).toList() : null,
dashbord_items: json['dashbord_items'] != null ? (json['dashbord_items'] as List).map((i) => TeamDetailsStyleModelDashbordItem.fromJson(i)).toList() : null,
dashbord_line_color: json['dashbord_line_color'],
header_referrer: json['header_referrer'] != null ? TeamDetailsStyleModelHeaderReferrer.fromJson(json['header_referrer']) : null,
self_info: json['self_info'] != null ? TeamViewItem.fromJson(json['self_info']) : null,
);
}

Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['app_bar_bg_color'] = this.app_bar_bg_color;
data['app_bar_bg_img'] = this.app_bar_bg_img;
data['app_bar_name'] = this.app_bar_name;
data['app_bar_name_color'] = this.app_bar_name_color;
data['bg_color'] = this.bg_color;
data['dashbord_line_color'] = this.dashbord_line_color;
if (this.dashbord != null) {
data['dashbord'] = this.dashbord.map((v) => v.toJson()).toList();
}
if (this.dashbord_items != null) {
data['dashbord_items'] = this.dashbord_items.map((v) => v.toJson()).toList();
}
if (this.header_referrer != null) {
data['header_referrer'] = this.header_referrer.toJson();
}
if (this.self_info != null) {
data['self_info'] = this.self_info.toJson();
}
return data;
}
}

class TeamDetailsStyleModelDashbordItem {
String bg_color;
String text_color;
String text_icon;
List<String> texts;
String title;
String title_bg_img;
String title_color;
String value_color;

TeamDetailsStyleModelDashbordItem({this.bg_color, this.text_color, this.text_icon, this.texts, this.title, this.title_bg_img, this.title_color, this.value_color});

factory TeamDetailsStyleModelDashbordItem.fromJson(Map<String, dynamic> json) {
return TeamDetailsStyleModelDashbordItem(
bg_color: json['bg_color'],
text_color: json['text_color'],
text_icon: json['text_icon'],
texts: json['texts'] != null ? new List<String>.from(json['texts']) : null,
title: json['title'],
title_bg_img: json['title_bg_img'],
title_color: json['title_color'],
value_color: json['value_color'],
);
}

Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['bg_color'] = this.bg_color;
data['text_color'] = this.text_color;
data['text_icon'] = this.text_icon;
data['title'] = this.title;
data['title_bg_img'] = this.title_bg_img;
data['title_color'] = this.title_color;
data['value_color'] = this.value_color;
if (this.texts != null) {
data['texts'] = this.texts;
}
return data;
}
}

class TeamDetailsStyleModelHeaderReferrer {
String bar_color;
String copy_btn_bg_color;
String copy_btn_icon;
String copy_btn_text;
String copy_btn_text_color;
String last_login_text;
String last_login_text_color;
String last_login_value_color;
String phone_color;
String phone_text;
String title;
String title_bg_color;
String title_bg_color_t;
String title_color;
String username_color;
String wx_color;
String wx_text;
String wx_value_color;

TeamDetailsStyleModelHeaderReferrer(
{this.bar_color,
this.copy_btn_bg_color,
this.copy_btn_icon,
this.copy_btn_text,
this.copy_btn_text_color,
this.last_login_text,
this.last_login_text_color,
this.last_login_value_color,
this.phone_color,
this.phone_text,
this.title,
this.title_bg_color,
this.title_bg_color_t,
this.title_color,
this.username_color,
this.wx_color,
this.wx_text,
this.wx_value_color});

factory TeamDetailsStyleModelHeaderReferrer.fromJson(Map<String, dynamic> json) {
return TeamDetailsStyleModelHeaderReferrer(
bar_color: json['bar_color'],
copy_btn_bg_color: json['copy_btn_bg_color'],
copy_btn_icon: json['copy_btn_icon'],
copy_btn_text: json['copy_btn_text'],
copy_btn_text_color: json['copy_btn_text_color'],
last_login_text: json['last_login_text'],
last_login_text_color: json['last_login_text_color'],
last_login_value_color: json['last_login_value_color'],
phone_color: json['phone_color'],
phone_text: json['phone_text'],
title: json['title'],
title_bg_color: json['title_bg_color'],
title_bg_color_t: json['title_bg_color_t'],
title_color: json['title_color'],
username_color: json['username_color'],
wx_color: json['wx_color'],
wx_text: json['wx_text'],
wx_value_color: json['wx_value_color'],
);
}

Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['bar_color'] = this.bar_color;
data['copy_btn_bg_color'] = this.copy_btn_bg_color;
data['copy_btn_icon'] = this.copy_btn_icon;
data['copy_btn_text'] = this.copy_btn_text;
data['copy_btn_text_color'] = this.copy_btn_text_color;
data['last_login_text'] = this.last_login_text;
data['last_login_text_color'] = this.last_login_text_color;
data['last_login_value_color'] = this.last_login_value_color;
data['phone_color'] = this.phone_color;
data['phone_text'] = this.phone_text;
data['title'] = this.title;
data['title_bg_color'] = this.title_bg_color;
data['title_bg_color_t'] = this.title_bg_color_t;
data['title_color'] = this.title_color;
data['username_color'] = this.username_color;
data['wx_color'] = this.wx_color;
data['wx_text'] = this.wx_text;
data['wx_value_color'] = this.wx_value_color;
return data;
}
}

class TeamDetailsStyleModelDashbord {
String name;
String name_color;
String name_selected_color;

TeamDetailsStyleModelDashbord({this.name, this.name_color, this.name_selected_color});

factory TeamDetailsStyleModelDashbord.fromJson(Map<String, dynamic> json) {
return TeamDetailsStyleModelDashbord(
name: json['name'],
name_color: json['name_color'],
name_selected_color: json['name_selected_color'],
);
}

Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['name'] = this.name;
data['name_color'] = this.name_color;
data['name_selected_color'] = this.name_selected_color;
return data;
}
}

+ 42
- 24
lib/pages/team_details_page/team_details_page.dart Zobrazit soubor

@@ -1,35 +1,63 @@

import 'package:flutter/material.dart';
import 'package:tab_indicator_styler/tab_indicator_styler.dart';
import 'package:zhiying_base_widget/pages/team_details_page/bloc/team_details_bloc.dart';
import 'package:zhiying_base_widget/pages/team_details_page/bloc/team_details_repository.dart';
import 'package:zhiying_base_widget/pages/team_details_page/model/team_details_data_model.dart';
import 'package:zhiying_base_widget/pages/team_details_page/model/team_details_style_model.dart';
import 'package:zhiying_base_widget/widgets/team_details/month_data/team_details_month_data_widget.dart';
import 'package:zhiying_base_widget/widgets/team_details/referrer/team_details_referrer_widget.dart';
import 'package:zhiying_comm/zhiying_comm.dart';
import 'package:zhiying_base_widget/widgets/team/fans_list/team_fans_item.dart';
import 'package:flutter_bloc/flutter_bloc.dart';

///
/// 我的团队 - 用户详情
///
class TeamDetailsPage extends StatefulWidget {

class TeamDetailsPage extends StatelessWidget {
final Map<String, dynamic> data;

TeamDetailsPage(this.data);

@override
Widget build(BuildContext context) {
return BlocProvider<TeamDetailsBloc>(
create: (_) => TeamDetailsBloc(repository: TeamDetailsRepository())..add(TeamDetailsInitEvent(data)),
child: _TeamDetailsPage(),
);
}
}

class _TeamDetailsPage extends StatefulWidget {
@override
_TeamDetailsPageState createState() => _TeamDetailsPageState();
}

class _TeamDetailsPageState extends State<TeamDetailsPage> {
class _TeamDetailsPageState extends State<_TeamDetailsPage> {
@override
Widget build(BuildContext context) {
return _getMainWidget();
return BlocConsumer<TeamDetailsBloc, TeamDetailsState>(
listener: (context, state) {},
buildWhen: (prov, current) {
return true;
},
builder: (context, state) {
if (state is TeamDetailsLoadedState) {
return _getMainWidget(state?.styleModel, state?.dataModel);
}
return _getMainWidget(null, null);
},
);
}

TabController controller = TabController(length: 2, vsync: ScrollableState());

/// 主视图
Widget _getMainWidget(){
Widget _getMainWidget(TeamDetailsStyleModel styleModel, TeamDetailsDataModel dataModel) {
return Scaffold(
backgroundColor: HexColor.fromHex('#F9F9F9'),
backgroundColor: HexColor.fromHex(styleModel?.bg_color ?? '#F9F9F9'),
body: CustomScrollView(
slivers: <Widget>[


/// 头部Bar
SliverAppBar(
// expandedHeight: 200.0,
@@ -37,16 +65,16 @@ class _TeamDetailsPageState extends State<TeamDetailsPage> {
icon: Icon(
Icons.arrow_back_ios,
size: 22,
color: HexColor.fromHex('#333333'),
color: HexColor.fromHex( '#333333'),
),
onPressed: () => Navigator.maybePop(context),
),
backgroundColor: Colors.white,
backgroundColor: HexColor.fromHex(styleModel?.app_bar_bg_color ?? '#FFFFFF'),
floating: true,
pinned: true,
title: Text(
'用户详情',
style: TextStyle(color: HexColor.fromHex('#333333'), fontWeight: FontWeight.bold, fontSize: 18),
styleModel?.app_bar_name ?? '用户详情',
style: TextStyle(color: HexColor.fromHex( styleModel?.app_bar_name_color ?? '#333333'), fontWeight: FontWeight.bold, fontSize: 18),
),
centerTitle: true,
elevation: 0,
@@ -72,15 +100,8 @@ class _TeamDetailsPageState extends State<TeamDetailsPage> {
labelStyle: TextStyle(fontSize: 15, fontWeight: FontWeight.bold),
indicatorColor: HexColor.fromHex('#F94B47'),
indicator: MaterialIndicator(
height: 2,
bottomRightRadius: 2,
bottomLeftRadius: 2,
topRightRadius: 2,
topLeftRadius: 2,
color: HexColor.fromHex('#F94B47'),
horizontalPadding: 17
),
unselectedLabelStyle: TextStyle(fontSize: 15 ),
height: 2, bottomRightRadius: 2, bottomLeftRadius: 2, topRightRadius: 2, topLeftRadius: 2, color: HexColor.fromHex('#F94B47'), horizontalPadding: 17),
unselectedLabelStyle: TextStyle(fontSize: 15),
indicatorSize: TabBarIndicatorSize.label,
labelColor: HexColor.fromHex('#000000'),
unselectedLabelColor: HexColor.fromHex('#999999'),
@@ -107,7 +128,6 @@ class _TeamDetailsPageState extends State<TeamDetailsPage> {
),

SliverPadding(padding: const EdgeInsets.only(bottom: 28))

],
),
);
@@ -115,10 +135,8 @@ class _TeamDetailsPageState extends State<TeamDetailsPage> {

/// 推荐人


/// 推荐人的信息


/// 本月数据 & 上个月数据

}

+ 5
- 2
lib/pages/team_page/model/team_style_model.dart Zobrazit soubor

@@ -1,3 +1,5 @@
import 'package:zhiying_comm/models/base/skip_model.dart';

class TeamStyleModel {
String appBarName;
String appBarNameColor;
@@ -435,7 +437,7 @@ class TeamViewItemTitleList {
}
}

class TeamViewItem {
class TeamViewItem extends SkipModel{
String lvTextColor;
String lvBgColor;
String lvBgImg;
@@ -518,6 +520,7 @@ class TeamViewItem {
this.monthEarningValueColor});

TeamViewItem.fromJson(Map<String, dynamic> json) {
super.fromJson(json);
lvTextColor = json['lv_text_color'];
lvBgColor = json['lv_bg_color'];
lvBgImg = json['lv_bg_img'];
@@ -560,7 +563,7 @@ class TeamViewItem {
}

Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
final Map<String, dynamic> data = super.toJson();
data['lv_text_color'] = this.lvTextColor;
data['lv_bg_color'] = this.lvBgColor;
data['lv_bg_img'] = this.lvBgImg;


+ 33
- 0
lib/pages/team_page/notifier/team_page_notifier.dart Zobrazit soubor

@@ -0,0 +1,33 @@
import 'package:flutter/material.dart';
import 'package:zhiying_comm/util/log/let_log.dart';

class TeamPageNotifier with ChangeNotifier {
/// taBar选中的index
int tabSelectIndex = 0;

/// 筛选的条件
Map<String, String> reqArgs = {};

/// 更新筛选条件
void updateSortCondition(String key, String args) {
reqArgs[key] = args;
Logger.log('updateSortCondition reqArgs = ${reqArgs?.toString()}');
notifyListeners();
}

/// 更新选中Index
void updateTabIndex(int index) {
print('111111');
this.tabSelectIndex = index;
}

/// 获取筛选条件
Map<String, String> getReqArgs() {
return this.reqArgs;
}

/// 获取当前选中的Tab下标
int getTabIndex() {
return this.tabSelectIndex;
}
}

+ 45
- 11
lib/pages/team_page/team_page.dart Zobrazit soubor

@@ -5,6 +5,7 @@ import 'package:zhiying_base_widget/pages/team_page/bloc/team_bloc.dart';
import 'package:zhiying_base_widget/pages/team_page/bloc/team_repository.dart';
import 'package:zhiying_base_widget/pages/team_page/model/team_data_model.dart';
import 'package:zhiying_base_widget/pages/team_page/model/team_style_model.dart';
import 'package:zhiying_base_widget/pages/team_page/notifier/team_page_notifier.dart';
import 'package:zhiying_base_widget/widgets/team/appbar/team_app_bar_widget.dart';
import 'package:zhiying_base_widget/widgets/team/data/team_data_widet.dart';
import 'package:zhiying_base_widget/widgets/team/fans_list/team_fans_widget.dart';
@@ -14,6 +15,7 @@ import 'package:zhiying_base_widget/widgets/team/recommend/team_recommend_widget
import 'package:zhiying_comm/util/custom_sliver_persistent_header_delegate.dart';
import 'package:zhiying_comm/zhiying_comm.dart';
import 'dart:ui';
import 'package:provider/provider.dart';
import 'package:flutter_bloc/flutter_bloc.dart';

import 'team_page_sk.dart';
@@ -28,9 +30,14 @@ class TeamPage extends StatelessWidget {

@override
Widget build(BuildContext context) {
return BlocProvider<TeamBloc>(
create: (_) => TeamBloc(repository: TeamRepository())..add(TeamInitEvent(data)),
child: _TeamPageContainer(),
return MultiProvider(
providers: [
ChangeNotifierProvider.value(value: TeamPageNotifier()),
],
child: BlocProvider<TeamBloc>(
create: (_) => TeamBloc(repository: TeamRepository())..add(TeamInitEvent(data)),
child: _TeamPageContainer(),
),
);
}
}
@@ -41,6 +48,16 @@ class _TeamPageContainer extends StatefulWidget {
}

class _TeamPageContainerState extends State<_TeamPageContainer> {

TabController _controller;
// TabController 监听
void _tabChangeListener(){
if (!_controller.indexIsChanging) {
Logger.log('this TabController is ${_controller?.index}');
Provider.of<TeamPageNotifier>(context, listen: false).updateTabIndex(_controller?.index ?? 0);
}
}

@override
Widget build(BuildContext context) {
return BlocConsumer<TeamBloc, TeamState>(
@@ -64,13 +81,7 @@ class _TeamPageContainerState extends State<_TeamPageContainer> {
);
}

var tabTitle = [
'全部1',
'达人1',
'超级达人',
'运营商1',
];
TabController _controller;


@override
void initState() {
@@ -81,17 +92,22 @@ class _TeamPageContainerState extends State<_TeamPageContainer> {
void _initTabController(TeamStyleModel styleModel) {
if (null == _controller) {
_controller = TabController(length: styleModel?.userLvTabs?.length ?? 0, vsync: ScrollableState());
_controller.addListener(_tabChangeListener);
}
}

@override
void dispose() {
_controller?.removeListener(_tabChangeListener);
_controller?.dispose();
super.dispose();
}

/// 主体视图
Widget _getMainWidget(TeamStyleModel styleModel, TeamDataModel dataModel) {



return Scaffold(
resizeToAvoidBottomPadding: false,
resizeToAvoidBottomInset: false,
@@ -155,12 +171,30 @@ class _TeamPageContainerState extends State<_TeamPageContainer> {
// child: TabBarView(controller: _controller, children: tabTitle.map((s) => TeamFansWidget(styleModel)).toList()),
child: TabBarView(
controller: _controller,
children: styleModel.userLvTabs.map((item) => TeamFansWidget(styleModel, item.type)).toList(),
children: _buildTabBarView(styleModel),
// children: styleModel.userLvTabs.map((item) => TeamFansWidget(styleModel, item.type, )).toList(),
),
),
),
);
}


/// 创建TabBarView
List<Widget> _buildTabBarView(TeamStyleModel styleModel){
List<Widget> lists = [];
int length = styleModel?.userLvTabs?.length ?? 0;
if(length > 0) {
for (int i = 0; i < styleModel.userLvTabs.length; i ++) {
UserLvTabs item = styleModel.userLvTabs[i];
lists.add(TeamFansWidget(styleModel, item.type, i));
}
}else{
lists.add(Container());
}
return lists;
}

}

class _SliverTabBarDelegate extends SliverPersistentHeaderDelegate {


+ 6
- 0
lib/register.dart Zobrazit soubor

@@ -18,6 +18,7 @@ import 'package:zhiying_base_widget/pages/security_page/security_mobile/security
import 'package:zhiying_base_widget/pages/security_page/security_page.dart';
import 'package:zhiying_base_widget/pages/security_page/security_password/security_password.dart';
import 'package:zhiying_base_widget/pages/setting_page/setting_page.dart';
import 'package:zhiying_base_widget/pages/team_details_page/team_details_page.dart';
import 'package:zhiying_base_widget/pages/team_page/team_page.dart';
import 'package:zhiying_base_widget/pages/webview/base_webview.dart';
import 'package:zhiying_base_widget/pages/wechat_teacher_page/wechat_teacher_page.dart';
@@ -51,6 +52,7 @@ import 'package:zhiying_base_widget/widgets/wallet/wallet_income/wallet_income.d
import 'package:zhiying_comm/util/defalut_widget_creater.dart';
import 'package:zhiying_comm/zhiying_comm.dart';

import 'pages/message_notice_page/message_notice_page.dart';
import 'pages/search_page/search_page.dart';
import 'pages/wallet_page/wallet_page.dart';
import 'widgets/goods_details/coupon/counpon_widget.dart';
@@ -144,6 +146,10 @@ class BaseWidgetRegister {

/// 我的团队
PageFactory.regist('pub.flutter.my_team', (model) => TeamPage(model));
/// 用户详情
PageFactory.regist('pub.flutter.my_fan_detail', (model) => TeamDetailsPage(model));
/// 消息中心
PageFactory.regist('pub.flutter.message_notice', (model) => MessageNoticePage(model));
}

// 注册控件


+ 2
- 2
lib/widgets/goods_details/price/goods_details_price_widget.dart Zobrazit soubor

@@ -86,8 +86,8 @@ class GoodsDetailsPriceWidget extends StatelessWidget {
Widget _getQhPriceWidget(GoodsDetailsPriceModel model) {
return Column(
children: <Widget>[
Text(model?.ticket ?? '券后', style: TextStyle(color: HexColor.fromHex(model?.ticket_color ?? '#FF4242'), fontSize: 11)),
Text('${model?.symbol}${model?.market_price}' ?? '¥ 199', style: TextStyle(color: HexColor.fromHex(model?.ticket_price_color ?? '#FF4242'), fontSize: 10, fontFamily: 'Din', package: 'zhiying_base_widget', decoration: TextDecoration.lineThrough)),
Text( model?.is_coupon == '1' ? model?.ticket ?? '券后' : model?.hand_price_text ?? '到手价', style: TextStyle(color: HexColor.fromHex(model?.ticket_color ?? '#FF4242'), fontSize: 11)),
Text('${model?.symbol}${model?.market_price}' ?? '¥ 0', style: TextStyle(color: HexColor.fromHex(model?.ticket_price_color ?? '#FF4242'), fontSize: 10, fontFamily: 'Din', package: 'zhiying_base_widget', decoration: TextDecoration.lineThrough)),
],
);
}


+ 24
- 16
lib/widgets/goods_details/price/model/goods_details_price_model.dart Zobrazit soubor

@@ -13,23 +13,27 @@ class GoodsDetailsPriceModel {
String ticket_price_color;
String price_color;
String symbol;
String hand_price_text;
String is_coupon;


GoodsDetailsPriceModel(
{this.buy_color,
this.buy_text,
this.current_price,
this.good_id,
this.market_price,
this.point,
this.points_bg_color,
this.points_color,
this.sold_count,
this.ticket,
this.ticket_color,
this.ticket_price_color,
this.price_color,
this.symbol});
GoodsDetailsPriceModel({
this.buy_color,
this.buy_text,
this.current_price,
this.good_id,
this.market_price,
this.point,
this.points_bg_color,
this.points_color,
this.sold_count,
this.ticket,
this.ticket_color,
this.ticket_price_color,
this.price_color,
this.symbol,
this.hand_price_text,
this.is_coupon,
});

factory GoodsDetailsPriceModel.fromJson(Map<String, dynamic> json) {
return GoodsDetailsPriceModel(
@@ -47,6 +51,8 @@ class GoodsDetailsPriceModel {
ticket_price_color: json['ticket_price_color'],
price_color: json['price_color'],
symbol: json['symbol'],
hand_price_text: json['hand_price_text'],
is_coupon: json['is_coupon'],
);
}

@@ -66,6 +72,8 @@ class GoodsDetailsPriceModel {
data['ticket_price_color'] = this.ticket_price_color;
data['price_color'] = this.price_color;
data['symbol'] = this.symbol;
data['hand_price_text'] = this.hand_price_text;
data['is_coupon'] = this.is_coupon;
return data;
}
}

+ 2
- 1
lib/widgets/home/home_slide_banner/home_slide_banner.dart Zobrazit soubor

@@ -5,6 +5,7 @@ import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_swiper/flutter_swiper.dart';
import 'package:provider/provider.dart';
import 'package:zhiying_base_widget/pages/main_page/notifier/main_page_bg_notifier.dart';
import 'package:zhiying_base_widget/pages/message_notice_page/message_notice_page.dart';
import 'package:zhiying_base_widget/pages/team_details_page/team_details_page.dart';
import 'package:zhiying_comm/zhiying_comm.dart';

@@ -54,7 +55,7 @@ class _HomeSlideBannerContainerState extends State<HomeSlideBannerContainer> {
// Navigator.push(context, CupertinoPageRoute(builder: (_)=> TeamPage()));

Navigator.push(
context, CupertinoPageRoute(builder: (_) => TeamDetailsPage()));
context, CupertinoPageRoute(builder: (_) => MessageNoticePage(null)));
}

@override


+ 28
- 6
lib/widgets/search/widget/text_tag_widget.dart Zobrazit soubor

@@ -1,6 +1,7 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:cached_network_image/cached_network_image.dart';
import 'package:zhiying_base_widget/widgets/home/home_quick_entry/cached_network_image_util.dart';
import 'package:zhiying_comm/util/empty_util.dart';
import 'color_utils.dart';

@@ -64,7 +65,7 @@ class _TestPageState extends State<TextTagWidget> {
@override
Widget build(BuildContext context) {

if(EmptyUtil.isEmpty(widget.icon)) {
if(EmptyUtil.isEmpty(widget?.icon)) {
return buildTag();
}else{
return buildTag();
@@ -74,12 +75,33 @@ class _TestPageState extends State<TextTagWidget> {
/// 构建按钮
Widget buildTag(){
return Container(
margin: EdgeInsets.only(right: EmptyUtil.isEmpty(widget?.icon) ? 0 : 10),
child: Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: <Widget>[
Container(
margin: widget.margin,
padding: widget.padding,
decoration: BoxDecoration(
color: widget.backgroundColor, borderRadius: BorderRadius.all(Radius.circular(widget.borderRadius)), border: Border.all(color: widget.borderColor)),
child: buildTextWidget(),
),
Visibility(
visible: !EmptyUtil.isEmpty(widget?.icon),
child: _buildIcon(),
),
],
),
);
}

margin: widget.margin,
padding: widget.padding,
decoration: BoxDecoration(
color: widget.backgroundColor, borderRadius: BorderRadius.all(Radius.circular(widget.borderRadius)), border: Border.all(color: widget.borderColor)),
child: buildTextWidget(),
Widget _buildIcon(){
return Transform.translate(
offset: Offset(10 ,-35),
child: Container(
child: CachedNetworkImage(imageUrl: widget?.icon ?? '', width: 35, height: 18,),
),
);
}



+ 15
- 1
lib/widgets/team/fans_list/bloc/team_list_fans_bloc.dart Zobrazit soubor

@@ -12,7 +12,6 @@ part 'team_list_fans_event.dart';
part 'team_list_fans_state.dart';

class TeamListFansBloc extends Bloc<TeamListFansEvent, TeamListFansState> {
// TeamListFansBloc() : super(TeamListFansInitial());

TeamListFansRepository repository;

@@ -46,6 +45,11 @@ class TeamListFansBloc extends Bloc<TeamListFansEvent, TeamListFansState> {
if (event is TeamListFansOnSortEvent) {
yield* _mapSortEventToState(event);
}

/// 整体条件筛选
if (event is TeamListFansFilterEvent) {
yield* _mapFilterEventToState(event);
}
}

/// 初始化
@@ -89,4 +93,14 @@ class TeamListFansBloc extends Bloc<TeamListFansEvent, TeamListFansState> {
yield TeamListFansErrorState();
}
}

/// 整体筛选
Stream<TeamListFansState> _mapFilterEventToState(TeamListFansFilterEvent event) async* {
var result = await repository.fetchFilter(event.args);
if (!EmptyUtil.isEmpty(result)) {
yield TeamListFansLoadedState(model: result);
} else {
yield TeamListFansErrorState();
}
}
}

+ 9
- 1
lib/widgets/team/fans_list/bloc/team_list_fans_event.dart Zobrazit soubor

@@ -23,7 +23,7 @@ class TeamListFansOnRefreshEvent extends TeamListFansEvent {}
/// 上拉更多
class TeamListFansOnLoadEevnt extends TeamListFansEvent {}

/// 排序
/// 排序(单个条件)
class TeamListFansOnSortEvent extends TeamListFansEvent {
final String key;
final String args;
@@ -33,3 +33,11 @@ class TeamListFansOnSortEvent extends TeamListFansEvent {
@override
List<Object> get props => [this.key, this.args];
}

/// 筛选(所有条件)
class TeamListFansFilterEvent extends TeamListFansEvent{
final Map<String, String > args;
const TeamListFansFilterEvent({@required this.args});
@override
List<Object> get props => [this.args];
}

+ 17
- 6
lib/widgets/team/fans_list/bloc/team_list_fans_repository.dart Zobrazit soubor

@@ -48,6 +48,15 @@ class TeamListFansRepository {
return fetchInitData();
}

/// 整体筛选排序的方法
Future<TeamFansListModel> fetchFilter(final Map<String ,String > reqArgs) async{
if(!EmptyUtil.isEmpty(reqArgs)) {
_reqArgs = reqArgs;
return fetchInitData();
}
return null;
}

/// 基础请求
Future<TeamFansListModel> _fetchBase() async {
try {
@@ -83,18 +92,20 @@ class TeamListFansRepository {
sb.write(_baseUrl);
sb.write(type);
sb.write('?');
_reqArgs[_pageKey] = _currentPage.toString();
_reqArgs[_sizeKey] = _max.toString();
_reqArgs[_pageKey] = '$_pageKey=${_currentPage.toString()}';
_reqArgs[_sizeKey] = '$_sizeKey=${_max.toString()}';

// sb.write('${_pageKey}=${_currentPage.toString()}&');
// sb.write('${_sizeKey}=${_MAX.toString()}&');

if (!EmptyUtil.isEmpty(_reqArgs)) {
_reqArgs.forEach((key, value) {
sb.write(key);
sb.write('=');
sb.write(value);
sb.write('&');
// sb.write(key);
// sb.write('=');
if(!EmptyUtil.isEmpty(value)) {
sb.write(value);
sb.write('&');
}
});
}



+ 4
- 0
lib/widgets/team/fans_list/model/team_fans_list_model.dart Zobrazit soubor

@@ -27,6 +27,7 @@ class TeamFansListModel {
}

class TeamFansListItemModel {
String uid;
String avatar;
String inviteCount;
String lastLogin;
@@ -57,6 +58,7 @@ class TeamFansListItemModel {
get blurWeChat => !EmptyUtil.isEmpty(wechat) ? wechat.length > 6 ? '${wechat.substring(0, 3)}****${wechat.substring(wechat.length - 3, wechat.length)}' : wechat : wechat;

TeamFansListItemModel({
this.uid,
this.avatar,
this.inviteCount,
this.lastLogin,
@@ -78,6 +80,7 @@ class TeamFansListItemModel {

factory TeamFansListItemModel.fromJson(Map<String, dynamic> json) {
return TeamFansListItemModel(
uid: json['uid'],
avatar: json['avatar'],
inviteCount: json['invite_count'],
lastLogin: json['last_login'],
@@ -100,6 +103,7 @@ class TeamFansListItemModel {

Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['uid'] = this.uid;
data['avatar'] = this.avatar;
data['invite_count'] = this.inviteCount;
data['last_login'] = this.lastLogin;


+ 3
- 1
lib/widgets/team/fans_list/team_fans_item.dart Zobrazit soubor

@@ -24,9 +24,11 @@ class TeamFansItem extends StatefulWidget {
class _TeamFansItemState extends State<TeamFansItem> {
/// 跳去粉丝详情
void _openFansItemDetailsPage() {
Navigator.push(context, CupertinoPageRoute(builder: (_) => TeamDetailsPage()));
// Navigator.push(context, CupertinoPageRoute(builder: (_) => TeamDetailsPage(null)));
RouterUtil.route(widget?.styleModel?.teamViewItem, widget?.dataModel?.toJson(), context);
}

/// 复制文字
void _copyText() {
Fluttertoast.showToast(msg: '复制成功~');
}


+ 31
- 11
lib/widgets/team/fans_list/team_fans_widget.dart Zobrazit soubor

@@ -3,11 +3,13 @@ import 'package:flutter/material.dart';
import 'package:pull_to_refresh/pull_to_refresh.dart';
import 'package:zhiying_base_widget/pages/team_page/model/team_style_model.dart';
import 'package:cached_network_image/cached_network_image.dart';
import 'package:zhiying_base_widget/pages/team_page/notifier/team_page_notifier.dart';
import 'package:zhiying_base_widget/widgets/team/fans_list/bloc/team_list_fans_repository.dart';
import 'package:zhiying_base_widget/widgets/team/fans_list/model/team_fans_list_model.dart';
import 'package:zhiying_comm/zhiying_comm.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:provider/provider.dart';

import 'bloc/team_list_fans_bloc.dart';
import 'team_fans_item.dart';
@@ -16,8 +18,9 @@ import 'team_fans_number_item.dart';
class TeamFansWidget extends StatefulWidget {
TeamStyleModel styleModel;
final String type;
final int tabCurrentIndex;

TeamFansWidget(this.styleModel, this.type);
TeamFansWidget(this.styleModel, this.type, this.tabCurrentIndex);

@override
_TeamFansWidgetState createState() => _TeamFansWidgetState();
@@ -28,7 +31,7 @@ class _TeamFansWidgetState extends State<TeamFansWidget> with AutomaticKeepAlive
Widget build(BuildContext context) {
return BlocProvider<TeamListFansBloc>(
create: (_) => TeamListFansBloc(TeamListFansRepository(type: widget?.type)),
child: _TeamFansWidgetContainer(widget?.styleModel),
child: _TeamFansWidgetContainer(widget?.styleModel, widget?.tabCurrentIndex),
);
}

@@ -38,8 +41,9 @@ class _TeamFansWidgetState extends State<TeamFansWidget> with AutomaticKeepAlive

class _TeamFansWidgetContainer extends StatefulWidget {
TeamStyleModel styleModel;
final int tabCurrentIndex;

_TeamFansWidgetContainer(this.styleModel);
_TeamFansWidgetContainer(this.styleModel, this.tabCurrentIndex);

@override
__TeamFansWidgetContainerState createState() => __TeamFansWidgetContainerState();
@@ -47,17 +51,20 @@ class _TeamFansWidgetContainer extends StatefulWidget {

class __TeamFansWidgetContainerState extends State<_TeamFansWidgetContainer> {
RefreshController _refreshController;
int tabSelectIndex = 0;

/// 上拉更多
void _onLoading() async {
// _refreshController.loadComplete();
BlocProvider.of<TeamListFansBloc>(context).add(TeamListFansOnLoadEevnt());
// if(widget.tabCurrentIndex == tabSelectIndex ) {
BlocProvider.of<TeamListFansBloc>(context).add(TeamListFansOnLoadEevnt());
// }
}

/// 下拉刷新
void _onRefresh() async {
// _refreshController.refreshCompleted(resetFooterState: true);
BlocProvider.of<TeamListFansBloc>(context).add(TeamListFansOnRefreshEvent());
// if(widget.tabCurrentIndex == tabSelectIndex || _refreshController.initialRefresh) {
BlocProvider.of<TeamListFansBloc>(context).add(TeamListFansOnRefreshEvent());
// }
}

@override
@@ -66,6 +73,21 @@ class __TeamFansWidgetContainerState extends State<_TeamFansWidgetContainer> {
super.initState();
}

@override
void didChangeDependencies() {
TeamPageNotifier notifier = Provider.of<TeamPageNotifier>(context);
if (null != notifier) {
tabSelectIndex = notifier?.getTabIndex() ?? 0;
Map<String, String> reqArgs = notifier?.getReqArgs() ?? null;
if(widget.tabCurrentIndex == tabSelectIndex && !EmptyUtil.isEmpty(reqArgs)) {
Logger.log('didChangeDependencies, currentTabIndex = ${widget?.tabCurrentIndex}, tabSelectIndex = $tabSelectIndex , reqArgs = ${reqArgs?.toString()}');
// _refreshController.refreshToIdle();
BlocProvider.of<TeamListFansBloc>(context).add(TeamListFansFilterEvent(args: reqArgs));
}
}
super.didChangeDependencies();
}

@override
void dispose() {
_refreshController?.dispose();
@@ -78,7 +100,6 @@ class __TeamFansWidgetContainerState extends State<_TeamFansWidgetContainer> {

return BlocConsumer<TeamListFansBloc, TeamListFansState>(
listener: (context, current) {
Logger.log('listener current current current current current $current');
if (current is TeamListFansOnLoadErrorState) {
_refreshController?.loadNoData();
}
@@ -94,12 +115,11 @@ class __TeamFansWidgetContainerState extends State<_TeamFansWidgetContainer> {
}
},
buildWhen: (prov, current) {
Logger.log('buildWhen current current current current current $current');
if (current is TeamListFansErrorState) {
if (prov is TeamListFansLoadedState) {
Fluttertoast.showToast(msg: '网络似乎开小差了~');
// Fluttertoast.showToast(msg: '网络似乎开小差了~');
}
return false;
return true;
}
// 加载更多成功
if (current is TeamListFansOnLoadSuccessState) {


+ 24
- 19
lib/widgets/team/filter/team_filter_widget.dart Zobrazit soubor

@@ -1,7 +1,9 @@
import 'package:flutter/material.dart';
import 'package:zhiying_base_widget/pages/team_page/model/team_style_model.dart';
import 'package:cached_network_image/cached_network_image.dart';
import 'package:zhiying_base_widget/pages/team_page/notifier/team_page_notifier.dart';
import 'package:zhiying_comm/zhiying_comm.dart';
import 'package:provider/provider.dart';

class TeamFilterWidget extends StatefulWidget {
TeamStyleModel styleModel;
@@ -18,6 +20,9 @@ class _TeamFilterWidgetState extends State<TeamFilterWidget> {

void _onClick(TeamViewSortList item) {
print('item selectState = ${item.selectState}');

String id = '1';
String args = '';
if (item.type != SPECIAL_TYPE) {
widget.styleModel.teamViewSortList.forEach((listItem) {
if (listItem.type != SPECIAL_TYPE && listItem.type != item.type) {
@@ -25,11 +30,17 @@ class _TeamFilterWidgetState extends State<TeamFilterWidget> {
}
});
item.updateSelectState();
setState(() {});
id = item.args[0].id;
args = item.selectState == 0 ? args : item.selectState == 1 ? item?.args[0]?.queryArgs ?? args : item.selectState == 2 ? item?.args[1]?.queryArgs ?? args : args;
} else {
item.updateSelectState();
setState(() {});
id = item.selectState == 0 ? item?.args[0]?.id ?? id : item.selectState == 1 ? item?.args[1]?.id ?? id : item.selectState == 2 ? item?.args[2]?.id ?? id : id;
args = item.selectState == 0
? item?.args[0]?.queryArgs ?? args
: item.selectState == 1 ? item?.args[1]?.queryArgs ?? args : item.selectState == 2 ? item?.args[2]?.queryArgs ?? args : args;
}
Provider.of<TeamPageNotifier>(context, listen: false).updateSortCondition(id, args);
setState(() {});
}

@override
@@ -43,20 +54,18 @@ class _TeamFilterWidgetState extends State<TeamFilterWidget> {
children: widget.styleModel.teamViewSortList.map((item) {
if (item.type != SPECIAL_TYPE) {
return _getCustomWidget(
item: item,
text: item?.name,
textColor: item.selectState == 0 ? item?.nameColor : item?.nameSelectedColor,
icon: item.selectState == 0 ? item?.icon1 : item.selectState == 1 ? item.icon2 : item.selectState == 2 ? item.icon3 : item.icon1,
isSelect: item.selectState != 0
);
item: item,
text: item?.name,
textColor: item.selectState == 0 ? item?.nameColor : item?.nameSelectedColor,
icon: item.selectState == 0 ? item?.icon1 : item.selectState == 1 ? item.icon2 : item.selectState == 2 ? item.icon3 : item.icon1,
isSelect: item.selectState != 0);
} else {
return _getCustomWidget(
item: item,
text: item.selectState == 0 ? item.args[0].name : item.selectState == 1 ? item.args[1].name : item.selectState == 2 ? item.args[2].name : item.args[0].name,
textColor: item?.nameSelectedColor,
icon: item?.icon1,
isSelect: true
);
item: item,
text: item.selectState == 0 ? item.args[0].name : item.selectState == 1 ? item.args[1].name : item.selectState == 2 ? item.args[2].name : item.args[0].name,
textColor: item?.nameSelectedColor,
icon: item?.icon1,
isSelect: true);
}
}).toList(),
),
@@ -71,11 +80,7 @@ class _TeamFilterWidgetState extends State<TeamFilterWidget> {
children: <Widget>[
Text(
text ?? '',
style: TextStyle(
fontSize: 12,
color: HexColor.fromHex(textColor),
fontWeight: isSelect ? FontWeight.bold : FontWeight.w400
),
style: TextStyle(fontSize: 12, color: HexColor.fromHex(textColor), fontWeight: isSelect ? FontWeight.bold : FontWeight.w400),
),
const SizedBox(width: 3),
CachedNetworkImage(


+ 76
- 30
lib/widgets/team/input/team_input_widget.dart Zobrazit soubor

@@ -1,12 +1,11 @@

import 'package:flutter/material.dart';
import 'package:zhiying_base_widget/pages/team_page/model/team_style_model.dart';
import 'package:cached_network_image/cached_network_image.dart';
import 'package:zhiying_comm/zhiying_comm.dart';

class TeamInputWidget extends StatefulWidget {

TeamStyleModel styleModel;

TeamInputWidget(this.styleModel);

@override
@@ -14,13 +13,33 @@ class TeamInputWidget extends StatefulWidget {
}

class _TeamInputWidgetState extends State<TeamInputWidget> {

TextEditingController _controller;
FocusNode _focusNode;
bool _showCancel = false;

/// 搜索方法
void _onSearchClick(){}
void _onSearchClick() {}

/// 点击取消输入
void _cancel() {
_controller?.clear();
}

void _onChange(text){
if(!EmptyUtil.isEmpty(text)){
if(!_showCancel){
setState(() {
_showCancel = true;
});
}
}else{
if(_showCancel) {
setState(() {
_showCancel = false;
});
}
}
}

@override
void initState() {
@@ -65,51 +84,78 @@ class _TeamInputWidgetState extends State<TeamInputWidget> {
borderRadius: BorderRadius.circular(30),
color: HexColor.fromHex(widget?.styleModel?.headerNoReferrerInputBgColor ?? '#F7F7F7'),
),
padding: const EdgeInsets.only(top: 5, bottom: 4.5, left: 7.5, right: 7.5),
// padding: const EdgeInsets.only(top: 5, bottom: 4.5, left: 7.5, right: 7.5),
width: double.infinity,
child: Row(
children: <Widget>[
// Container(width: 11.5, height: 11.5, color: Colors.red,),
/// 查询图标
Padding(
padding: const EdgeInsets.only(top: 5, bottom: 4.5, left: 7.5),
child: CachedNetworkImage(
imageUrl: widget?.styleModel?.searchBarLeftIcon,
width: 11.5,
)),

CachedNetworkImage(imageUrl: widget?.styleModel?.searchBarLeftIcon, width: 11.5,),

Expanded(child: Container(
color: Colors.transparent,
child: TextField(
controller: _controller,
focusNode: _focusNode,
style: TextStyle(fontSize: 11 , color: HexColor.fromHex(widget?.styleModel?.headerNoReferrerInputColor ?? '#000000'), textBaseline: TextBaseline.alphabetic),
decoration: InputDecoration(
focusedBorder: InputBorder.none,
border: InputBorder.none,
focusedErrorBorder: InputBorder.none,
errorBorder: InputBorder.none,
disabledBorder: InputBorder.none,
enabledBorder: InputBorder.none,
filled: true,
isDense: true,
contentPadding: const EdgeInsets.only(left: 6, bottom: 0, top: 0, right: 0),
fillColor: Colors.transparent,
hintStyle: TextStyle(fontSize: 11 , color: HexColor.fromHex(widget?.styleModel?.searchBarHideTextColor ?? '#999999'), textBaseline: TextBaseline.alphabetic),
hintText: widget?.styleModel?.searchBarHideText ?? '输入需搜索的手机号/昵称',
Expanded(
child: Container(
padding: const EdgeInsets.only(top: 5, bottom: 4.5),
color: Colors.transparent,
child: TextField(
controller: _controller,
focusNode: _focusNode,
onChanged: _onChange,
style: TextStyle(fontSize: 11, color: HexColor.fromHex(widget?.styleModel?.headerNoReferrerInputColor ?? '#000000'), textBaseline: TextBaseline.alphabetic),
decoration: InputDecoration(
focusedBorder: InputBorder.none,
border: InputBorder.none,
focusedErrorBorder: InputBorder.none,
errorBorder: InputBorder.none,
disabledBorder: InputBorder.none,
enabledBorder: InputBorder.none,
filled: true,
isDense: true,
contentPadding: const EdgeInsets.only(left: 6, bottom: 0, top: 0, right: 0),
fillColor: Colors.transparent,
hintStyle:
TextStyle(fontSize: 11, color: HexColor.fromHex(widget?.styleModel?.searchBarHideTextColor ?? '#999999'), textBaseline: TextBaseline.alphabetic),
hintText: widget?.styleModel?.searchBarHideText ?? '输入需搜索的手机号/昵称',
),
),
),
),),
),
// Container(width: 15, height: 15, color: Colors.red,)
CachedNetworkImage(imageUrl: widget?.styleModel?.searchBarRightIcon, width: 11.5,),
/// 关闭按钮
Visibility(
visible: _showCancel,
child: GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: () => _cancel(),
child: Padding(
padding: const EdgeInsets.only(top: 5, bottom: 4.5, right: 7.5),
child: CachedNetworkImage(
imageUrl: widget?.styleModel?.searchBarRightIcon,
width: 11.5,
),
)),
),
],
),
),
),
const SizedBox(width: 8),

/// 确定按钮
GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: ()=> _onSearchClick(),
onTap: () => _onSearchClick(),
child: Container(
decoration: BoxDecoration(borderRadius: BorderRadius.circular(30), color: HexColor.fromHex(widget?.styleModel?.searchBarBtnBgColor ?? '#FF4242')),
padding: const EdgeInsets.only(left: 15, right: 15, bottom: 6.5, top: 6.5),
child: Text(widget?.styleModel?.searchBarBtnText ?? '搜索', style: TextStyle(color: HexColor.fromHex(widget?.styleModel?.searchBarBtnTextColor ?? '#FFFFFF'), fontSize: 11),),
child: Text(
widget?.styleModel?.searchBarBtnText ?? '搜索',
style: TextStyle(color: HexColor.fromHex(widget?.styleModel?.searchBarBtnTextColor ?? '#FFFFFF'), fontSize: 11),
),
),
)
],


+ 1
- 1
lib/widgets/wallet/wallet_detail/wallet_detail.dart Zobrazit soubor

@@ -82,7 +82,7 @@ class _WalletDetailState extends State<WalletDetail>

///日期选择
Container(
height: 75.h,
height: 100.h,
child: ListView.builder(
padding: EdgeInsets.only(top: 16,left: 16.w),
itemCount: _model.dateList.length,


Načítá se…
Zrušit
Uložit