Commit 3235a999 authored by 杜欣's avatar 杜欣

Merge branch 'test' into featrue/duxin

# Conflicts:
#	lib/ClueModel/ClueRouter.dart
#	lib/ClueModel/ClueRouterImpl.dart
#	lib/MainRouter/page/test/TestPage.dart
parents 91caf80a 59af1797
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Flutter",
"request": "launch",
"type": "dart"
}
]
}
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -3,14 +3,21 @@
* @date 2020/6/24
**/
import 'package:flutter/cupertino.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_common/Annotations/RouterBaser.dart';
import 'package:flutter_common/Annotations/anno/Router.dart';
import 'package:flutter_common/Annotations/anno/RouterCenter.dart';
import 'package:gm_flutter/ClueModel/ClueRouterImpl.dart';
@Router("ClueRouter", ClueRouterImpl, true)
abstract class ClueRouter implements RouterBaser {
Widget getProjectDetailsPage();
Widget getPlansCompareFeed();
Widget getLevelOnePage();
Widget getLevelTwoPage();
Widget getPlanPage();
Widget getPlanCompareDetailPage();
}
......@@ -4,16 +4,40 @@
**/
import 'package:flutter/src/widgets/framework.dart';
import 'package:gm_flutter/ClueModel/ClueRouter.dart';
import 'package:gm_flutter/ClueModel/page/PlansCompareFeed/PlansCompareFeedPage.dart';
import 'package:gm_flutter/ClueModel/page/ProjectDetails/ProjectDetailsPage.dart';
import 'package:gm_flutter/ClueModel/page/levelOne/LevelOnePage.dart';
import 'package:gm_flutter/ClueModel/page/levelTwo/LevelTwoPage.dart';
import 'package:gm_flutter/ClueModel/page/plan/PlanPage.dart';
import 'package:gm_flutter/ClueModel/page/PlanCompareDetail/PlanCompareDetailPage.dart';
class ClueRouterImpl implements ClueRouter {
@override
Widget getProjectDetailsPage() {
return ProjectDetailsPage();
}
@override
Widget getLevelOnePage() {
return LevelOnePage();
}
@override
Widget getLevelTwoPage() {
return LevelTwoPage();
}
@override
Widget getPlansCompareFeed() {
return PlansCompareFeedPage();
}
@override
Widget getPlanPage() {
return PlanPage();
}
Widget getPlanCompareDetailPage() {
return PlanCompareDetailPage();
}
}
/*
* @Author: zx
* @Date: 2020-06-30 17:43:13
* @Last Modified by: zx
* @Last Modified time: 2020-07-01 20:04:23
*/
import 'package:flutter_common/commonModel/live/BaseModel.dart';
import 'package:flutter_common/commonModel/live/LiveData.dart';
import 'package:gm_flutter/ClueModel/server/api/ClueApi.serv.dart';
import 'package:gm_flutter/ClueModel/server/entity/PlanCompareDetail.dart';
import 'package:gm_flutter/commonModel/GMBase.dart';
import 'package:gm_flutter/commonModel/rx/RxDispose.dart';
class PlanCompareDetailModel extends BaseModel {
LiveData<PlanCompareDetail> detailLive = LiveData();
RxDispose rxDispose = RxDispose();
void init() {
ClueApiImpl.getInstance()
.getPlanCompareDetail(DioUtil.getInstance().getDio(), [1,2])
.listen((event) {
if (event.error == 0) {
detailLive.notifyView(event);
}
})
.addToDispose(rxDispose)
.onError((err) {});
}
@override
void dispose() {
detailLive.dispost();
}
}
\ No newline at end of file
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:gm_flutter/ClueModel/server/entity/PlansCompareFeed.dart';
class PlansCompareFeedItemView extends StatelessWidget {
Plans plan;
int groupValue = 1;
PlansCompareFeedItemView(this.plan);
@override
Widget build(BuildContext context) {
return Container(child: getItem());
}
getItem() {
if (plan.planType == 1) {
return getFirstLevelItem();
} else {
return getSecondLevelItem();
}
}
getFirstLevelItem() {
Container(
margin: EdgeInsets.all(4.0),
child: Row(
children: <Widget>[
Radio(
value: 1,
groupValue: groupValue,
onChanged: (value) {
groupValue = value;
}),
ClipRRect(
borderRadius: BorderRadius.circular(2.0),
child: Image.network(
plan.projectImage,
width: 50,
height: 50,
fit: BoxFit.fill,
),
),
Expanded(
child: Container(
margin: EdgeInsets.only(left: 8.0),
height: 50,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Row(
children: <Widget>[
Text(
plan.name,
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 14,
color: Color(0xFF282828)),
maxLines: 1,
),
Text(
"好评率 ",
style: TextStyle(fontSize: 11, color: Color(0xFF282828)),
maxLines: 1,
),
Text(
plan.positiveRate,
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 14,
color: Color(0xFFFF5963)),
maxLines: 1,
),
],
),
Row(
children: <Widget>[
Text(
'¥${plan.minPrice}-${plan.maxPrice})',
style: TextStyle(fontSize: 13, color: Color(0xFFFF5963)),
),
Text(
"销量${plan.salesCount}",
style: TextStyle(fontSize: 11, color: Color(0xFF282828)),
maxLines: 1,
)
],
)
],
),
))
],
),
);
}
getSecondLevelItem() {
Container(
margin: EdgeInsets.all(4.0),
child: Row(
children: <Widget>[
Radio(
value: 1,
groupValue: groupValue,
onChanged: (value) {
groupValue = value;
}),
Expanded(
child: Container(
margin: EdgeInsets.only(left: 8.0),
height: 50,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
plan.name,
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 14,
color: Color(0xFF282828)),
maxLines: 1,
),
Row(
children: <Widget>[
Text(
'¥${plan.minPrice}-${plan.maxPrice})',
style: TextStyle(fontSize: 13, color: Color(0xFFFF5963)),
),
Text(
"指导价:¥${plan.guidePrice}",
style: TextStyle(fontSize: 11, color: Color(0xFF282828)),
maxLines: 1,
)
],
)
],
),
))
],
),
);
}
}
import 'package:flutter_common/commonModel/live/BaseModel.dart';
import 'package:flutter_common/commonModel/live/LiveData.dart';
import 'package:gm_flutter/ClueModel/server/api/ClueApi.serv.dart';
import 'package:gm_flutter/ClueModel/server/entity/PlansCompareFeed.dart';
import 'package:gm_flutter/commonModel/net/DioUtil.dart';
import 'package:gm_flutter/commonModel/rx/RxDispose.dart';
class PlansCompareFeedModel extends BaseModel {
LiveData<PlansCompareFeed> liveData = LiveData();
RxDispose rxDispose = RxDispose();
void init() {
ClueApiImpl.getInstance()
.getPlansCompareFeed(DioUtil.getInstance().getDio(), 123, 1)
.listen((event) {
if (event.error == 0) {
liveData.notifyView(event);
}
})
.addToDispose(rxDispose)
.onError((err) {});
}
@override
void dispose() {
liveData.dispost();
rxDispose.dispose();
}
}
/*
* @author zcc
* @date 2020-07-01
* 方案对比
**/
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:gm_flutter/ClueModel/page/PlansCompareFeed/PlansCompareFeedModel.dart';
import 'package:gm_flutter/ClueModel/server/entity/PlansCompareFeed.dart';
import 'package:gm_flutter/commonModel/base/BaseComponent.dart';
import 'package:gm_flutter/commonModel/base/BaseState.dart';
import 'PlansCompareFeedItemView.dart';
class PlansCompareFeedPage extends StatefulWidget {
@override
State<StatefulWidget> createState() => PlansCompareFeedState();
}
class PlansCompareFeedState extends BaseState<PlansCompareFeedPage> {
PlansCompareFeedModel _model = new PlansCompareFeedModel();
@override
void initState() {
super.initState();
_model.init();
}
@override
void dispose() {
_model.dispose();
super.dispose();
}
@override
Widget buildItem(BuildContext context) {}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("方案对比"),
),
body: Center(
child: getBody(),
),
);
}
getList(List<Plans> plans) {
return Stack(alignment: Alignment.bottomCenter, //指定未定位或部分定位widget的对齐方式
children: <Widget>[
ListView.builder(
itemCount: plans.length,
itemBuilder: (BuildContext context, int position) {
return PlansCompareFeedItemView(plans[position]);
}),
GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: () {},
child: Container(
margin:
EdgeInsets.only(left: 15, right: 15, top: 7.5, bottom: 7.5),
width: double.maxFinite,
height: 40,
decoration: BoxDecoration(
color: Color(0xff51CDC7),
borderRadius: BorderRadius.circular(20)),
alignment: Alignment.center,
child: baseText("对比", 14, Colors.white, bold: true),
))
]);
}
getBody() {
return StreamBuilder(
stream: _model.liveData.stream,
initialData: PlansCompareFeed(),
builder: (c, data) {
PlansCompareFeed item = data.data;
if (item == null || item.data == null || item.data.plans == null) {
return loadingItem();
}
return getList(item.data.plans);
},
);
}
}
/*
* @author zcc
* @date 2020-07-01
* 项目说明
**/
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:gm_flutter/ClueModel/server/entity/ProjectDetailsItem.dart';
class ProjectDetailsItemView extends StatelessWidget {
Groups listData;
ProjectDetailsItemView(this.listData);
@override
Widget build(BuildContext context) {
List<Widget> tiles = [];
for (var item in listData.attrs) {
tiles.add(getItem(item));
}
var row = Row(
children: <Widget>[
Container(
padding: EdgeInsets.only(top: 8.0, bottom: 8.0, left: 20),
child: Text(
listData.name,
style: TextStyle(
color: Color(0xFF000000),
fontSize: 15.0,
),
),
),
Column(
children: tiles,
)
],
);
return Container(
margin: EdgeInsets.only(bottom: 5, left: 20),
child: row,
);
}
getItem(Attrs attrs) {
var row = Container(
margin: EdgeInsets.only(bottom: 25),
child: Row(
children: <Widget>[
Text(
attrs.attrName,
style: TextStyle(
color: Color(0xFF999999),
fontSize: 13.0,
),
),
Text(
attrs.attrValue,
style: TextStyle(
color: Color(0xFF282828),
fontSize: 14.0,
),
maxLines: 1,
),
],
),
);
return Container(
child: row,
);
}
}
/*
* @author zcc
* @date 2020-07-01
* 项目说明
**/
import 'package:flutter_common/commonModel/live/BaseModel.dart';
import 'package:flutter_common/commonModel/live/LiveData.dart';
import 'package:gm_flutter/ClueModel/server/api/ClueApi.serv.dart';
import 'package:gm_flutter/commonModel/GMBase.dart';
import 'package:gm_flutter/commonModel/rx/RxDispose.dart';
import 'package:gm_flutter/commonModel/util/PrintUtil.dart';
import '../../server/entity/ProjectDetailsItem.dart';
class ProjectDetailsModel extends BaseModel {
LiveData<ProjectDetailsItem> liveData = LiveData();
RxDispose rxDispose = RxDispose();
void init() {
ClueApiImpl.getInstance()
.getProjectDetails(DioUtil.getInstance().getDio(), 123)
.listen((event) {
print(event);
if (event.error == 0) {
liveData.notifyView(event);
}
})
.addToDispose(rxDispose)
.onError((err) {
PrintUtil.printBug(err);
});
}
@override
void dispose() {
liveData.dispost();
rxDispose.dispose();
}
}
/*
* @author zcc
* @date 2020-07-01
* 项目说明
**/
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:gm_flutter/ClueModel/page/ProjectDetails/ProjectDetailsItemView.dart';
import 'package:gm_flutter/ClueModel/page/ProjectDetails/ProjectDetailsModel.dart';
import 'package:gm_flutter/commonModel/base/BaseComponent.dart';
import 'package:gm_flutter/commonModel/base/BaseState.dart';
import '../../server/entity/ProjectDetailsItem.dart';
class ProjectDetailsPage extends StatefulWidget {
@override
State<StatefulWidget> createState() => ProjectDetailsState();
}
class ProjectDetailsState extends BaseState<ProjectDetailsPage> {
ProjectDetailsModel _model = new ProjectDetailsModel();
@override
void initState() {
super.initState();
_model.init();
}
@override
void dispose() {
_model.dispose();
super.dispose();
}
@override
Widget buildItem(BuildContext context) {}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: baseAppBar(title: "项目说明",
centerTitle: true,
backClick: (){
Navigator.pop(context);
}),
body: Center(
child: getBody(),
),
);
}
getBody() {
return StreamBuilder(
stream: _model.liveData.stream,
initialData: ProjectDetailsItem(),
builder: (c, data) {
ProjectDetailsItem item = data.data;
if (item == null || item.data == null || item.data.groups == null) {
return loadingItem();
}
return ListView.builder(
itemCount: item.data.groups.length,
itemBuilder: (BuildContext context, int position) {
return ProjectDetailsItemView(item.data.groups[position]);
});
},
);
}
}
......@@ -167,7 +167,7 @@ class LevelOneItem extends StatelessWidget {
Positioned(
left: 57,
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';
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';
import 'package:pull_to_refresh/pull_to_refresh.dart';
class LevelOneModel extends BaseModel {
......@@ -57,17 +58,19 @@ class LevelOneModel extends BaseModel {
cardsLive.notifyView(Pair(ENDLOADING, data));
});
// int index = currentIndex;
// if (clear) {
// data.clear();
// pageList = [1, 1, 1, 1];
// }
// ClueApiImpl.getInstance()
// .getLevelOneList(
// DioUtil.getInstance().getDio(), 123, list[index], pageList[index])
// .listen((event) {})
// .addToDispose(rxDispose)
// .onError((err) {});
int index = currentIndex;
if (clear) {
data.clear();
pageList = [1, 1, 1, 1];
}
ClueApiImpl.getInstance()
.getLevelOneList(
DioUtil.getInstance().getDio(), 123, list[index], pageList[index])
.listen((event) {})
.addToDispose(rxDispose)
.onError((err) {
PrintUtil.printBug(err);
});
}
int currentIndex = 0;
......@@ -96,5 +99,7 @@ class LevelOneModel extends BaseModel {
}
}
void loadMore() {}
void loadMore() {
}
}
......@@ -42,10 +42,10 @@ class LevelOneState extends BaseState<LevelOnePage>
@override
void initState() {
super.initState();
Future.delayed(Duration(seconds: 3), () {
_model.loadingLive.notifyView(false);
_model.refreshView(true);
});
// Future.delayed(Duration(seconds: 3), () {
// _model.loadingLive.notifyView(false);
// _model.refreshView(true);
// });
pageController.addListener(() {
if (screenWidth != null) {
_model.topScrollLive.notifyView(
......@@ -485,13 +485,12 @@ class LevelOneState extends BaseState<LevelOnePage>
height);
}
return Container(
color: Colors.yellow,
width: double.maxFinite,
height: height,
child: PageView.builder(
itemBuilder: (c, pageIndex) {
if (data.data.first == FAIL) {
return errorItem(() {
return errorItem(MediaQuery.of(context).size.width, height, () {
_model.refreshView(true);
});
}
......@@ -501,7 +500,7 @@ class LevelOneState extends BaseState<LevelOnePage>
}
if (data.data.second.length == 0) {
if (_model.pageList[pageIndex] == 1) {
return emptyItem();
return emptyItem(MediaQuery.of(context).size.width, height);
} else {
_refreshController.loadNoData();
}
......
/*
* @author lsy
* @date 2020/7/1
**/
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:gm_flutter/ClueModel/page/plan/PlanProgressBar.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(
bottom: 74.5,
left: 15,
child: Container(
width: MediaQuery.of(context).size.width - 30,
child: PlanProgressBar(0, 5, 0, 10,padding: 15,),
),
),
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);
}
}
This diff is collapsed.
/*
* @author lsy
* @date 2020/7/1
**/
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:gm_flutter/commonModel/base/BaseComponent.dart';
class PlanProgressBar extends StatefulWidget {
int low;
int high;
int maxlow;
int maxHigh;
int padding;
PlanProgressBar(this.low, this.high, this.maxlow, this.maxHigh,
{this.padding});
@override
State<StatefulWidget> createState() => PlanProgressBarState();
}
class PlanProgressBarState extends State<PlanProgressBar> {
double distance;
double leftStarPosPercent;
double leftPosTempPercent;
double rightStarPosPercent;
double rightPosTempPercent;
double leftDowPos;
double rightDowPos;
double scrollDistance;
double leftPos;
double textLeft = -1;
bool isLeftMove = true;
@override
void initState() {
super.initState();
distance = widget.maxHigh - widget.maxlow - 0.0;
leftStarPosPercent = (widget.low / distance);
leftPosTempPercent = leftStarPosPercent;
rightStarPosPercent = (widget.high / distance);
rightPosTempPercent = rightStarPosPercent;
}
@override
Widget build(BuildContext context) {
double totle = MediaQuery.of(context).size.width - widget.padding * 2 - 8;
scrollDistance = 0.05;
double textL = textLeft * totle - 67.5 / 2 + 9;
if (textL < 0) {
textL = 0;
} else if (textL + 67.5 > totle) {
textL = totle - 67.5;
}
return Container(
width: double.maxFinite,
height: 65,
child: Stack(
children: <Widget>[
Positioned(
bottom: 7.5,
left: 4,
child: Container(
width: totle,
height: 4,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(50),
color: Color(0xffD5D5D5)),
),
),
Positioned(
left: leftPosTempPercent * totle + 5,
bottom: 7.5,
child: Container(
height: 4,
width: (rightPosTempPercent - leftPosTempPercent) * totle,
color: Color(0xff51CDC7),
),
),
Positioned(
left: textL,
bottom: 23,
child: Visibility(
visible: textLeft >= 0,
child: Container(
width: 67.5,
height: 42,
color: Color(0x66000000),
alignment: Alignment.center,
child: Column(
children: <Widget>[
baseText(
"${(widget.maxlow + (isLeftMove?leftPosTempPercent:rightPosTempPercent+0.03) * distance).toInt()}",
13,
Colors.white)
],
),
),
),
),
Positioned(
bottom: 0,
left: leftPosTempPercent * totle,
child: Listener(
onPointerDown: (p) {
leftDowPos = p.localPosition.dx;
isLeftMove = true;
},
onPointerMove: (p) {
var d = p.localPosition.dx - leftDowPos;
leftPosTempPercent = leftStarPosPercent + (d / totle);
if (leftPosTempPercent < 0.0) {
leftPosTempPercent = 0;
} else if (leftPosTempPercent >
rightPosTempPercent - scrollDistance) {
leftPosTempPercent = rightPosTempPercent - scrollDistance;
}
textLeft = leftPosTempPercent;
setState(() {});
},
onPointerUp: (p) {
textLeft = -1;
leftStarPosPercent = leftPosTempPercent;
setState(() {});
},
child: Container(
width: 19,
height: 19,
alignment: Alignment.centerLeft,
child: Image.asset(
"assets/progress_inner.png",
),
),
)),
Positioned(
bottom: 0,
left: rightPosTempPercent * totle,
child: Listener(
onPointerDown: (p) {
rightDowPos = p.localPosition.dx;
isLeftMove = false;
},
onPointerMove: (p) {
var d = p.localPosition.dx - rightDowPos;
rightPosTempPercent = rightStarPosPercent + (d / totle);
if (rightPosTempPercent <
leftPosTempPercent + scrollDistance) {
rightPosTempPercent = leftPosTempPercent + scrollDistance;
} else if (rightPosTempPercent > 1.0 - 0.03) {
rightPosTempPercent = 1.0 - 0.03;
}
textLeft = rightPosTempPercent;
setState(() {});
},
onPointerUp: (p) {
textLeft = -1;
rightStarPosPercent = rightPosTempPercent;
setState(() {});
},
child: Container(
width: 19,
height: 19,
alignment: Alignment.centerLeft,
child: Image.asset(
"assets/progress_inner.png",
),
),
)),
],
),
);
}
}
This diff is collapsed.
/*
* @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,
));
}
}
......@@ -6,10 +6,38 @@ import 'package:flutter_common/Annotations/anno/Get.dart';
import 'package:flutter_common/Annotations/anno/Query.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/PlanCompareDetail.dart';
import 'package:gm_flutter/ClueModel/server/entity/PlansCompareFeed.dart';
import 'package:gm_flutter/ClueModel/server/entity/ProjectDetailsItem.dart';
import 'package:gm_flutter/ClueModel/server/entity/PlanBean.dart';
import 'package:gm_flutter/ClueModel/server/entity/PlanFeedBean.dart';
@ServiceCenter()
abstract class ClueApi {
@Get("/api/janus/plans/plan_detail")
ProjectDetailsItem getProjectDetails(@Query("plan_id") int plan_id);
@Get("/api/janus/plans/compare_feed")
PlansCompareFeed getPlansCompareFeed(
@Query("plan_id") int plan_id, @Query("plan_type") int plan_type);
@Get("api/janus/plans/plan_feed")
LevelOneFeedList getLevelOneList(@Query("plan_id") int plan_id,
@Query("tab_type") String tab_type, @Query("page") int page);
@Get("api/janus/plans/compare")
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,
);
}
......@@ -14,7 +14,12 @@ import 'package:dio/dio.dart';
import 'package:flutter/foundation.dart';
import 'package:gm_flutter/ClueModel/server/entity/ProjectDetailsItem.dart';
import 'package:gm_flutter/ClueModel/server/entity/PlansCompareFeed.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/PlanBean.dart';
import 'package:gm_flutter/ClueModel/server/entity/PlanFeedBean.dart';
const bool inProduction = const bool.fromEnvironment("dart.vm.product");
......@@ -32,6 +37,36 @@ class ClueApiImpl {
return _instance;
}
Stream<ProjectDetailsItem> getProjectDetails(Dio _dio, int plan_id) {
return Stream.fromFuture(get(_dio, '/api/janus/plans/plan_detail', data: {
'plan_id': plan_id,
})).flatMap((value) {
if (value != null &&
(value.statusCode >= 200 && value.statusCode < 300)) {
return Stream.fromFuture(
compute(parseProjectDetailsItem, value.toString()));
} else {
throw Exception("--未知网络错误--");
}
});
}
Stream<PlansCompareFeed> getPlansCompareFeed(
Dio _dio, int plan_id, int plan_type) {
return Stream.fromFuture(get(_dio, '/api/janus/plans/compare_feed', data: {
'plan_id': plan_id,
'plan_type': plan_type,
})).flatMap((value) {
if (value != null &&
(value.statusCode >= 200 && value.statusCode < 300)) {
return Stream.fromFuture(
compute(parsePlansCompareFeed, value.toString()));
} else {
throw Exception("--未知网络错误--");
}
});
}
Stream<LevelOneFeedList> getLevelOneList(
Dio _dio, int plan_id, String tab_type, int page) {
return Stream.fromFuture(get(_dio, 'api/janus/plans/plan_feed', data: {
......@@ -49,6 +84,61 @@ class ClueApiImpl {
});
}
Stream<PlanCompareDetail> getPlanCompareDetail(Dio _dio, List<int> plan_ids) {
return Stream.fromFuture(get(_dio, 'api/janus/plans/compare', data: {
'plan_ids': plan_ids,
})).flatMap((value) {
if (value != null &&
(value.statusCode >= 200 && value.statusCode < 300)) {
return Stream.fromFuture(
compute(parsePlanCompareDetail, value.toString()));
} else {
throw Exception("--未知网络错误--");
}
});
}
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==================
Future<Response> get(Dio _dio, url, {data, options, cancelToken}) async {
......@@ -186,6 +276,26 @@ class ClueApiImpl {
}
}
ProjectDetailsItem parseProjectDetailsItem(String value) {
return ProjectDetailsItem.fromJson(json.decode(value));
}
PlansCompareFeed parsePlansCompareFeed(String value) {
return PlansCompareFeed.fromJson(json.decode(value));
}
LevelOneFeedList parseLevelOneFeedList(String value) {
return LevelOneFeedList.fromJson(json.decode(value));
}
PlanCompareDetail parsePlanCompareDetail(String 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));
}
This diff is collapsed.
/*
* @Author: zx
* @Date: 2020-06-30 19:31:32
* @Last Modified by: zx
* @Last Modified time: 2020-07-01 20:31:42
*/
import 'dart:convert';
class PlanCompareDetail {
int error;
String message;
Null extra;
Null errorExtra;
UserType userType;
Data data;
PlanCompareDetail({this.error, this.message, this.extra, this.errorExtra, this.userType, this.data});
PlanCompareDetail.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<PlansInfo> plansInfo;
List<Groups> groups;
Data({this.plansInfo, this.groups});
Data.fromJson(Map<String, dynamic> json) {
if (json['plans_info'] != null) {
plansInfo = new List<PlansInfo>();
json['plans_info'].forEach((v) { plansInfo.add(new PlansInfo.fromJson(v)); });
}
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>();
if (this.plansInfo != null) {
data['plans_info'] = this.plansInfo.map((v) => v.toJson()).toList();
}
if (this.groups != null) {
data['groups'] = this.groups.map((v) => v.toJson()).toList();
}
return data;
}
}
class PlansInfo {
int planId;
String planName;
String minPrice;
String maxPrice;
PlansInfo({this.planId, this.planName, this.minPrice, this.maxPrice});
PlansInfo.fromJson(Map<String, dynamic> json) {
planId = json['plan_id'];
planName = json['plan_name'];
minPrice = json['min_price'];
maxPrice = json['max_price'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['plan_id'] = this.planId;
data['plan_name'] = this.planName;
data['min_price'] = this.minPrice;
data['max_price'] = this.maxPrice;
return data;
}
}
class Groups {
String groupType;
String groupName;
List<Plans> plans;
Groups({this.groupType, this.groupName, this.plans});
Groups.fromJson(Map<String, dynamic> json) {
groupType = json['group_type'];
groupName = json['group_name'];
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>();
data['group_type'] = this.groupType;
data['group_name'] = this.groupName;
if (this.plans != null) {
data['plans'] = this.plans.map((v) => v.toJson()).toList();
}
return data;
}
}
class Plans {
int planId;
String positiveRate;
String salesCount;
List<Attrs> attrs;
Plans({this.planId, this.positiveRate, this.salesCount, this.attrs});
Plans.fromJson(Map<String, dynamic> json) {
planId = json['plan_id'];
positiveRate = json['positive_rate'];
salesCount = json['sales_count'];
if (json['attrs'] != null) {
attrs = new List<Attrs>();
json['attrs'].forEach((v) { attrs.add(new Attrs.fromJson(v)); });
}
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['plan_id'] = this.planId;
data['positive_rate'] = this.positiveRate;
data['sales_count'] = this.salesCount;
if (this.attrs != null) {
data['attrs'] = this.attrs.map((v) => v.toJson()).toList();
}
return data;
}
}
class Attrs {
String attrName;
String attrValue;
Attrs({this.attrName, this.attrValue});
Attrs.fromJson(Map<String, dynamic> json) {
attrName = json['attr_name'];
attrValue = json['attr_value'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['attr_name'] = this.attrName;
data['attr_value'] = this.attrValue;
return data;
}
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -26,10 +26,24 @@ class TestState extends BaseState<TestPage> {
JumpUtil.jumpToPageRight(context, NetProxyPage());
}));
list.add(listItem("一级列表页", () {
JumpUtil.jumpToPageRight(context, RouterCenterImpl().findClueRouter().getLevelOnePage());
JumpUtil.jumpToPageRight(
context, RouterCenterImpl().findClueRouter().getLevelOnePage());
}));
list.add(listItem("二级列表页", () {
JumpUtil.jumpToPageRight(context, RouterCenterImpl().findClueRouter().getLevelTwoPage());
JumpUtil.jumpToPageRight(
context, RouterCenterImpl().findClueRouter().getLevelTwoPage());
}));
list.add(listItem("方案页面", () {
JumpUtil.jumpToPageRight(
context, RouterCenterImpl().findClueRouter().getPlanPage());
}));
list.add(listItem("对比详情页", () {
JumpUtil.jumpToPageRight(context,
RouterCenterImpl().findClueRouter().getPlanCompareDetailPage());
}));
list.add(listItem("项目说明", () {
JumpUtil.jumpToPageRight(
context, RouterCenterImpl().findClueRouter().getProjectDetailsPage());
}));
return list;
}
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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