Commit 55b71eff authored by 朱璇's avatar 朱璇

conflict fix

parents 2c467f3d cac886d2
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -12,4 +12,6 @@ import 'package:gm_flutter/ClueModel/ClueRouterImpl.dart'; ...@@ -12,4 +12,6 @@ import 'package:gm_flutter/ClueModel/ClueRouterImpl.dart';
abstract class ClueRouter implements RouterBaser{ abstract class ClueRouter implements RouterBaser{
Widget getLevelOnePage(); Widget getLevelOnePage();
Widget getPlanPage();
} }
\ No newline at end of file
...@@ -5,10 +5,16 @@ ...@@ -5,10 +5,16 @@
import 'package:flutter/src/widgets/framework.dart'; import 'package:flutter/src/widgets/framework.dart';
import 'package:gm_flutter/ClueModel/ClueRouter.dart'; import 'package:gm_flutter/ClueModel/ClueRouter.dart';
import 'package:gm_flutter/ClueModel/page/levelOne/LevelOnePage.dart'; import 'package:gm_flutter/ClueModel/page/levelOne/LevelOnePage.dart';
import 'package:gm_flutter/ClueModel/page/plan/PlanPage.dart';
class ClueRouterImpl implements ClueRouter { class ClueRouterImpl implements ClueRouter {
@override @override
Widget getLevelOnePage() { Widget getLevelOnePage() {
return LevelOnePage(); return LevelOnePage();
} }
@override
Widget getPlanPage() {
return PlanPage();
}
} }
...@@ -167,7 +167,7 @@ class LevelOneItem extends StatelessWidget { ...@@ -167,7 +167,7 @@ class LevelOneItem extends StatelessWidget {
Positioned( Positioned(
left: 57, left: 57,
top: 43.5, top: 43.5,
child: FiveStarView(cards.hospital.star, 5), child: FiveStarView(int.parse(cards.hospital.star), 5),
) )
], ],
), ),
......
...@@ -10,6 +10,7 @@ import 'package:gm_flutter/ClueModel/server/entity/LevelOneFeedList.dart'; ...@@ -10,6 +10,7 @@ import 'package:gm_flutter/ClueModel/server/entity/LevelOneFeedList.dart';
import 'package:gm_flutter/commonModel/GMBase.dart'; import 'package:gm_flutter/commonModel/GMBase.dart';
import 'package:gm_flutter/commonModel/bean/Pair.dart'; import 'package:gm_flutter/commonModel/bean/Pair.dart';
import 'package:gm_flutter/commonModel/rx/RxDispose.dart'; import 'package:gm_flutter/commonModel/rx/RxDispose.dart';
import 'package:gm_flutter/commonModel/util/PrintUtil.dart';
import 'package:pull_to_refresh/pull_to_refresh.dart'; import 'package:pull_to_refresh/pull_to_refresh.dart';
class LevelOneModel extends BaseModel { class LevelOneModel extends BaseModel {
...@@ -57,17 +58,19 @@ class LevelOneModel extends BaseModel { ...@@ -57,17 +58,19 @@ class LevelOneModel extends BaseModel {
cardsLive.notifyView(Pair(ENDLOADING, data)); cardsLive.notifyView(Pair(ENDLOADING, data));
}); });
// int index = currentIndex; int index = currentIndex;
// if (clear) { if (clear) {
// data.clear(); data.clear();
// pageList = [1, 1, 1, 1]; pageList = [1, 1, 1, 1];
// } }
// ClueApiImpl.getInstance() ClueApiImpl.getInstance()
// .getLevelOneList( .getLevelOneList(
// DioUtil.getInstance().getDio(), 123, list[index], pageList[index]) DioUtil.getInstance().getDio(), 123, list[index], pageList[index])
// .listen((event) {}) .listen((event) {})
// .addToDispose(rxDispose) .addToDispose(rxDispose)
// .onError((err) {}); .onError((err) {
PrintUtil.printBug(err);
});
} }
int currentIndex = 0; int currentIndex = 0;
...@@ -96,5 +99,7 @@ class LevelOneModel extends BaseModel { ...@@ -96,5 +99,7 @@ class LevelOneModel extends BaseModel {
} }
} }
void loadMore() {} void loadMore() {
}
} }
...@@ -121,6 +121,8 @@ class LevelOneState extends BaseState<LevelOnePage> ...@@ -121,6 +121,8 @@ class LevelOneState extends BaseState<LevelOnePage>
} }
}, },
))); )));
} }
Widget home() { Widget home() {
...@@ -485,7 +487,6 @@ class LevelOneState extends BaseState<LevelOnePage> ...@@ -485,7 +487,6 @@ class LevelOneState extends BaseState<LevelOnePage>
height); height);
} }
return Container( return Container(
color: Colors.yellow,
width: double.maxFinite, width: double.maxFinite,
height: height, height: height,
child: PageView.builder( child: PageView.builder(
......
/*
* @author lsy
* @date 2020/7/1
**/
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:gm_flutter/commonModel/base/BaseComponent.dart';
import 'package:gm_flutter/commonModel/util/DartUtil.dart';
class FilterView extends StatelessWidget {
final Function(int high, int low) call;
FilterView(this.call);
int min = 0;
int max = 0;
@override
Widget build(BuildContext context) {
return Container(
color: Colors.white,
height: 186,
child: Stack(
children: <Widget>[
Positioned(
top: 54.5,
right: 15,
child: baseText("无限", 12, Color(0xff3FB5AF)),
),
Positioned(
top: 54.5,
left: 15,
child: baseText("¥0", 12, Color(0xff3FB5AF)),
),
Positioned(
top: 25,
left: 15,
child: baseText("价格区间:", 13, Color(0xff666666)),
),
Positioned(
bottom: 0,
child: Container(
width: MediaQuery.of(context).size.width,
height: 44.5,
child: Row(
children: <Widget>[
Expanded(
child: Container(
child: baseText("重置", 16, Color(0xff3FB5AF)),
alignment: Alignment.center,
).gestureDetector(() {
//TODO
}),
),
Expanded(
child: Container(
color: Color(0xff3FB5AF),
alignment: Alignment.center,
child: baseText("确定", 16, Colors.white),
).gestureDetector(() {
call(max, min);
}),
)
],
),
),
)
],
),
);
}
}
/*
* @author lsy
* @date 2020-01-02
**/
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:flutter_common/flutter_common.dart';
import 'package:gm_flutter/commonModel/base/BaseComponent.dart';
class PlanBarView extends StatelessWidget {
final LiveData<List> managerLive;
final Function(int showIndex) managerListener;
final ChangeNotifier notifier;
int showIndex = -1;
List normalData = ["全部项目", "智能排序", "筛选"];
PlanBarView(this.managerLive, this.managerListener, this.notifier) {
if (!notifier?.hasListeners) {
notifier?.addListener(() {
showIndex = -1;
managerListener(-1);
managerLive.notifyView(managerLive.data ?? normalData);
});
}
}
@override
Widget build(BuildContext context) {
return managerTop(context);
}
managerTop(BuildContext context) {
return Container(
width: double.maxFinite,
height: 45,
child: StreamBuilder<List>(
stream: managerLive.stream,
initialData: managerLive.data ?? normalData,
builder: (c, data) {
if (data.data.length != 3) {
return Container();
}
return Row(
children: <Widget>[
item(data.data[0], 0),
item(data.data[1], 1),
item(data.data[2], 2),
],
);
},
));
}
Widget item(String text, int index) {
return Expanded(
child: GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: () {
if (index == showIndex) {
showIndex = -1;
} else {
showIndex = index;
}
managerListener(showIndex);
managerLive.notifyView(managerLive.data ?? normalData);
},
child: Container(
alignment: Alignment.center,
child: Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
baseText(text, 14,
index == showIndex ? Color(0xff3FB5AF) : Color(0xff666666)),
Container(
width: 10,
height: 10,
padding: EdgeInsets.only(top: 3),
alignment: Alignment.topCenter,
child: Container(
width: 6,
height: 3.5,
child: index == showIndex
? Image.asset("assets/top_arrow.png")
: Image.asset("assets/bottom_arrow.png"),
),
)
],
),
),
),
);
}
}
/*
* @author lsy
* @date 2020/7/1
**/
import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:gm_flutter/ClueModel/server/entity/PlanFeedBean.dart';
import 'package:gm_flutter/commonModel/base/BaseComponent.dart';
class PlanItem extends StatelessWidget {
final Plans plans;
PlanItem(this.plans);
@override
Widget build(BuildContext context) {
return Container(
margin: EdgeInsets.only(top: 10, left: 10, right: 10),
child: Container(
height: 90,
decoration: BoxDecoration(
color: Colors.white, borderRadius: BorderRadius.circular(4)),
child: Stack(
children: <Widget>[
Positioned(
top: 10,
left: 10,
child: Container(
width: 70,
height: 70,
child: ClipRRect(
borderRadius: BorderRadius.circular(4),
child: CachedNetworkImage(
imageUrl: "",
fit: BoxFit.cover,
),
),
),
),
Positioned(
left: 92,
top: 14,
child: Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
baseText(plans.name, 14, Color(0xff282828)),
Container(
margin: EdgeInsets.only(left: 4),
child: Container(
width: 28,
height: 15,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(2),
color: Color(0xffF0F9F7)),
alignment: Alignment.center,
child: baseText("??", 11, Color(0xff3FB5AF)),
),
)
],
),
),
Positioned(
top: 13,
right: 10,
child: Row(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.end,
children: <Widget>[
baseText("好评率", 11, Color(0xff282828)),
Container(
width: 4,
),
baseText(plans.positiveRate, 14, Color(0xffFF5963))
],
),
),
Positioned(
bottom: 14,
right: 10,
child: baseText("销量${plans.salesCount}", 11, Color(0xff282828)),
),
Positioned(
left: 91,
bottom: 14,
child: Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
baseText("¥", 10, Color(0xffFF5963)),
baseText("${plans.minPrice}-${plans.maxPrice}", 13,
Color(0xffFF5963)),
],
),
),
Positioned(
left: 92,
top: 36,
child: baseText("TODO", 11, Color(0xff999999)),
)
],
),
),
);
}
}
/*
* @author lsy
* @date 2020/6/30
**/
import 'package:flutter/foundation.dart';
import 'package:flutter_common/commonModel/live/BaseModel.dart';
import 'package:flutter_common/commonModel/live/LiveData.dart';
import 'package:flutter_common/commonModel/toast/NativeToast.dart';
import 'package:gm_flutter/ClueModel/page/plan/PlanTest.dart';
import 'package:gm_flutter/ClueModel/server/api/ClueApi.serv.dart';
import 'package:gm_flutter/ClueModel/server/entity/PlanBean.dart';
import 'package:gm_flutter/ClueModel/server/entity/PlanFeedBean.dart';
import 'package:gm_flutter/commonModel/GMBase.dart';
import 'package:gm_flutter/commonModel/bean/Pair.dart';
import 'package:gm_flutter/commonModel/rx/RxDispose.dart';
import 'package:gm_flutter/commonModel/util/PrintUtil.dart';
class PlanModel extends BaseModel {
LiveData<List> managerLive = new LiveData();
LiveData<List<double>> posLive = new LiveData();
LiveData<List<double>> backLive = new LiveData();
LiveData<List<Ranks>> picLive = LiveData();
LiveData<int> stateLive = LiveData();
double menuBottom;
int menuIndex = -1;
bool needChangBack = true;
LiveData<Pair<int, List<Plans>>> feedsLive = LiveData();
List<Plans> feedDatas = [];
List<Tags> projectData = [];
List<Orders> sortList = [];
RxDispose rxDispose = RxDispose();
String tag_id = "";
String order_by = "";
String current_city_id = "";
String min_price = "";
String max_price = "";
String rank_type = "";
int page = 1;
int sortPos = 0;
void init() {
ClueApiImpl.getInstance()
.getPlan(DioUtil.getInstance().getDio())
.listen((event) {
if (event.error == 0) {
projectData = event.data.tags;
sortList = event.data.orders;
picLive.notifyView(event.data.ranks);
stateLive.notifyView(ENDLOADING);
refreshFeed(true);
} else {
stateLive.notifyView(FAIL);
NativeToast.showNativeToast(event.message);
}
})
.addToDispose(rxDispose)
.onError((err) {
PrintUtil.printBug(err);
stateLive.notifyView(FAIL);
});
}
void projectClick(String id) {
if (tag_id == id) {
return;
}
tag_id = id;
feedsLive.notifyView(Pair(LOADING, null));
refreshFeed(true);
}
void refreshFeed(bool clear) {
if (clear) {
feedDatas.clear();
}
ClueApiImpl.getInstance()
.getPlanFeed(DioUtil.getInstance().getDio(), tag_id, order_by,
current_city_id, min_price, max_price, rank_type, page)
.listen((event) {
if (event.error == 0) {
if (event.data.plans == null || event.data.plans.isEmpty) {
feedsLive.notifyView(Pair(ENDLOADING, []));
} else {
feedDatas.addAll(event.data.plans);
feedsLive.notifyView(Pair(ENDLOADING, feedDatas));
}
} else {
NativeToast.showNativeToast(event.message);
feedsLive.notifyView(Pair(FAIL, null));
}
})
.addToDispose(rxDispose)
.onError((err) {
PrintUtil.printBug(err);
feedsLive.notifyView(Pair(FAIL, null));
});
}
@override
void dispose() {
stateLive.dispost();
picLive.dispost();
rxDispose.dispose();
managerLive.dispost();
posLive.dispost();
backLive.dispost();
feedsLive.dispost();
}
void backProgress(double pro, int index) {
if (needChangBack || menuIndex == -1) {
backLive.notifyView([0.0, menuBottom, pro]);
}
}
void loadMore() {
page++;
refreshFeed(false);
}
void sortClick(int index) {
if (index == sortPos) {
return;
}
sortPos = index;
order_by = sortList[index].id.toString();
refreshFeed(true);
}
void filterClick(int max, int min) {
if (max_price == max.toString() && min_price == min.toString()) {
return;
}
max_price = max.toString();
min_price = min.toString();
refreshFeed(true);
}
}
/*
* @author lsy
* @date 2020/6/30
**/
import 'dart:io';
import 'dart:math';
import 'dart:ui';
import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:gm_flutter/ClueModel/page/plan/FilterView.dart';
import 'package:gm_flutter/ClueModel/page/plan/PlanBar.dart';
import 'package:gm_flutter/ClueModel/page/plan/PlanItem.dart';
import 'package:gm_flutter/ClueModel/page/plan/SortView.dart';
import 'package:gm_flutter/ClueModel/server/entity/PlanBean.dart';
import 'package:gm_flutter/ClueModel/server/entity/PlanFeedBean.dart';
import 'package:gm_flutter/ClueModel/util/PosUtil.dart';
import 'package:gm_flutter/commonModel/base/BaseComponent.dart';
import 'package:gm_flutter/commonModel/base/BaseState.dart';
import 'package:gm_flutter/commonModel/bean/Pair.dart';
import 'package:gm_flutter/commonModel/popMenu/BaseMenuListener.dart';
import 'package:gm_flutter/commonModel/popMenu/BasePopMenu.dart';
import 'package:gm_flutter/commonModel/util/DartUtil.dart';
import 'package:gm_flutter/commonModel/util/WidgetUtil.dart';
import 'package:pull_to_refresh/pull_to_refresh.dart';
import 'PlanModel.dart';
import 'ProjectView.dart';
class PlanPage extends StatefulWidget {
@override
State<StatefulWidget> createState() => PlanState();
}
class PlanState extends BaseState<PlanPage> {
PlanModel _model = PlanModel();
TextEditingController _editingController = TextEditingController();
FocusNode focusNode = FocusNode();
RefreshController refreshController = RefreshController();
List<Widget> planList = List();
BaseMenuListener projectMenuListener = BaseMenuListener();
BaseMenuListener sortMenuListener = BaseMenuListener();
BaseMenuListener filterMenuListener = BaseMenuListener();
ChangeNotifier hideAllMenuListener = new ChangeNotifier();
GlobalKey globalKey = GlobalKey();
PlanBarView planBarView;
@override
void initState() {
super.initState();
_model.init();
planBarView =
PlanBarView(_model.managerLive, clickIndex, hideAllMenuListener);
planList.add(towPic());
planList.add(planBar());
planList.add(pages());
}
@override
void dispose() {
hideAllMenuListener.dispose();
projectMenuListener.dispose();
sortMenuListener.dispose();
filterMenuListener.dispose();
_model.dispose();
focusNode.dispose();
refreshController.dispose();
_editingController.dispose();
super.dispose();
}
@override
Widget buildItem(BuildContext context) {
return Scaffold(
body: MediaQuery.removePadding(
removeTop: true,
context: context,
child: SafeArea(
top: false,
child: Stack(
children: <Widget>[
Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
child: Column(
children: <Widget>[
head(),
Expanded(
child: Stack(
children: <Widget>[
Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height - 86,
child: child(),
),
StreamBuilder<List<double>>(
stream: _model.backLive.stream,
initialData: [0.0, 0.0, 0.0],
builder: (c, data) {
return Positioned(
left: 0.0,
top: 0.0,
child: Visibility(
visible: data.data[2] > 0.1,
child: Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
child: Column(
children: <Widget>[
Container(
height: data.data[1] - 45,
color: Colors.transparent,
),
Container(
height: 45,
child: Row(
children: <Widget>[
Expanded(
child: Container()
.gestureDetector(() {
clickIndexOther(0);
}),
),
Expanded(
child: Container()
.gestureDetector(() {
clickIndexOther(1);
}),
),
Expanded(
child: Container()
.gestureDetector(() {
clickIndexOther(2);
}),
),
],
),
),
Expanded(
child: Container(
color: Color.fromARGB(
(data.data[2] * 153).toInt(),
0,
0,
0),
).gestureDetector(() {
hideAllMenuListener
.notifyListeners();
}),
)
],
),
),
),
);
}),
StreamBuilder<List<double>>(
stream: _model.posLive.stream,
initialData: [0.0, 0.0],
builder: (c, data) {
return BasePopMenu(
leftPos: data.data[0],
topPos: data.data[1],
width: MediaQuery.of(context).size.width,
maxHeight: 450,
listener: projectMenuListener,
child: ProjectView(_model.projectData, (id) {
clickIndexOther(0);
_model.projectClick(id);
}),
proListener: (pro) {
_model.backProgress(pro, 0);
},
);
}),
StreamBuilder<List<double>>(
stream: _model.posLive.stream,
initialData: [0.0, 0.0],
builder: (c, data) {
return BasePopMenu(
leftPos: data.data[0],
topPos: data.data[1],
width: MediaQuery.of(context).size.width,
maxHeight: 272,
listener: sortMenuListener,
child: SortView(_model.sortList, _model.sortPos, (index) {
clickIndexOther(1);
_model.sortClick(index);
}),
proListener: (pro) {
_model.backProgress(pro, 1);
},
);
},
),
StreamBuilder<List<double>>(
stream: _model.posLive.stream,
initialData: [0.0, 0.0],
builder: (c, data) {
return BasePopMenu(
leftPos: data.data[0],
topPos: data.data[1],
width: MediaQuery.of(context).size.width,
maxHeight: 186,
listener: filterMenuListener,
child: FilterView((max, min) {
clickIndexOther(2);
_model.filterClick(max,min);
}),
proListener: (pro) {
_model.backProgress(pro, 2);
},
);
}),
],
),
)
],
),
),
StreamBuilder(
stream: _model.stateLive.stream,
initialData: _model.stateLive.data ?? LOADING,
builder: (c, data) {
if (data.data == LOADING) {
return Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
color: Colors.white,
child: loadingItem(),
);
} else if (data.data == FAIL) {
return Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
color: Colors.white,
child: errorItem(() {
_model.stateLive.notifyView(LOADING);
_model.init();
}),
);
} else {
return Container(
width: 0,
height: 0,
);
}
},
)
],
),
),
));
}
Widget head() {
return Container(
height: 86,
child: Container(
margin: EdgeInsets.only(top: 48, left: 15, right: 15),
width: double.maxFinite,
height: 32,
child: TextField(
cursorColor: Color(0xff20BDBB),
style: TextStyle(fontSize: 12, color: Color(0xff999999)),
decoration: InputDecoration(
isDense: true,
prefixIcon: Container(
child: Container(
margin: EdgeInsets.only(left: 12, right: 6),
width: 13,
height: 13,
child: Image.asset("assets/search.png"),
),
),
prefixIconConstraints:
BoxConstraints(maxWidth: 31, minWidth: 31, maxHeight: 13),
suffixIconConstraints:
BoxConstraints(maxWidth: 56.5, maxHeight: 32),
suffixIcon: Container(
decoration: BoxDecoration(
color: Color(0xff51CDC7),
borderRadius: BorderRadius.circular(16),
),
alignment: Alignment.center,
child: baseText("搜索", 14, Colors.white),
).gestureDetector(() {
//TODO
}),
contentPadding:
const EdgeInsets.symmetric(horizontal: 12.0, vertical: 10.0),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(19.5),
borderSide: BorderSide.none),
filled: true,
fillColor: Color(0xffF7F6FA),
hintStyle: TextStyle(fontSize: 12, color: Color(0xff999999)),
hintText: "切开双眼皮"),
maxLines: 1,
enableInteractiveSelection: true,
focusNode: focusNode,
autocorrect: false,
autofocus: false,
textInputAction: Platform.isAndroid
? TextInputAction.newline
: TextInputAction.send,
controller: _editingController,
minLines: null,
onEditingComplete: () {},
onSubmitted: (text) {},
),
),
);
}
Widget child() {
return baseRefreshView(
refreshController,
() {
_model.refreshFeed(true);
},
Container(
width: 0,
height: 0,
),
SliverList(
delegate: SliverChildBuilderDelegate(
(BuildContext context, int index) {
return planList[index];
},
childCount: planList.length,
),
),
onLoading: () {
_model.loadMore();
},
pullUp: true);
}
Widget towPic() {
return Container(
height: 90,
margin: EdgeInsets.only(left: 15, right: 15, top: 15, bottom: 10),
child: Row(
children: <Widget>[
Expanded(
child: Container(
child: StreamBuilder<List<Ranks>>(
stream: _model.picLive.stream,
initialData: _model.picLive.data ?? null,
builder: (c, data) {
return ClipRRect(
borderRadius: BorderRadius.circular(3),
child: CachedNetworkImage(
imageUrl:
data.data == null ? "" : data.data[0].icon ?? "",
fit: BoxFit.cover,
)).gestureDetector(() {
//TODO
});
},
),
),
),
Container(
width: 10,
),
Expanded(
child: Container(
child: StreamBuilder<List<Ranks>>(
stream: _model.picLive.stream,
initialData: _model.picLive.data ?? null,
builder: (c, data) {
return ClipRRect(
borderRadius: BorderRadius.circular(3),
child: CachedNetworkImage(
imageUrl:
data.data == null ? "" : data.data[1].icon ?? "",
fit: BoxFit.cover,
)).gestureDetector(() {
//TODO
});
},
),
),
)
],
),
);
}
Widget planBar() {
return Container(
key: globalKey,
child: planBarView,
);
}
void clickIndexOther(int index) {
if (index == planBarView.showIndex) {
planBarView.showIndex = -1;
} else {
planBarView.showIndex = index;
}
_model.managerLive
.notifyView(_model.managerLive.data ?? planBarView.normalData);
clickIndex(planBarView.showIndex);
}
void clickIndex(int index) {
double bottom =
WidgetUtil.buttonLeftMenuPosition(globalKey.currentContext).top - 86;
_model.menuBottom = bottom;
if (_model.menuIndex == index || _model.menuIndex == -1) {
_model.needChangBack = true;
} else {
_model.needChangBack = false;
}
_model.menuIndex = index;
_model.posLive.notifyView([0.0, bottom]);
if (index == -1) {
projectMenuListener.hide();
sortMenuListener.hide();
filterMenuListener.hide();
} else if (index == 0) {
projectMenuListener.show();
sortMenuListener.hide();
filterMenuListener.hide();
} else if (index == 1) {
projectMenuListener.hide();
sortMenuListener.show();
filterMenuListener.hide();
} else if (index == 2) {
projectMenuListener.hide();
sortMenuListener.hide();
filterMenuListener.show();
}
}
Widget pages() {
return StreamBuilder<Pair<int, List<Plans>>>(
stream: _model.feedsLive.stream,
initialData: _model.feedsLive.data ?? Pair(LOADING, null),
builder: (c, data) {
double height = MediaQuery.of(context).size.height - 131;
if (_model.feedDatas != null && _model.feedDatas.length > 0) {
height = max(_model.feedDatas.length * 100.0, height);
}
return Container(
width: double.maxFinite,
height: height,
child: ListView.builder(
physics: NeverScrollableScrollPhysics(),
itemBuilder: (c, index) {
if (data.data.first == FAIL) {
return errorItem(() {
_model.refreshFeed(true);
});
}
if (data.data.first == LOADING) {
return loadingItem();
}
if (data.data.second.length == 0) {
if (_model.page == 1) {
return emptyItem();
} else {
refreshController.loadNoData();
}
} else {
refreshController.loadComplete();
}
return PlanItem(_model.feedDatas[index]);
},
itemCount: _model.feedDatas.length,
));
},
);
}
}
/*
* @author lsy
* @date 2020/7/1
**/
const PLAN_TEST_JSON = """
{
"error": 0,
"message": "",
"extra": null,
"error_extra": null,
"user_type": {},
"data": {
"ranks": [
{
"name": "方案好评榜",
"gm_url": "xxxxx",
"icon": "https://heras.igengmei.com/2020/02/16/9327baec41"
},
{
"name": "热门榜",
"gm_url": "xxxxx",
"icon": "https://heras.igengmei.com/2020/02/16/9327baec41"
}
],
"areas": [
{
"is_located": true,
"name": "中国",
"groups": [
{
"is_hot": true,
"initial": "热",
"cities": [
{
"city_name": "beijing",
"id": 328,
"name": "北京"
},
{
"city_name": "shanghai",
"id": 592,
"name": "上海"
},
{
"city_name": "guangzhou",
"id": 409,
"name": "广州"
},
{
"city_name": "shenzhen",
"id": 604,
"name": "深圳"
},
{
"city_name": "chengdu",
"id": 352,
"name": "成都"
},
{
"city_name": "chongqing",
"id": 359,
"name": "重庆"
},
{
"city_name": "wuhan",
"id": 662,
"name": "武汉"
},
{
"city_name": "changsha",
"id": 343,
"name": "长沙"
},
{
"city_name": "xian",
"id": 675,
"name": "西安"
},
{
"city_name": "zhengzhou",
"id": 744,
"name": "郑州"
},
{
"city_name": "hangzhou",
"id": 425,
"name": "杭州"
},
{
"city_name": "nanjing",
"id": 542,
"name": "南京"
}
],
"title": "热门城市"
},
{
"initial": "*",
"cities": [
{
"city_name": "worldwide",
"id": "worldwide",
"name": "全部城市"
}
],
"title": "*"
},
{
"is_hot": false,
"initial": "A",
"cities": [
{
"city_name": "ankang",
"id": 304,
"name": "安康"
},
{
"city_name": "anqing",
"id": 306,
"name": "安庆"
}
],
"title": "A"
},
{
"is_hot": false,
"initial": "B",
"cities": [
{
"city_name": "baoding",
"id": 317,
"name": "保定"
},
{
"city_name": "baoji",
"id": 318,
"name": "宝鸡"
},
{
"city_name": "baotou",
"id": 321,
"name": "包头"
},
{
"city_name": "beijing",
"id": 328,
"name": "北京"
},
{
"city_name": "bengbu",
"id": 329,
"name": "蚌埠"
},
{
"city_name": "bijie",
"id": 331,
"name": "毕节"
},
{
"city_name": "bozhou",
"id": 335,
"name": "亳州"
}
],
"title": "B"
},
{
"is_hot": false,
"initial": "C",
"cities": [
{
"city_name": "cangzhou",
"id": 336,
"name": "沧州"
},
{
"city_name": "changchun",
"id": 337,
"name": "长春"
},
{
"city_name": "changsha",
"id": 343,
"name": "长沙"
},
{
"city_name": "changzhou",
"id": 347,
"name": "常州"
},
{
"city_name": "chengde",
"id": 351,
"name": "承德"
},
{
"city_name": "chengdu",
"id": 352,
"name": "成都"
},
{
"city_name": "chenzhou",
"id": 355,
"name": "郴州"
},
{
"city_name": "chongqing",
"id": 359,
"name": "重庆"
},
{
"city_name": "chuxiong",
"id": 361,
"name": "楚雄"
}
],
"title": "C"
},
{
"is_hot": false,
"initial": "D",
"cities": [
{
"city_name": "dali",
"id": 364,
"name": "大理"
},
{
"city_name": "dalian",
"id": 365,
"name": "大连"
},
{
"city_name": "dandong",
"id": 366,
"name": "丹东"
},
{
"city_name": "daqing",
"id": 369,
"name": "大庆"
},
{
"city_name": "datong",
"id": 370,
"name": "大同"
},
{
"city_name": "dazhou",
"id": 373,
"name": "达州"
},
{
"city_name": "deyang",
"id": 376,
"name": "德阳"
},
{
"city_name": "dongguan",
"id": 382,
"name": "东莞"
},
{
"city_name": "dongyang",
"id": 384,
"name": "东阳"
},
{
"city_name": "dongying",
"id": 385,
"name": "东营"
}
],
"title": "D"
},
{
"is_hot": false,
"initial": "E",
"cities": [
{
"city_name": "enshi",
"id": 387,
"name": "恩施"
}
],
"title": "E"
},
{
"is_hot": false,
"initial": "F",
"cities": [
{
"city_name": "foshan",
"id": 395,
"name": "佛山"
},
{
"city_name": "fuyang",
"id": 399,
"name": "阜阳"
},
{
"city_name": "fuzhou",
"id": 400,
"name": "福州"
}
],
"title": "F"
},
{
"is_hot": false,
"initial": "G",
"cities": [
{
"city_name": "ganzhou",
"id": 403,
"name": "赣州"
},
{
"city_name": "guangzhou",
"id": 409,
"name": "广州"
},
{
"city_name": "guilin",
"id": 411,
"name": "桂林"
},
{
"city_name": "guiyang",
"id": 412,
"name": "贵阳"
}
],
"title": "G"
},
{
"is_hot": false,
"initial": "H",
"cities": [
{
"city_name": "haerbin",
"id": 415,
"name": "哈尔滨"
},
{
"city_name": "haikou",
"id": 419,
"name": "海口"
},
{
"city_name": "handan",
"id": 423,
"name": "邯郸"
},
{
"city_name": "hangzhou",
"id": 425,
"name": "杭州"
},
{
"city_name": "hefei",
"id": 430,
"name": "合肥"
},
{
"city_name": "hengshui",
"id": 434,
"name": "衡水"
},
{
"city_name": "hengyang",
"id": 435,
"name": "衡阳"
},
{
"city_name": "heyuan",
"id": 437,
"name": "河源"
},
{
"city_name": "huaian",
"id": 441,
"name": "淮安"
},
{
"city_name": "huaibei",
"id": 442,
"name": "淮北"
},
{
"city_name": "huangshan",
"id": 449,
"name": "黄山"
},
{
"city_name": "huangshi",
"id": 450,
"name": "黄石"
},
{
"city_name": "huhehaote",
"id": 451,
"name": "呼和浩特"
},
{
"city_name": "huizhou",
"id": 452,
"name": "惠州"
},
{
"city_name": "huludao",
"id": 453,
"name": "葫芦岛"
},
{
"city_name": "huzhou",
"id": 455,
"name": "湖州"
}
],
"title": "H"
},
{
"is_hot": false,
"initial": "J",
"cities": [
{
"city_name": "jiamusi",
"id": 457,
"name": "佳木斯"
},
{
"city_name": "jian",
"id": 458,
"name": "吉安"
},
{
"city_name": "jiangmen",
"id": 460,
"name": "江门"
},
{
"city_name": "jiaozuo",
"id": 462,
"name": "焦作"
},
{
"city_name": "jiaxing",
"id": 463,
"name": "嘉兴"
},
{
"city_name": "jilin1",
"id": 467,
"name": "吉林"
},
{
"city_name": "jinan",
"id": 468,
"name": "济南"
},
{
"city_name": "jingzhou",
"id": 474,
"name": "荆州"
},
{
"city_name": "jinhua",
"id": 475,
"name": "金华"
},
{
"city_name": "jining",
"id": 476,
"name": "济宁"
},
{
"city_name": "jinzhong",
"id": 479,
"name": "晋中"
},
{
"city_name": "jinzhou",
"id": 480,
"name": "锦州"
}
],
"title": "J"
},
{
"is_hot": false,
"initial": "K",
"cities": [
{
"city_name": "kunming",
"id": 493,
"name": "昆明"
}
],
"title": "K"
},
{
"is_hot": false,
"initial": "L",
"cities": [
{
"city_name": "langfang",
"id": 497,
"name": "廊坊"
},
{
"city_name": "lanzhou",
"id": 498,
"name": "兰州"
},
{
"city_name": "lasa",
"id": 499,
"name": "拉萨"
},
{
"city_name": "leshan",
"id": 501,
"name": "乐山"
},
{
"city_name": "lianyungang",
"id": 504,
"name": "连云港"
},
{
"city_name": "linyi",
"id": 514,
"name": "临沂"
},
{
"city_name": "liupanshui",
"id": 518,
"name": "六盘水"
},
{
"city_name": "liuzhou",
"id": 519,
"name": "柳州"
},
{
"city_name": "luohe",
"id": 524,
"name": "漯河"
},
{
"city_name": "luoyang",
"id": 525,
"name": "洛阳"
},
{
"city_name": "luzhou",
"id": 526,
"name": "泸州"
}
],
"title": "L"
},
{
"is_hot": false,
"initial": "M",
"cities": [
{
"city_name": "maoming",
"id": 529,
"name": "茂名"
},
{
"city_name": "meishan",
"id": 530,
"name": "眉山"
},
{
"city_name": "mianyang",
"id": 533,
"name": "绵阳"
}
],
"title": "M"
},
{
"is_hot": false,
"initial": "N",
"cities": [
{
"city_name": "nanchang",
"id": 538,
"name": "南昌"
},
{
"city_name": "nanchong",
"id": 539,
"name": "南充"
},
{
"city_name": "nanjing",
"id": 542,
"name": "南京"
},
{
"city_name": "nanning",
"id": 543,
"name": "南宁"
},
{
"city_name": "nantong",
"id": 545,
"name": "南通"
},
{
"city_name": "nanyang",
"id": 547,
"name": "南阳"
},
{
"city_name": "neijiang",
"id": 549,
"name": "内江"
},
{
"city_name": "ningbo",
"id": 550,
"name": "宁波"
}
],
"title": "N"
},
{
"is_hot": false,
"initial": "P",
"cities": [
{
"city_name": "panzhihua",
"id": 555,
"name": "攀枝花"
},
{
"city_name": "putian",
"id": 564,
"name": "莆田"
},
{
"city_name": "puyang",
"id": 565,
"name": "濮阳"
}
],
"title": "P"
},
{
"is_hot": false,
"initial": "Q",
"cities": [
{
"city_name": "qingdao",
"id": 572,
"name": "青岛"
},
{
"city_name": "qingyuan",
"id": 575,
"name": "清远"
},
{
"city_name": "qinhuangdao",
"id": 576,
"name": "秦皇岛"
},
{
"city_name": "qiqihaer",
"id": 580,
"name": "齐齐哈尔"
},
{
"city_name": "quanzhou",
"id": 582,
"name": "泉州"
},
{
"city_name": "qujing",
"id": 583,
"name": "曲靖"
}
],
"title": "Q"
},
{
"is_hot": false,
"initial": "R",
"cities": [
{
"city_name": "rizhao",
"id": 586,
"name": "日照"
}
],
"title": "R"
},
{
"is_hot": false,
"initial": "S",
"cities": [
{
"city_name": "sanya",
"id": 591,
"name": "三亚"
},
{
"city_name": "shanghai",
"id": 592,
"name": "上海"
},
{
"city_name": "shangqiu",
"id": 594,
"name": "商丘"
},
{
"city_name": "shangrao",
"id": 595,
"name": "上饶"
},
{
"city_name": "shantou",
"id": 597,
"name": "汕头"
},
{
"city_name": "shaoguan",
"id": 599,
"name": "韶关"
},
{
"city_name": "shaoxing",
"id": 600,
"name": "绍兴"
},
{
"city_name": "shaoyang",
"id": 601,
"name": "邵阳"
},
{
"city_name": "shengzhou",
"id": 7401,
"name": "嵊州"
},
{
"city_name": "shenyang",
"id": 603,
"name": "沈阳"
},
{
"city_name": "shenzhen",
"id": 604,
"name": "深圳"
},
{
"city_name": "shijiazhuang",
"id": 606,
"name": "石家庄"
},
{
"city_name": "suining",
"id": 620,
"name": "遂宁"
},
{
"city_name": "suizhou",
"id": 621,
"name": "随州"
},
{
"city_name": "suzhou",
"id": 623,
"name": "苏州"
}
],
"title": "S"
},
{
"is_hot": false,
"initial": "T",
"cities": [
{
"city_name": "taian",
"id": 626,
"name": "泰安"
},
{
"city_name": "taiyuan",
"id": 631,
"name": "太原"
},
{
"city_name": "taizhou",
"id": 633,
"name": "泰州"
},
{
"city_name": "taizhou1",
"id": 634,
"name": "台州"
},
{
"city_name": "tangshan",
"id": 636,
"name": "唐山"
},
{
"city_name": "tianjin",
"id": 638,
"name": "天津"
},
{
"city_name": "tongren",
"id": 648,
"name": "铜仁"
}
],
"title": "T"
},
{
"is_hot": false,
"initial": "W",
"cities": [
{
"city_name": "weifang",
"id": 655,
"name": "潍坊"
},
{
"city_name": "weihai",
"id": 656,
"name": "威海"
},
{
"city_name": "weinan",
"id": 657,
"name": "渭南"
},
{
"city_name": "wenzhou",
"id": 660,
"name": "温州"
},
{
"city_name": "wuhan",
"id": 662,
"name": "武汉"
},
{
"city_name": "wuhu",
"id": 663,
"name": "芜湖"
},
{
"city_name": "wulumuqi",
"id": 666,
"name": "乌鲁木齐"
},
{
"city_name": "wuwei",
"id": 669,
"name": "武威"
},
{
"city_name": "wuxi",
"id": 670,
"name": "无锡"
}
],
"title": "W"
},
{
"is_hot": false,
"initial": "X",
"cities": [
{
"city_name": "xiamen",
"id": 674,
"name": "厦门"
},
{
"city_name": "xian",
"id": 675,
"name": "西安"
},
{
"city_name": "xiangtan",
"id": 678,
"name": "湘潭"
},
{
"city_name": "xiangyang",
"id": 676,
"name": "襄阳"
},
{
"city_name": "xianyang",
"id": 682,
"name": "咸阳"
},
{
"city_name": "xingtai",
"id": 686,
"name": "邢台"
},
{
"city_name": "xining",
"id": 687,
"name": "西宁"
},
{
"city_name": "xinxiang",
"id": 689,
"name": "新乡"
},
{
"city_name": "xishuangbanna",
"id": 695,
"name": "西双版纳"
},
{
"city_name": "xuzhou",
"id": 699,
"name": "徐州"
}
],
"title": "X"
},
{
"is_hot": false,
"initial": "Y",
"cities": [
{
"city_name": "yancheng",
"id": 703,
"name": "盐城"
},
{
"city_name": "yangzhou",
"id": 706,
"name": "扬州"
},
{
"city_name": "yantai",
"id": 709,
"name": "烟台"
},
{
"city_name": "yibin",
"id": 710,
"name": "宜宾"
},
{
"city_name": "yichang",
"id": 711,
"name": "宜昌"
},
{
"city_name": "yinchuan",
"id": 716,
"name": "银川"
},
{
"city_name": "yingtan",
"id": 718,
"name": "鹰潭"
},
{
"city_name": "yiwu",
"id": 297,
"name": "义乌"
},
{
"city_name": "yiyang",
"id": 719,
"name": "益阳"
},
{
"city_name": "yuncheng",
"id": 727,
"name": "运城"
},
{
"city_name": "yuxi",
"id": 732,
"name": "玉溪"
}
],
"title": "Y"
},
{
"is_hot": false,
"initial": "Z",
"cities": [
{
"city_name": "zaozhuang",
"id": 733,
"name": "枣庄"
},
{
"city_name": "zhangjiakou",
"id": 737,
"name": "张家口"
},
{
"city_name": "zhanjiang",
"id": 741,
"name": "湛江"
},
{
"city_name": "zhaoqing",
"id": 742,
"name": "肇庆"
},
{
"city_name": "zhengzhou",
"id": 744,
"name": "郑州"
},
{
"city_name": "zhenjiang",
"id": 745,
"name": "镇江"
},
{
"city_name": "zhongshan",
"id": 746,
"name": "中山"
},
{
"city_name": "zhoukou",
"id": 749,
"name": "周口"
},
{
"city_name": "zhoushan",
"id": 750,
"name": "舟山"
},
{
"city_name": "zhuhai",
"id": 751,
"name": "珠海"
},
{
"city_name": "zhumadian",
"id": 752,
"name": "驻马店"
},
{
"city_name": "zhuzhou",
"id": 753,
"name": "株洲"
},
{
"city_name": "zibo",
"id": 754,
"name": "淄博"
},
{
"city_name": "zunyi",
"id": 757,
"name": "遵义"
}
],
"title": "Z"
}
]
},
{
"is_located": false,
"name": "国际/港澳台",
"groups": [
{
"is_hot": true,
"initial": "热",
"cities": [
{
"city_name": "shouer",
"id": 612,
"name": "首尔"
},
{
"city_name": "dongjing",
"id": 2669,
"name": "东京"
},
{
"city_name": "mangu",
"id": 3936,
"name": "曼谷"
},
{
"city_name": "jizhoushi",
"id": 2536,
"name": "济州岛"
},
{
"city_name": "xianggangdao",
"id": 677,
"name": "香港"
}
],
"title": "热门城市"
},
{
"initial": "*",
"cities": [
{
"city_name": "worldwide",
"id": "worldwide",
"name": "全部城市"
}
],
"title": "*"
},
{
"is_hot": false,
"initial": "D",
"cities": [
{
"city_name": "dongjing",
"id": 2669,
"name": "东京"
}
],
"title": "D"
},
{
"is_hot": false,
"initial": "J",
"cities": [
{
"city_name": "jizhoushi",
"id": 2536,
"name": "济州岛"
}
],
"title": "J"
},
{
"is_hot": false,
"initial": "M",
"cities": [
{
"city_name": "mangu",
"id": 3936,
"name": "曼谷"
}
],
"title": "M"
},
{
"is_hot": false,
"initial": "S",
"cities": [
{
"city_name": "shouer",
"id": 612,
"name": "首尔"
}
],
"title": "S"
},
{
"is_hot": false,
"initial": "T",
"cities": [
{
"city_name": "taibei",
"id": 627,
"name": "台北"
}
],
"title": "T"
},
{
"is_hot": false,
"initial": "X",
"cities": [
{
"city_name": "xianggangdao",
"id": 677,
"name": "中国香港"
}
],
"title": "X"
}
]
}
],
"tags": [
{
"id": "all",
"sub_tags": [
{
"id": "all",
"name": "全部项目"
}
],
"name": "全部项目"
},
{
"name": "眼部整形",
"sub_tags": [
{
"id": 1,
"name": "全部眼部整形"
},
{
"id": 15,
"name": "双眼皮"
},
{
"id": 16,
"name": "填充泪沟"
},
{
"id": 17,
"name": "开眼角"
},
{
"id": 18,
"name": "祛眼袋"
},
{
"id": 19,
"name": "祛黑眼圈"
},
{
"id": 63,
"name": "填充卧蚕"
},
{
"id": 64,
"name": "眼部修复"
},
{
"id": 884,
"name": "垫眉弓"
},
{
"id": 975,
"name": "眼睑"
},
{
"id": 3459,
"name": "眼部综合"
}
]
},
{
"name": "鼻部整形",
"sub_tags": [
{
"id": 2,
"name": "全部鼻部整形"
},
{
"id": 21,
"name": "隆鼻"
},
{
"id": 24,
"name": "鼻翼"
},
{
"id": 26,
"name": "鼻形矫正"
},
{
"id": 65,
"name": "鼻部修复"
},
{
"id": 896,
"name": "鼻基底"
},
{
"id": 3285,
"name": "鼻部综合"
}
]
},
{
"name": "轮廓骨骼",
"sub_tags": [
{
"id": 3,
"name": "全部轮廓骨骼"
},
{
"id": 28,
"name": "颧骨"
},
{
"id": 29,
"name": "额头"
},
{
"id": 30,
"name": "太阳穴"
},
{
"id": 45,
"name": "面颊"
},
{
"id": 46,
"name": "下巴"
},
{
"id": 81,
"name": "轮廓修复"
},
{
"id": 235,
"name": "下颌角切除术"
},
{
"id": 766,
"name": "祛颊脂垫"
},
{
"id": 812,
"name": "V-line瓜子脸手术"
},
{
"id": 898,
"name": "咬肌切除"
},
{
"id": 900,
"name": "两颚"
},
{
"id": 1136,
"name": "磨骨"
},
{
"id": 1233,
"name": "自体脂肪填充面部"
},
{
"id": 3047,
"name": "假体填充"
},
{
"id": 5060,
"name": "轮廓套餐"
},
{
"id": 6150,
"name": "手术套餐"
}
]
},
{
"name": "瘦身美体",
"sub_tags": [
{
"id": 4,
"name": "全部瘦身美体"
},
{
"id": 32,
"name": "腰腹"
},
{
"id": 33,
"name": "臀部"
},
{
"id": 38,
"name": "溶脂"
},
{
"id": 72,
"name": "中医减肥"
},
{
"id": 84,
"name": "手臂"
},
{
"id": 221,
"name": "吸脂"
},
{
"id": 892,
"name": "大腿"
},
{
"id": 893,
"name": "小腿"
},
{
"id": 894,
"name": "肩背"
},
{
"id": 5061,
"name": "瘦身套餐"
}
]
},
{
"name": "皮肤美容",
"sub_tags": [
{
"id": 5,
"name": "全部皮肤美容"
},
{
"id": 34,
"name": "祛痘祛痘印"
},
{
"id": 35,
"name": "祛斑"
},
{
"id": 41,
"name": "改善肤质"
},
{
"id": 47,
"name": "美白嫩肤"
},
{
"id": 60,
"name": "祛纹身"
},
{
"id": 78,
"name": "祛红血丝"
},
{
"id": 1387,
"name": "清洁补水"
},
{
"id": 1992,
"name": "祛痣"
},
{
"id": 2942,
"name": "祛疤"
}
]
},
{
"name": "胸部塑身",
"sub_tags": [
{
"id": 7,
"name": "全部胸部塑身"
},
{
"id": 66,
"name": "丰胸(隆胸)"
},
{
"id": 67,
"name": "乳头乳晕"
},
{
"id": 68,
"name": "副乳"
},
{
"id": 69,
"name": "胸部形态重塑"
},
{
"id": 70,
"name": "胸部修复"
},
{
"id": 5724,
"name": "胸部提升"
},
{
"id": 6144,
"name": "胸部套餐"
}
]
},
{
"name": "毛发管理",
"sub_tags": [
{
"id": 9,
"name": "全部毛发管理"
},
{
"id": 80,
"name": "毛发其他"
},
{
"id": 865,
"name": "药物脱毛"
},
{
"id": 983,
"name": "毛发移植"
},
{
"id": 2663,
"name": "激光脱毛"
},
{
"id": 2947,
"name": "光子脱毛"
}
]
},
{
"name": "私密整形",
"sub_tags": [
{
"id": 10,
"name": "全部私密整形"
},
{
"id": 955,
"name": "女性私密"
},
{
"id": 956,
"name": "男性私密"
}
]
},
{
"name": "牙齿美容",
"sub_tags": [
{
"id": 11,
"name": "全部牙齿美容"
},
{
"id": 53,
"name": "牙齿整形"
},
{
"id": 55,
"name": "美容冠"
},
{
"id": 154,
"name": "牙齿矫正"
},
{
"id": 155,
"name": "牙齿美白"
},
{
"id": 156,
"name": "烤瓷牙"
},
{
"id": 157,
"name": "洗牙"
},
{
"id": 158,
"name": "补牙"
},
{
"id": 159,
"name": "种植牙"
},
{
"id": 852,
"name": "拔牙"
},
{
"id": 2458,
"name": "瓷贴面"
}
]
},
{
"name": "口唇整形",
"sub_tags": [
{
"id": 12,
"name": "全部口唇整形"
},
{
"id": 31,
"name": "酒窝"
},
{
"id": 52,
"name": "丰唇"
},
{
"id": 903,
"name": "嘴角上提"
},
{
"id": 904,
"name": "厚唇"
},
{
"id": 907,
"name": "唇形"
}
]
},
{
"name": "抗衰紧致",
"sub_tags": [
{
"id": 922,
"name": "全部抗衰紧致"
},
{
"id": 62,
"name": "颈部"
},
{
"id": 79,
"name": "除皱"
},
{
"id": 933,
"name": "自体脂肪面部年轻化"
},
{
"id": 4422,
"name": "祛皱"
}
]
},
{
"name": "注射美容",
"sub_tags": [
{
"id": 992,
"name": "全部注射美容"
},
{
"id": 82,
"name": "微整修复"
},
{
"id": 1055,
"name": "玻尿酸注射"
},
{
"id": 2033,
"name": "瘦脸除皱"
},
{
"id": 3042,
"name": "胶原蛋白注射"
},
{
"id": 3044,
"name": "少女针"
},
{
"id": 3046,
"name": "童颜针"
},
{
"id": 5078,
"name": "微整套餐"
},
{
"id": 6147,
"name": "注射美肤"
}
]
},
{
"name": "自体脂肪",
"sub_tags": [
{
"id": 1024,
"name": "全部自体脂肪"
},
{
"id": 2112,
"name": "面部填充"
},
{
"id": 6102,
"name": "身体塑形"
},
{
"id": 7117,
"name": "脂肪其他"
}
]
},
{
"name": "半永久",
"sub_tags": [
{
"id": 1080,
"name": "全部半永久"
},
{
"id": 1370,
"name": "韩式半永久纹眉"
},
{
"id": 2054,
"name": "半永久妆"
},
{
"id": 2055,
"name": "韩式半永久飘眉"
},
{
"id": 2056,
"name": "韩式半永久雾眉"
},
{
"id": 2057,
"name": "韩式半永久纹眼线(美瞳线)"
},
{
"id": 2058,
"name": "韩式半永久漂唇"
},
{
"id": 2954,
"name": "韩式半永久纹发际线"
},
{
"id": 5079,
"name": "韩式半永久套餐"
},
{
"id": 6944,
"name": "半永久 生活美容"
}
]
},
{
"name": "其他",
"sub_tags": [
{
"id": 2214,
"name": "全部其他"
},
{
"id": 13,
"name": "耳部整形"
},
{
"id": 929,
"name": "视力矫正"
},
{
"id": 957,
"name": "祛腋臭"
},
{
"id": 971,
"name": "产后修复"
},
{
"id": 1134,
"name": "面膜"
},
{
"id": 2054,
"name": "半永久妆"
},
{
"id": 2955,
"name": "体检"
},
{
"id": 5433,
"name": "腿型矫正"
},
{
"id": 6418,
"name": "补差价"
},
{
"id": 6933,
"name": "生活美容"
},
{
"id": 7587,
"name": "大脚骨矫正"
},
{
"id": 11340,
"name": "塌鼻梁拯救计划"
},
{
"id": 11341,
"name": "Get元气初恋脸"
},
{
"id": 11342,
"name": "维密身材养成记"
},
{
"id": 11344,
"name": "电眼杀手俱乐部"
},
{
"id": 11345,
"name": "人间水蜜桃计划"
}
]
},
{
"name": "眼科",
"sub_tags": [
{
"id": 12711,
"name": "全部眼科"
},
{
"id": 932,
"name": "近视矫正"
},
{
"id": 940,
"name": "眼科其他"
}
]
}
],
"orders": [
{
"id": 0,
"name": "智能排序"
},
{
"id": 1,
"name": "价格"
},
{
"id": 2,
"name": "好评率"
},
{
"id": 3,
"name": "销量"
}
]
}
}
""";
/*
* @author lsy
* @date 2020/7/1
**/
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:gm_flutter/ClueModel/server/entity/PlanBean.dart';
import 'package:gm_flutter/commonModel/base/BaseComponent.dart';
import 'package:gm_flutter/commonModel/bean/Pair.dart';
import 'package:gm_flutter/commonModel/util/DartUtil.dart';
class ProjectView extends StatefulWidget {
final List<Tags> datas;
final Function(String id) clickCall;
ProjectView(this.datas, this.clickCall);
@override
State<StatefulWidget> createState() => ProjectViewState();
}
class ProjectViewState extends State<ProjectView> {
int selectIndex = 0;
@override
Widget build(BuildContext context) {
if (widget.datas == null || widget.datas.isEmpty) {
return Container();
}
return Container(
height: 450,
color: Colors.white,
child: Row(
children: <Widget>[
Container(
width: 75,
child: ListView.builder(
itemBuilder: (c, index) {
return Container(
height: 50,
color:
selectIndex == index ? Colors.white : Color(0xffF4F3F8),
child: Stack(
alignment: AlignmentDirectional.center,
children: <Widget>[
baseText(
widget.datas[index].name,
14,
selectIndex == index
? Color(0xff4ABAB4)
: Color(0xff464646),
bold: selectIndex == index ? true : false),
Positioned(
left: 0,
top: 17,
child: selectIndex == index
? Container(
width: 3,
height: 16,
decoration: BoxDecoration(
color: Color(0xff4ABAB4),
borderRadius: BorderRadius.circular(1.5)),
)
: Container(),
)
],
)).gestureDetector(() {
setState(() {
selectIndex = index;
});
});
},
itemCount: widget.datas.length,
),
),
Expanded(
child: ListView.builder(
itemBuilder: (c, index) {
return Container(
margin: EdgeInsets.only(left: 20, top: 18, bottom: 18),
child: baseText(widget.datas[selectIndex].subTags[index].name,
14, Color(0xff464646)),
).gestureDetector(() {
widget.clickCall(widget.datas[selectIndex].subTags[index].id);
});
},
itemCount: widget.datas[selectIndex].subTags.length,
),
)
],
),
);
}
}
/*
* @author lsy
* @date 2020/7/1
**/
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:gm_flutter/ClueModel/server/entity/PlanBean.dart';
import 'package:gm_flutter/commonModel/base/BaseComponent.dart';
import 'package:gm_flutter/commonModel/util/DartUtil.dart';
class SortView extends StatelessWidget {
final List<Orders> datas;
int selectIndex = 0;
final Function(int index) clickIndex;
SortView(this.datas, this.selectIndex, this.clickIndex);
@override
Widget build(BuildContext context) {
if (datas == null || datas.isEmpty) {
return Container();
}
return Container(
color: Colors.white,
child: ListView.builder(
itemBuilder: (c, index) {
return Container(
margin: EdgeInsets.only(left: 15, right: 15),
width: double.maxFinite,
height: 45,
child: Stack(
children: <Widget>[
Positioned(
top: 16,
child: baseText(
datas[index].name,
13,
selectIndex == index
? Color(0xff4ABAB4)
: Color(0xff464646)),
),
Positioned(
right: 0,
top: 15,
child: selectIndex == index
? Container(
width: 15,
height: 15,
child: Image.asset("assets/yes.png"),
)
: Container(),
),
Positioned(
bottom: 0,
child: Container(
height: 0.5,
width: MediaQuery.of(context).size.width - 30,
color: Color(0xffE5E5E5),
),
)
],
),
).gestureDetector(() {
clickIndex(index);
});
},
itemCount: datas.length,
));
}
}
...@@ -7,6 +7,8 @@ import 'package:flutter_common/Annotations/anno/Query.dart'; ...@@ -7,6 +7,8 @@ import 'package:flutter_common/Annotations/anno/Query.dart';
import 'package:flutter_common/Annotations/anno/ServiceCenter.dart'; import 'package:flutter_common/Annotations/anno/ServiceCenter.dart';
import 'package:gm_flutter/ClueModel/server/entity/LevelOneFeedList.dart'; import 'package:gm_flutter/ClueModel/server/entity/LevelOneFeedList.dart';
import 'package:gm_flutter/ClueModel/server/entity/PlanCompareDetail.dart'; import 'package:gm_flutter/ClueModel/server/entity/PlanCompareDetail.dart';
import 'package:gm_flutter/ClueModel/server/entity/PlanBean.dart';
import 'package:gm_flutter/ClueModel/server/entity/PlanFeedBean.dart';
@ServiceCenter() @ServiceCenter()
abstract class ClueApi { abstract class ClueApi {
@Get("api/janus/plans/plan_feed") @Get("api/janus/plans/plan_feed")
...@@ -15,4 +17,18 @@ abstract class ClueApi { ...@@ -15,4 +17,18 @@ abstract class ClueApi {
@Get("api/janus/plans/compare") @Get("api/janus/plans/compare")
PlanCompareDetail getPlanCompareDetail(@Query("plan_ids") List<int> plan_ids); PlanCompareDetail getPlanCompareDetail(@Query("plan_ids") List<int> plan_ids);
@Get("api/janus/plans/options")
PlanBean getPlan();
@Get("api/janus/plans/feed")
PlanFeedBean getPlanFeed(
@Query("tag_id")String tag_id,
@Query("order_by")String order_by,
@Query("current_city_id")String current_city_id,
@Query("min_price")String min_price,
@Query("max_price")String max_price,
@Query("rank_type")String rank_type,
@Query("page")int page,
);
} }
...@@ -16,6 +16,8 @@ import 'package:flutter/foundation.dart'; ...@@ -16,6 +16,8 @@ import 'package:flutter/foundation.dart';
import 'package:gm_flutter/ClueModel/server/entity/LevelOneFeedList.dart'; import 'package:gm_flutter/ClueModel/server/entity/LevelOneFeedList.dart';
import 'package:gm_flutter/ClueModel/server/entity/PlanCompareDetail.dart'; import 'package:gm_flutter/ClueModel/server/entity/PlanCompareDetail.dart';
import 'package:gm_flutter/ClueModel/server/entity/PlanBean.dart';
import 'package:gm_flutter/ClueModel/server/entity/PlanFeedBean.dart';
const bool inProduction = const bool.fromEnvironment("dart.vm.product"); const bool inProduction = const bool.fromEnvironment("dart.vm.product");
...@@ -64,6 +66,47 @@ class ClueApiImpl { ...@@ -64,6 +66,47 @@ class ClueApiImpl {
}); });
} }
Stream<PlanBean> getPlan(
Dio _dio,
) {
return Stream.fromFuture(get(_dio, 'api/janus/plans/options'))
.flatMap((value) {
if (value != null &&
(value.statusCode >= 200 && value.statusCode < 300)) {
return Stream.fromFuture(compute(parsePlanBean, value.toString()));
} else {
throw Exception("--未知网络错误--");
}
});
}
Stream<PlanFeedBean> getPlanFeed(
Dio _dio,
String tag_id,
String order_by,
String current_city_id,
String min_price,
String max_price,
String rank_type,
int page) {
return Stream.fromFuture(get(_dio, 'api/janus/plans/feed', data: {
'tag_id': tag_id,
'order_by': order_by,
'current_city_id': current_city_id,
'min_price': min_price,
'max_price': max_price,
'rank_type': rank_type,
'page': page,
})).flatMap((value) {
if (value != null &&
(value.statusCode >= 200 && value.statusCode < 300)) {
return Stream.fromFuture(compute(parsePlanFeedBean, value.toString()));
} else {
throw Exception("--未知网络错误--");
}
});
}
///==================base method================== ///==================base method==================
Future<Response> get(Dio _dio, url, {data, options, cancelToken}) async { Future<Response> get(Dio _dio, url, {data, options, cancelToken}) async {
...@@ -208,3 +251,11 @@ LevelOneFeedList parseLevelOneFeedList(String value) { ...@@ -208,3 +251,11 @@ LevelOneFeedList parseLevelOneFeedList(String value) {
PlanCompareDetail parsePlanCompareDetail(String value) { PlanCompareDetail parsePlanCompareDetail(String value) {
return PlanCompareDetail.fromJson(json.decode(value)); return PlanCompareDetail.fromJson(json.decode(value));
} }
PlanBean parsePlanBean(String value) {
return PlanBean.fromJson(json.decode(value));
}
PlanFeedBean parsePlanFeedBean(String value) {
return PlanFeedBean.fromJson(json.decode(value));
}
...@@ -3,16 +3,63 @@ ...@@ -3,16 +3,63 @@
* @date 2020/6/29 * @date 2020/6/29
**/ **/
class LevelOneFeedList { class LevelOneFeedList {
List<Cards> cards; int error;
String message;
Null extra;
Null errorExtra;
UserType userType;
Data data;
LevelOneFeedList({this.cards}); LevelOneFeedList({this.error, this.message, this.extra, this.errorExtra, this.userType, this.data});
LevelOneFeedList.fromJson(Map<String, dynamic> json) { LevelOneFeedList.fromJson(Map<String, dynamic> json) {
error = json['error'];
message = json['message'];
extra = json['extra'];
errorExtra = json['error_extra'];
userType = json['user_type'] != null ? new UserType.fromJson(json['user_type']) : null;
data = json['data'] != null ? new Data.fromJson(json['data']) : null;
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['error'] = this.error;
data['message'] = this.message;
data['extra'] = this.extra;
data['error_extra'] = this.errorExtra;
if (this.userType != null) {
data['user_type'] = this.userType.toJson();
}
if (this.data != null) {
data['data'] = this.data.toJson();
}
return data;
}
}
class UserType {
UserType();
UserType.fromJson(Map<String, dynamic> json) {
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
return data;
}
}
class Data {
List<Cards> cards;
Data({this.cards});
Data.fromJson(Map<String, dynamic> json) {
if (json['cards'] != null) { if (json['cards'] != null) {
cards = new List<Cards>(); cards = new List<Cards>();
json['cards'].forEach((v) { json['cards'].forEach((v) { cards.add(new Cards.fromJson(v)); });
cards.add(new Cards.fromJson(v));
});
} }
} }
...@@ -29,7 +76,7 @@ class Cards { ...@@ -29,7 +76,7 @@ class Cards {
String cardType; String cardType;
Plan plan; Plan plan;
Hospital hospital; Hospital hospital;
Hospital doctor; Doctor doctor;
Diary diary; Diary diary;
Cards({this.cardType, this.plan, this.hospital, this.doctor, this.diary}); Cards({this.cardType, this.plan, this.hospital, this.doctor, this.diary});
...@@ -37,11 +84,8 @@ class Cards { ...@@ -37,11 +84,8 @@ class Cards {
Cards.fromJson(Map<String, dynamic> json) { Cards.fromJson(Map<String, dynamic> json) {
cardType = json['card_type']; cardType = json['card_type'];
plan = json['plan'] != null ? new Plan.fromJson(json['plan']) : null; plan = json['plan'] != null ? new Plan.fromJson(json['plan']) : null;
hospital = json['hospital'] != null hospital = json['hospital'] != null ? new Hospital.fromJson(json['hospital']) : null;
? new Hospital.fromJson(json['hospital']) doctor = json['doctor'] != null ? new Doctor.fromJson(json['doctor']) : null;
: null;
doctor =
json['doctor'] != null ? new Hospital.fromJson(json['doctor']) : null;
diary = json['diary'] != null ? new Diary.fromJson(json['diary']) : null; diary = json['diary'] != null ? new Diary.fromJson(json['diary']) : null;
} }
...@@ -72,19 +116,10 @@ class Plan { ...@@ -72,19 +116,10 @@ class Plan {
String salesCount; String salesCount;
List<BaseAttrs> baseAttrs; List<BaseAttrs> baseAttrs;
String projectImage; String projectImage;
String consultUrl; String consultType;
String phoneAuthroize; String messageUrl;
Plan( Plan({this.planName, this.minPrice, this.maxPrice, this.positiveRate, this.salesCount, this.baseAttrs, this.projectImage, this.consultType, this.messageUrl});
{this.planName,
this.minPrice,
this.maxPrice,
this.positiveRate,
this.salesCount,
this.baseAttrs,
this.projectImage,
this.consultUrl,
this.phoneAuthroize});
Plan.fromJson(Map<String, dynamic> json) { Plan.fromJson(Map<String, dynamic> json) {
planName = json['plan_name']; planName = json['plan_name'];
...@@ -94,13 +129,11 @@ class Plan { ...@@ -94,13 +129,11 @@ class Plan {
salesCount = json['sales_count']; salesCount = json['sales_count'];
if (json['base_attrs'] != null) { if (json['base_attrs'] != null) {
baseAttrs = new List<BaseAttrs>(); baseAttrs = new List<BaseAttrs>();
json['base_attrs'].forEach((v) { json['base_attrs'].forEach((v) { baseAttrs.add(new BaseAttrs.fromJson(v)); });
baseAttrs.add(new BaseAttrs.fromJson(v));
});
} }
projectImage = json['project_image']; projectImage = json['project_image'];
consultUrl = json['consult_url']; consultType = json['consult_type'];
phoneAuthroize = json['phone_authroize']; messageUrl = json['message_url'];
} }
Map<String, dynamic> toJson() { Map<String, dynamic> toJson() {
...@@ -114,8 +147,8 @@ class Plan { ...@@ -114,8 +147,8 @@ class Plan {
data['base_attrs'] = this.baseAttrs.map((v) => v.toJson()).toList(); data['base_attrs'] = this.baseAttrs.map((v) => v.toJson()).toList();
} }
data['project_image'] = this.projectImage; data['project_image'] = this.projectImage;
data['consult_url'] = this.consultUrl; data['consult_type'] = this.consultType;
data['phone_authroize'] = this.phoneAuthroize; data['message_url'] = this.messageUrl;
return data; return data;
} }
} }
...@@ -144,36 +177,59 @@ class Hospital { ...@@ -144,36 +177,59 @@ class Hospital {
String name; String name;
String minPrice; String minPrice;
String maxPrice; String maxPrice;
String star;
String address; String address;
int star; String consultType;
List<BaseAttrs> baseAttrs; String messageUrl;
String consultUrl;
String phoneAuthroize; Hospital({this.portrait, this.name, this.minPrice, this.maxPrice, this.star, this.address, this.consultType, this.messageUrl});
Hospital(
{this.portrait,
this.name,
this.minPrice,
this.maxPrice,
this.baseAttrs,
this.consultUrl,
this.phoneAuthroize});
Hospital.fromJson(Map<String, dynamic> json) { Hospital.fromJson(Map<String, dynamic> json) {
portrait = json['portrait']; portrait = json['portrait'];
name = json['name']; name = json['name'];
minPrice = json['min_price'];
maxPrice = json['max_price'];
star = json['star']; star = json['star'];
address = json['address']; address = json['address'];
consultType = json['consult_type'];
messageUrl = json['message_url'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['portrait'] = this.portrait;
data['name'] = this.name;
data['min_price'] = this.minPrice;
data['max_price'] = this.maxPrice;
data['star'] = this.star;
data['address'] = this.address;
data['consult_type'] = this.consultType;
data['message_url'] = this.messageUrl;
return data;
}
}
class Doctor {
String portrait;
String name;
String minPrice;
String maxPrice;
String star;
String title;
String consultType;
String messageUrl;
Doctor({this.portrait, this.name, this.minPrice, this.maxPrice, this.star, this.title, this.consultType, this.messageUrl});
Doctor.fromJson(Map<String, dynamic> json) {
portrait = json['portrait'];
name = json['name'];
minPrice = json['min_price']; minPrice = json['min_price'];
maxPrice = json['max_price']; maxPrice = json['max_price'];
if (json['base_attrs'] != null) { star = json['star'];
baseAttrs = new List<BaseAttrs>(); title = json['title'];
json['base_attrs'].forEach((v) { consultType = json['consult_type'];
baseAttrs.add(new BaseAttrs.fromJson(v)); messageUrl = json['message_url'];
});
}
consultUrl = json['consult_url'];
phoneAuthroize = json['phone_authroize'];
} }
Map<String, dynamic> toJson() { Map<String, dynamic> toJson() {
...@@ -182,13 +238,10 @@ class Hospital { ...@@ -182,13 +238,10 @@ class Hospital {
data['name'] = this.name; data['name'] = this.name;
data['min_price'] = this.minPrice; data['min_price'] = this.minPrice;
data['max_price'] = this.maxPrice; data['max_price'] = this.maxPrice;
data['address'] = this.address;
data['star'] = this.star; data['star'] = this.star;
if (this.baseAttrs != null) { data['title'] = this.title;
data['base_attrs'] = this.baseAttrs.map((v) => v.toJson()).toList(); data['consult_type'] = this.consultType;
} data['message_url'] = this.messageUrl;
data['consult_url'] = this.consultUrl;
data['phone_authroize'] = this.phoneAuthroize;
return data; return data;
} }
} }
...@@ -202,7 +255,7 @@ class Diary { ...@@ -202,7 +255,7 @@ class Diary {
int replyNum; int replyNum;
int lasestTopicCreatedTime; int lasestTopicCreatedTime;
List<Images> images; List<Images> images;
RelationServiceSku relationServiceSku; UserType relationServiceSku;
String createdTime; String createdTime;
int latestTopicId; int latestTopicId;
int id; int id;
...@@ -232,44 +285,7 @@ class Diary { ...@@ -232,44 +285,7 @@ class Diary {
UserLevel userLevel; UserLevel userLevel;
int serviceId; int serviceId;
Diary( Diary({this.diaryNum, this.videoUrl, this.isIdentification, this.isLiked, this.titleStyleType, this.replyNum, this.lasestTopicCreatedTime, this.images, this.relationServiceSku, this.createdTime, this.latestTopicId, this.id, this.city, this.userId, this.title, this.isVoted, this.diaryId, this.preImageList, this.voteNum, this.tagsNewEra, this.content, this.videoPic, this.shortVideoUrl, this.diaryAmount, this.diaryTitle, this.authorType, this.tags, this.contentLevel, this.lastModified, this.user, this.isOnline, this.date, this.membershipLevel, this.viewNum, this.postImageList, this.userLevel, this.serviceId});
{this.diaryNum,
this.videoUrl,
this.isIdentification,
this.isLiked,
this.titleStyleType,
this.replyNum,
this.lasestTopicCreatedTime,
this.images,
this.relationServiceSku,
this.createdTime,
this.latestTopicId,
this.id,
this.city,
this.userId,
this.title,
this.isVoted,
this.diaryId,
this.preImageList,
this.voteNum,
this.tagsNewEra,
this.content,
this.videoPic,
this.shortVideoUrl,
this.diaryAmount,
this.diaryTitle,
this.authorType,
this.tags,
this.contentLevel,
this.lastModified,
this.user,
this.isOnline,
this.date,
this.membershipLevel,
this.viewNum,
this.postImageList,
this.userLevel,
this.serviceId});
Diary.fromJson(Map<String, dynamic> json) { Diary.fromJson(Map<String, dynamic> json) {
diaryNum = json['diary_num']; diaryNum = json['diary_num'];
...@@ -281,13 +297,9 @@ class Diary { ...@@ -281,13 +297,9 @@ class Diary {
lasestTopicCreatedTime = json['lasest_topic_created_time']; lasestTopicCreatedTime = json['lasest_topic_created_time'];
if (json['images'] != null) { if (json['images'] != null) {
images = new List<Images>(); images = new List<Images>();
json['images'].forEach((v) { json['images'].forEach((v) { images.add(new Images.fromJson(v)); });
images.add(new Images.fromJson(v));
});
} }
relationServiceSku = json['relation_service_sku'] != null relationServiceSku = json['relation_service_sku'] != null ? new UserType.fromJson(json['relation_service_sku']) : null;
? new RelationServiceSku.fromJson(json['relation_service_sku'])
: null;
createdTime = json['created_time']; createdTime = json['created_time'];
latestTopicId = json['latest_topic_id']; latestTopicId = json['latest_topic_id'];
id = json['id']; id = json['id'];
...@@ -300,9 +312,7 @@ class Diary { ...@@ -300,9 +312,7 @@ class Diary {
voteNum = json['vote_num']; voteNum = json['vote_num'];
if (json['tags_new_era'] != null) { if (json['tags_new_era'] != null) {
tagsNewEra = new List<TagsNewEra>(); tagsNewEra = new List<TagsNewEra>();
json['tags_new_era'].forEach((v) { json['tags_new_era'].forEach((v) { tagsNewEra.add(new TagsNewEra.fromJson(v)); });
tagsNewEra.add(new TagsNewEra.fromJson(v));
});
} }
content = json['content']; content = json['content'];
videoPic = json['video_pic']; videoPic = json['video_pic'];
...@@ -312,9 +322,7 @@ class Diary { ...@@ -312,9 +322,7 @@ class Diary {
authorType = json['author_type']; authorType = json['author_type'];
if (json['tags'] != null) { if (json['tags'] != null) {
tags = new List<Tags>(); tags = new List<Tags>();
json['tags'].forEach((v) { json['tags'].forEach((v) { tags.add(new Tags.fromJson(v)); });
tags.add(new Tags.fromJson(v));
});
} }
contentLevel = json['content_level']; contentLevel = json['content_level'];
lastModified = json['last_modified']; lastModified = json['last_modified'];
...@@ -324,9 +332,7 @@ class Diary { ...@@ -324,9 +332,7 @@ class Diary {
membershipLevel = json['membership_level']; membershipLevel = json['membership_level'];
viewNum = json['view_num']; viewNum = json['view_num'];
postImageList = json['post_image_list'].cast<String>(); postImageList = json['post_image_list'].cast<String>();
userLevel = json['user_level'] != null userLevel = json['user_level'] != null ? new UserLevel.fromJson(json['user_level']) : null;
? new UserLevel.fromJson(json['user_level'])
: null;
serviceId = json['service_id']; serviceId = json['service_id'];
} }
...@@ -396,16 +402,7 @@ class Images { ...@@ -396,16 +402,7 @@ class Images {
String imageHalf; String imageHalf;
String desc; String desc;
Images( Images({this.imageWide, this.imageType, this.image, this.sImagePlatform, this.imageSlimwidth, this.smallWide, this.imageThumb, this.imageHalf, this.desc});
{this.imageWide,
this.imageType,
this.image,
this.sImagePlatform,
this.imageSlimwidth,
this.smallWide,
this.imageThumb,
this.imageHalf,
this.desc});
Images.fromJson(Map<String, dynamic> json) { Images.fromJson(Map<String, dynamic> json) {
imageWide = json['image_wide']; imageWide = json['image_wide'];
...@@ -434,17 +431,6 @@ class Images { ...@@ -434,17 +431,6 @@ class Images {
} }
} }
class RelationServiceSku {
RelationServiceSku();
RelationServiceSku.fromJson(Map<String, dynamic> json) {}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
return data;
}
}
class TagsNewEra { class TagsNewEra {
String type; String type;
String name; String name;
...@@ -479,14 +465,7 @@ class User { ...@@ -479,14 +465,7 @@ class User {
String userName; String userName;
String membershipLevel; String membershipLevel;
User( User({this.city, this.userId, this.topicNumPosted, this.voteNumGained, this.portrait, this.userName, this.membershipLevel});
{this.city,
this.userId,
this.topicNumPosted,
this.voteNumGained,
this.portrait,
this.userName,
this.membershipLevel});
User.fromJson(Map<String, dynamic> json) { User.fromJson(Map<String, dynamic> json) {
city = json['city']; city = json['city'];
...@@ -557,3 +536,4 @@ class Tags { ...@@ -557,3 +536,4 @@ class Tags {
return data; return data;
} }
} }
/*
* @author lsy
* @date 2020/7/1
**/
class PlanBean {
int error;
String message;
Null extra;
Null errorExtra;
UserType userType;
Data data;
PlanBean({this.error, this.message, this.extra, this.errorExtra, this.userType, this.data});
PlanBean.fromJson(Map<String, dynamic> json) {
error = json['error'];
message = json['message'];
extra = json['extra'];
errorExtra = json['error_extra'];
userType = json['user_type'] != null ? new UserType.fromJson(json['user_type']) : null;
data = json['data'] != null ? new Data.fromJson(json['data']) : null;
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['error'] = this.error;
data['message'] = this.message;
data['extra'] = this.extra;
data['error_extra'] = this.errorExtra;
if (this.userType != null) {
data['user_type'] = this.userType.toJson();
}
if (this.data != null) {
data['data'] = this.data.toJson();
}
return data;
}
}
class UserType {
UserType();
UserType.fromJson(Map<String, dynamic> json) {
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
return data;
}
}
class Data {
List<Ranks> ranks;
List<Areas> areas;
List<Tags> tags;
List<Orders> orders;
Data({this.ranks, this.areas, this.tags, this.orders});
Data.fromJson(Map<String, dynamic> json) {
if (json['ranks'] != null) {
ranks = new List<Ranks>();
json['ranks'].forEach((v) { ranks.add(new Ranks.fromJson(v)); });
}
if (json['areas'] != null) {
areas = new List<Areas>();
json['areas'].forEach((v) { areas.add(new Areas.fromJson(v)); });
}
if (json['tags'] != null) {
tags = new List<Tags>();
json['tags'].forEach((v) { tags.add(new Tags.fromJson(v)); });
}
if (json['orders'] != null) {
orders = new List<Orders>();
json['orders'].forEach((v) { orders.add(new Orders.fromJson(v)); });
}
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
if (this.ranks != null) {
data['ranks'] = this.ranks.map((v) => v.toJson()).toList();
}
if (this.areas != null) {
data['areas'] = this.areas.map((v) => v.toJson()).toList();
}
if (this.tags != null) {
data['tags'] = this.tags.map((v) => v.toJson()).toList();
}
if (this.orders != null) {
data['orders'] = this.orders.map((v) => v.toJson()).toList();
}
return data;
}
}
class Ranks {
String name;
String gmUrl;
String icon;
Ranks({this.name, this.gmUrl, this.icon});
Ranks.fromJson(Map<String, dynamic> json) {
name = json['name'];
gmUrl = json['gm_url'];
icon = json['icon'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['name'] = this.name;
data['gm_url'] = this.gmUrl;
data['icon'] = this.icon;
return data;
}
}
class Areas {
bool isLocated;
String name;
List<Groups> groups;
Areas({this.isLocated, this.name, this.groups});
Areas.fromJson(Map<String, dynamic> json) {
isLocated = json['is_located'];
name = json['name'];
if (json['groups'] != null) {
groups = new List<Groups>();
json['groups'].forEach((v) { groups.add(new Groups.fromJson(v)); });
}
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['is_located'] = this.isLocated;
data['name'] = this.name;
if (this.groups != null) {
data['groups'] = this.groups.map((v) => v.toJson()).toList();
}
return data;
}
}
class Groups {
bool isHot;
String initial;
List<Cities> cities;
String title;
Groups({this.isHot, this.initial, this.cities, this.title});
Groups.fromJson(Map<String, dynamic> json) {
isHot = json['is_hot'];
initial = json['initial'];
if (json['cities'] != null) {
cities = new List<Cities>();
json['cities'].forEach((v) { cities.add(new Cities.fromJson(v)); });
}
title = json['title'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['is_hot'] = this.isHot;
data['initial'] = this.initial;
if (this.cities != null) {
data['cities'] = this.cities.map((v) => v.toJson()).toList();
}
data['title'] = this.title;
return data;
}
}
class Cities {
String cityName;
int id;
String name;
Cities({this.cityName, this.id, this.name});
Cities.fromJson(Map<String, dynamic> json) {
cityName = json['city_name'];
id = json['id'];
name = json['name'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['city_name'] = this.cityName;
data['id'] = this.id;
data['name'] = this.name;
return data;
}
}
class Tags {
String id;
List<SubTags> subTags;
String name;
Tags({this.id, this.subTags, this.name});
Tags.fromJson(Map<String, dynamic> json) {
id = json['id'];
if (json['sub_tags'] != null) {
subTags = new List<SubTags>();
json['sub_tags'].forEach((v) { subTags.add(new SubTags.fromJson(v)); });
}
name = json['name'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = this.id;
if (this.subTags != null) {
data['sub_tags'] = this.subTags.map((v) => v.toJson()).toList();
}
data['name'] = this.name;
return data;
}
}
class SubTags {
String id;
String name;
SubTags({this.id, this.name});
SubTags.fromJson(Map<String, dynamic> json) {
id = json['id'];
name = json['name'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = this.id;
data['name'] = this.name;
return data;
}
}
class Orders {
int id;
String name;
Orders({this.id, this.name});
Orders.fromJson(Map<String, dynamic> json) {
id = json['id'];
name = json['name'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = this.id;
data['name'] = this.name;
return data;
}
}
/*
* @author lsy
* @date 2020/7/1
**/
class PlanFeedBean {
int error;
String message;
String extra;
String errorExtra;
UserType userType;
Data data;
PlanFeedBean(
{this.error,
this.message,
this.extra,
this.errorExtra,
this.userType,
this.data});
PlanFeedBean.fromJson(Map<String, dynamic> json) {
error = json['error'];
message = json['message'];
extra = json['extra'];
errorExtra = json['error_extra'];
userType = json['user_type'] != null
? new UserType.fromJson(json['user_type'])
: null;
data = json['data'] != null ? new Data.fromJson(json['data']) : null;
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['error'] = this.error;
data['message'] = this.message;
data['extra'] = this.extra;
data['error_extra'] = this.errorExtra;
if (this.userType != null) {
data['user_type'] = this.userType.toJson();
}
if (this.data != null) {
data['data'] = this.data.toJson();
}
return data;
}
}
class UserType {
UserType();
UserType.fromJson(Map<String, dynamic> json) {}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
return data;
}
}
class Data {
List<Plans> plans;
Data({this.plans});
Data.fromJson(Map<String, dynamic> json) {
if (json['plans'] != null) {
plans = new List<Plans>();
json['plans'].forEach((v) {
plans.add(new Plans.fromJson(v));
});
}
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
if (this.plans != null) {
data['plans'] = this.plans.map((v) => v.toJson()).toList();
}
return data;
}
}
class Plans {
String cardType;
String name;
String positiveRate;
String salesCount;
List<BaseAttrs> baseAttrs;
String minPrice;
String maxPrice;
String projectImage;
Plans(
{this.cardType,
this.name,
this.positiveRate,
this.salesCount,
this.baseAttrs,
this.minPrice,
this.maxPrice,
this.projectImage});
Plans.fromJson(Map<String, dynamic> json) {
cardType = json['card_type'];
name = json['name'];
positiveRate = json['positive_rate'];
salesCount = json['sales_count'];
if (json['base_attrs'] != null) {
baseAttrs = new List<BaseAttrs>();
json['base_attrs'].forEach((v) {
baseAttrs.add(new BaseAttrs.fromJson(v));
});
}
minPrice = json['min_price'];
maxPrice = json['max_price'];
projectImage = json['project_image'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['card_type'] = this.cardType;
data['name'] = this.name;
data['positive_rate'] = this.positiveRate;
data['sales_count'] = this.salesCount;
if (this.baseAttrs != null) {
data['base_attrs'] = this.baseAttrs.map((v) => v.toJson()).toList();
}
data['min_price'] = this.minPrice;
data['max_price'] = this.maxPrice;
data['project_image'] = this.projectImage;
return data;
}
}
class BaseAttrs {
int attrId;
String attrName;
String attrValue;
BaseAttrs({this.attrId, this.attrName, this.attrValue});
BaseAttrs.fromJson(Map<String, dynamic> json) {
attrId = json['attr_id'];
attrName = json['attr_name'];
attrValue = json['attr_value'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['attr_id'] = this.attrId;
data['attr_name'] = this.attrName;
data['attr_value'] = this.attrValue;
return data;
}
}
...@@ -28,6 +28,9 @@ class TestState extends BaseState<TestPage> { ...@@ -28,6 +28,9 @@ class TestState extends BaseState<TestPage> {
list.add(listItem("一级列表页", () { list.add(listItem("一级列表页", () {
JumpUtil.jumpToPageRight(context, RouterCenterImpl().findClueRouter().getLevelOnePage()); JumpUtil.jumpToPageRight(context, RouterCenterImpl().findClueRouter().getLevelOnePage());
})); }));
list.add(listItem("方案页面", () {
JumpUtil.jumpToPageRight(context, RouterCenterImpl().findClueRouter().getPlanPage());
}));
return list; return list;
} }
......
...@@ -12,6 +12,7 @@ import 'package:flutter_svg/svg.dart'; ...@@ -12,6 +12,7 @@ import 'package:flutter_svg/svg.dart';
import 'package:gm_flutter/commonModel/GMBase.dart'; import 'package:gm_flutter/commonModel/GMBase.dart';
import 'package:gm_flutter/commonModel/util/DartUtil.dart'; import 'package:gm_flutter/commonModel/util/DartUtil.dart';
import 'package:gm_flutter/commonModel/view/ImagesAnimation.dart'; import 'package:gm_flutter/commonModel/view/ImagesAnimation.dart';
import 'package:lottie/lottie.dart';
import 'package:pull_to_refresh/pull_to_refresh.dart'; import 'package:pull_to_refresh/pull_to_refresh.dart';
double SCREENWIDTH; double SCREENWIDTH;
...@@ -271,19 +272,23 @@ Widget baseRefreshView(RefreshController refreshController, ...@@ -271,19 +272,23 @@ Widget baseRefreshView(RefreshController refreshController,
onRefresh: refresh, onRefresh: refresh,
footer: CustomFooter( footer: CustomFooter(
builder: (BuildContext context, LoadStatus mode) { builder: (BuildContext context, LoadStatus mode) {
Widget body; Widget body = Container();
print("LOAD STATUE ${mode}"); // print("LOAD STATUE ${mode}");
if (mode == LoadStatus.idle) { // if (mode == LoadStatus.idle) {
body = baseText("上拉加载更多", 12, Color(0xff545454)); // body = baseText("上拉加载更多", 12, Color(0xff545454));
} else if (mode == LoadStatus.loading) { // } else if (mode == LoadStatus.loading) {
body = baseText("加载中", 12, Color(0xff545454)); // body = baseText("加载中", 12, Color(0xff545454));
} else if (mode == LoadStatus.failed) { // } else if (mode == LoadStatus.failed) {
body = baseText("加载失败", 12, Color(0xff545454)); // body = baseText("加载失败", 12, Color(0xff545454));
} else if (mode == LoadStatus.noMore) { // } else if (mode == LoadStatus.noMore) {
body = baseText("没有更多数据了", 12, Color(0xff545454)); // body = baseText("没有更多数据了", 12, Color(0xff545454));
} // }
else { // else {
body = Container(); // body = Container();
// }
if (mode == LoadStatus.loading) {
body = Lottie.asset("assets/smart_refresh_header.json",
repeat: true, reverse: false);
} }
return Container( return Container(
height: 55.0, height: 55.0,
...@@ -306,26 +311,29 @@ Widget baseRefreshView(RefreshController refreshController, ...@@ -306,26 +311,29 @@ Widget baseRefreshView(RefreshController refreshController,
Widget normalRefreshHeader() { Widget normalRefreshHeader() {
return CustomHeader( return CustomHeader(
builder: (BuildContext context, RefreshStatus mode) { builder: (BuildContext context, RefreshStatus mode) {
Widget body; Widget body=Container();
// if (mode == RefreshStatus.idle) { // if (mode == RefreshStatus.idle) {
// //
// } else // } else
if (mode == RefreshStatus.refreshing) { if (mode == RefreshStatus.refreshing) {
body = ImagesAnimation( // body = ImagesAnimation(
w: 46, // w: 46,
h: 15, // h: 15,
durationSeconds: 1500, // durationSeconds: 1500,
entry: ImagesAnimationEntry(1, 20, "assets/ptr_header_loading")); // entry: ImagesAnimationEntry(1, 20, "assets/ptr_header_loading"));
body = Lottie.asset("assets/smart_refresh_header.json",
repeat: true, reverse: false);
} }
// else if (mode == RefreshStatus.failed) { // else if (mode == RefreshStatus.failed) {
// body = Text("Load Failed!Click retry!"); // body = Text("Load Failed!Click retry!");
// } // }
else { else {
body = Image.asset( // body = Image.asset(
"assets/ptr_header_loading01.png", // "assets/ptr_header_loading01.png",
width: 46, // width: 46,
height: 15, // height: 15,
); // );
} }
return Container( return Container(
height: 55.0, height: 55.0,
...@@ -335,7 +343,6 @@ Widget normalRefreshHeader() { ...@@ -335,7 +343,6 @@ Widget normalRefreshHeader() {
); );
} }
Widget emptyItem({String detail}) { Widget emptyItem({String detail}) {
return Column( return Column(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
......
...@@ -15,6 +15,7 @@ class BasePopMenu extends StatefulWidget { ...@@ -15,6 +15,7 @@ class BasePopMenu extends StatefulWidget {
final int maxHeight; final int maxHeight;
final Widget child; final Widget child;
final BaseMenuListener listener; final BaseMenuListener listener;
final Function(double progress) proListener;
BasePopMenu( BasePopMenu(
{this.leftPos, {this.leftPos,
...@@ -23,11 +24,13 @@ class BasePopMenu extends StatefulWidget { ...@@ -23,11 +24,13 @@ class BasePopMenu extends StatefulWidget {
this.width, this.width,
this.height, this.height,
this.child, this.child,
this.listener}); this.listener,
this.proListener});
@override @override
State<StatefulWidget> createState() { State<StatefulWidget> createState() {
return BasePopMenuState();; return BasePopMenuState();
;
} }
} }
...@@ -37,6 +40,7 @@ class BasePopMenuState extends State<BasePopMenu> ...@@ -37,6 +40,7 @@ class BasePopMenuState extends State<BasePopMenu>
AnimationController animationController; AnimationController animationController;
LiveData<double> _liveData = LiveData(); LiveData<double> _liveData = LiveData();
bool isOpen = false; bool isOpen = false;
bool isDestory = false;
@override @override
void initState() { void initState() {
...@@ -45,12 +49,15 @@ class BasePopMenuState extends State<BasePopMenu> ...@@ -45,12 +49,15 @@ class BasePopMenuState extends State<BasePopMenu>
duration: const Duration(milliseconds: 300), vsync: this) duration: const Duration(milliseconds: 300), vsync: this)
..addListener(() { ..addListener(() {
_liveData.notifyView(animation.value * widget.maxHeight); _liveData.notifyView(animation.value * widget.maxHeight);
if (widget.proListener != null && !isDestory) {
widget.proListener(animation.value);
}
}); });
animation = new Tween(begin: 0.0, end: 1.0).animate(animationController); animation = new Tween(begin: 0.0, end: 1.0).animate(animationController);
widget.listener.addListener(() { widget.listener.addListener(() {
if(widget.listener.isShow){ if (widget.listener.isShow) {
animationController.forward(); animationController.forward();
}else{ } else {
animationController.reverse(); animationController.reverse();
} }
}); });
...@@ -77,6 +84,7 @@ class BasePopMenuState extends State<BasePopMenu> ...@@ -77,6 +84,7 @@ class BasePopMenuState extends State<BasePopMenu>
@override @override
void dispose() { void dispose() {
isDestory = true;
_liveData.dispost(); _liveData.dispost();
animationController.dispose(); animationController.dispose();
super.dispose(); super.dispose();
......
...@@ -6,10 +6,12 @@ import 'package:flutter_common/Annotations/anno/RouterCenter.dart'; ...@@ -6,10 +6,12 @@ import 'package:flutter_common/Annotations/anno/RouterCenter.dart';
import 'package:flutter_common/commonModel/util/WindowUtil.dart'; import 'package:flutter_common/commonModel/util/WindowUtil.dart';
import 'package:gm_flutter/commonModel/base/BaseComponent.dart'; import 'package:gm_flutter/commonModel/base/BaseComponent.dart';
import 'package:gm_flutter/main.mark.dart'; import 'package:gm_flutter/main.mark.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'DemoPage.dart'; import 'DemoPage.dart';
import 'DemoPage1.dart'; import 'DemoPage1.dart';
import 'commonModel/base/BaseUtil.dart'; import 'commonModel/base/BaseUtil.dart';
import 'commonModel/cache/CacheManager.dart';
import 'commonModel/nav/NavigationService.dart'; import 'commonModel/nav/NavigationService.dart';
NavigationService navigationService; NavigationService navigationService;
...@@ -31,6 +33,9 @@ void main() { ...@@ -31,6 +33,9 @@ void main() {
runApp( runApp(
MyAppWidget(), MyAppWidget(),
); );
SharedPreferences.getInstance().then((value) {
sharedPreferences = value;
});
RouterCenterImpl().findMainRouter().init(); RouterCenterImpl().findMainRouter().init();
}, (Object error, StackTrace stack) { }, (Object error, StackTrace stack) {
//TODO //TODO
......
...@@ -106,6 +106,13 @@ packages: ...@@ -106,6 +106,13 @@ packages:
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "2.2.0+1" version: "2.2.0+1"
characters:
dependency: transitive
description:
name: characters
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.0.0"
charcode: charcode:
dependency: transitive dependency: transitive
description: description:
...@@ -356,6 +363,13 @@ packages: ...@@ -356,6 +363,13 @@ packages:
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "0.11.4" version: "0.11.4"
lottie:
dependency: "direct main"
description:
name: lottie
url: "https://pub.flutter-io.cn"
source: hosted
version: "0.4.0+1"
matcher: matcher:
dependency: transitive dependency: transitive
description: description:
......
...@@ -31,6 +31,7 @@ dependencies: ...@@ -31,6 +31,7 @@ dependencies:
permission_handler: ^5.0.0 permission_handler: ^5.0.0
#轻量级存储 #轻量级存储
shared_preferences: ^0.5.7+1 shared_preferences: ^0.5.7+1
lottie: ^0.4.0+1
dev_dependencies: dev_dependencies:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment