Commit c8d34ce1 authored by 朱翠翠's avatar 朱翠翠

Merge branch 'test' of http://git.wanmeizhensuo.com/linshengyu/gm_flutter into zcc/flutter

parents 30a027a2 1e0d0eeb
......@@ -2,6 +2,7 @@
* @author lsy
* @date 2020/6/24
**/
import 'package:flutter/material.dart';
import 'package:flutter/src/widgets/framework.dart';
import 'package:gm_flutter/ClueModel/ClueRouter.dart';
import 'package:gm_flutter/ClueModel/page/PlansCompareFeed/PlansCompareFeedPage.dart';
......@@ -22,7 +23,7 @@ class ClueRouterImpl implements ClueRouter {
Widget getLevelOnePage() {
return LevelOnePage();
}
@override
Widget getLevelTwoPage() {
return LevelTwoPage();
......@@ -38,6 +39,7 @@ class ClueRouterImpl implements ClueRouter {
return PlanPage();
}
@override
Widget getPlanCompareDetailPage() {
return PlanCompareDetailPage();
}
......
/*
* @Author: zx
* @Date: 2020-07-03 20:54:59
* @Last Modified by: zx
* @Last Modified time: 2020-07-04 12:20:45
*/
import 'package:dio/dio.dart';
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:flutter_common/commonModel/toast/NativeToast.dart';
import 'package:gm_flutter/commonModel/bean/Pair.dart';
import 'package:gm_flutter/ClueModel/server/entity/DiscussLowPriceModelBean.dart';
import 'package:gm_flutter/ClueModel/server/entity/DiscussLowPriceAuthBean.dart';
class DiscussLowPriceModel extends BaseModel {
LiveData<Pair<int, DiscussLowPriceModelBean>> popViewLive = LiveData();
RxDispose rxDispose = RxDispose();
fetchPopviewData(String planId, String hospitalId, String doctorId) {
ClueApiImpl.getInstance()
.getPopviewData(
DioUtil.getInstance().getDio(), planId, hospitalId, doctorId)
.listen((event) {
if (event.error == 0) {
if (event.data == null) {
popViewLive.notifyView(Pair(ENDLOADING, null));
} else {
popViewLive.notifyView(Pair(ENDLOADING, event.data));
}
} else {
NativeToast.showNativeToast(event.message);
popViewLive.notifyView(Pair(FAIL, null));
}
})
.addToDispose(rxDispose)
.onError((err) {
popViewLive.notifyView(Pair(FAIL, null));
NativeToast.showNativeToast(err.message);
});
}
givePhoneAuth(int leadPhoneRequestId, VoidCallback callback) {
popViewLive.notifyView(Pair(LOADING, null));
ClueApiImpl.getInstance()
.givePhoneAuth(DioUtil.getInstance().getDio(), leadPhoneRequestId)
.listen((event) {
if (event.error == 0) {
} else {
NativeToast.showNativeToast(event.message);
}
callback();
})
.addToDispose(rxDispose)
.onError((err) {
NativeToast.showNativeToast(err.message);
callback();
});
}
@override
void dispose() {
popViewLive.dispost();
rxDispose.dispose();
}
}
/*
* @Author: zx
* @Date: 2020-07-03 13:53:16
* @Last Modified by: zx
* @Last Modified time: 2020-07-04 12:48:35
*/
import 'package:flutter/material.dart';
import 'package:flutter_common/commonModel/picker/base/BaseCenterPicker.dart';
import 'package:gm_flutter/ClueModel/server/entity/DiscussLowPriceModelBean.dart';
import 'package:gm_flutter/commonModel/base/BaseComponent.dart';
import 'package:gm_flutter/ClueModel/page/DiscussLowPrice/DiscussLowPriceModel.dart';
import 'package:gm_flutter/commonModel/bean/Pair.dart';
import 'package:gm_flutter/commonModel/util/DartUtil.dart';
class DiscussLowPricePopView {
static void showPopView(BuildContext content) {
BaseCenterPicker()
..setPicker(_PopView())
..show(content);
}
}
class _PopView implements ICenterPicker {
VoidCallback dismissCallback;
double contentWidth;
DiscussLowPriceModel _model = new DiscussLowPriceModel();
@override
Widget build(BuildContext context, int alp) {
contentWidth = MediaQuery.of(context).size.width - 72;
return StreamBuilder<Pair<int, DiscussLowPriceModelBean>>(
stream: _model.popViewLive.stream,
initialData: _model.popViewLive.data ?? Pair(LOADING, null),
builder: (c, data) {
if (data.data.first == LOADING) {
return loadingItem();
}
if (data.data.second == null || data.data.first == FAIL) {
return errorItem(contentWidth, 308.5, () {});
}
return Opacity(
opacity: alp / 255.0,
child: Container(
width: contentWidth,
height: 308.5,
child: Stack(
alignment: AlignmentDirectional.topCenter,
children: <Widget>[
Positioned(
top: 42.5,
child: setupBodyView(),
),
Positioned(
top: 62.5,
right: 20,
width: 13.5,
height: 13.5,
child: GestureDetector(
onTap: () {
dismissCallback();
},
child: Image.asset(
'assets/discuss_loe_price_cancel.png'),
)),
Container(
width: 85,
height: 85,
decoration: BoxDecoration(boxShadow: [
BoxShadow(
color: Colors.black12,
offset: Offset(0.0, 15.0),
blurRadius: 15.0,
spreadRadius: 1.0)
], shape: BoxShape.circle),
child: ClipOval(
child: Image.network(
_model.popViewLive.data.second.icon,
fit: BoxFit.cover),
),
)
]),
));
});
}
setupBodyView() {
return Container(
height: 266,
width: contentWidth,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(7),
color: Colors.white,
),
child: Container(
alignment: Alignment.center,
margin: EdgeInsets.only(bottom: 0, top: 44),
child: detailView(),
),
);
}
detailView() {
return Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Container(
margin: EdgeInsets.only(bottom: 13.5),
alignment: AlignmentDirectional.center,
child: Row(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Container(
width: 16,
height: 16,
child: Image.asset(
'assets/discuss_loe_price_like.png',
)),
Container(
margin: EdgeInsets.only(left: 4),
child: baseText(_model.popViewLive.data.second.tip, 14,
Color(0xff848484)),
)
]),
),
Container(
margin: EdgeInsets.only(bottom: 25),
child: baseText(
_model.popViewLive.data.second.title, 18, Color(0xff464646),
bold: true)),
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(7),
color: Color(0xffECECEC),
),
alignment: Alignment.center,
margin: EdgeInsets.only(bottom: 12),
width: contentWidth - 70,
height: 37,
child: baseText(_model.popViewLive.data.second.authorizePhone, 16,
Color(0xff484848))),
Container(
margin: EdgeInsets.only(bottom: 14),
width: contentWidth - 70,
height: 37,
// decoration: BoxDecoration(
// borderRadius: BorderRadius.circular(7),
// color: Color.fromARGB(alp, 58, 195, 189)
// ),
child: Image.asset(
"assets/discuss_loe_price_auth.png",
),
).gestureDetector(() {
// 一键授权
_model.givePhoneAuth(111, () {
dismissCallback();
});
}),
Container(
width: contentWidth - 70,
margin: EdgeInsets.only(bottom: 23.5),
child: baseText('授权后,您的手机将以“虚拟号”方式提供给机构', 11, Color(0xff999999))),
]);
}
@override
void dispose() {
_model.dispose();
}
@override
void initState(VoidCallback dismissCall, BuildContext context) {
this.dismissCallback = dismissCall;
_model.fetchPopviewData('1', '2', '3');
}
}
......@@ -53,5 +53,6 @@ class PlanCompareDetailModel extends BaseModel {
void dispose() {
stateLive.dispost();
detailLive.dispost();
headerLive.dispost();
}
}
......@@ -47,13 +47,7 @@ class PlanCompareDetailPageState extends BaseState<PlanCompareDetailPage> {
Navigator.pop(context);
}),
body: Container(
child:
// head(),
// planPopularityView()
// planNormalEffectiveAttrsView()
// setupHome([], []),
reloadPage(),
child: reloadPage(),
));
}
......
......@@ -4,7 +4,6 @@
**/
import 'dart:math';
import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
......@@ -42,10 +41,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(
......@@ -205,27 +204,9 @@ class LevelOneState extends BaseState<LevelOnePage>
},
),
),
Positioned(
top: 49,
left: 15,
child: GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: () {
//TODO
print("TAP");
Navigator.pop(context);
},
child: Container(
width: 30,
height: 30,
decoration: BoxDecoration(
color: Color(0x99FFFFFF), shape: BoxShape.circle),
alignment: Alignment.center,
child: Container(
child: Image.asset("assets/left_arrow.png"),
),
)),
)
baseSliverBack(() {
Navigator.of(context).pop();
})
],
),
),
......@@ -520,8 +501,8 @@ class LevelOneState extends BaseState<LevelOnePage>
controller: pageController,
itemCount: 4,
onPageChanged: (index) {
_refreshController.resetNoData();
setState(() {
_refreshController.resetNoData();
});
_model.topIndexLive.notifyView(index);
_model.selectPage(index);
......
/*
* @author lsy
* @date 2020/7/2
**/
import 'package:flutter/material.dart';
import 'package:gm_flutter/ClueModel/page/plan/PlanItem.dart';
import 'package:gm_flutter/ClueModel/server/entity/PlanFeedBean.dart';
import 'package:gm_flutter/commonModel/base/BaseComponent.dart';
import 'package:pull_to_refresh/pull_to_refresh.dart';
import 'TopListModel.dart';
class TopList extends StatefulWidget {
final int id;
double topHeight;
TopList(this.id, this.topHeight);
@override
State<StatefulWidget> createState() => TopListState();
}
class TopListState extends State<TopList> {
RefreshController refreshController = RefreshController();
TopListModel _model = TopListModel();
@override
void initState() {
super.initState();
_model.getData(true);
print("${this} INIT");
}
@override
void dispose() {
refreshController.dispose();
_model.dispose();
print("${this} QUIT");
super.dispose();
}
@override
Widget build(BuildContext context) {
return baseStateView(MediaQuery.of(context).size.width,
MediaQuery.of(context).size.height, _model.stateLive, home(), () {
_model.getData(true);
});
}
Widget home() {
return baseRefreshView(refreshController, () {}, null, null,
customScrollView: CustomScrollView(
// physics: NeverScrollableScrollPhysics(),
physics: ClampingScrollPhysics(),
// shrinkWrap: true,
slivers: <Widget>[
SliverOverlapInjector(
handle: NestedScrollView.sliverOverlapAbsorberHandleFor(context),
),
StreamBuilder<List<Plans>>(
stream: _model.datasLive.stream,
initialData: _model.datas ?? [],
builder: (c, data) {
print("LLDATA ${data.data}");
if (data.data.isEmpty && _model.page > 1) {
refreshController.loadNoData();
} else {
refreshController.loadComplete();
}
return SliverFixedExtentList(
itemExtent: 100,
delegate: SliverChildBuilderDelegate(
(BuildContext context, int index) {
return PlanItem(_model.datas[index]);
},
childCount: _model.datas.length,
),
);
},
),
StreamBuilder<List<Plans>>(
stream: _model.datasLive.stream,
initialData: _model.datas ?? [],
builder: (c, data) {
double height = MediaQuery.of(context).size.height -
40 -
widget.topHeight -
100 * _model.datas.length;
return SliverToBoxAdapter(
child: Container(
height: height < 0 ? 0 : height,
),
);
},
),
],
), onLoading: () {
_model.loadMore();
}, pullDown: false, pullUp: true);
}
}
/*
* @author lsy
* @date 2020/7/3
**/
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/server/api/ClueApi.serv.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 TopListModel extends BaseModel {
LiveData<int> stateLive = LiveData();
String tagId;
int page = 1;
RxDispose rxDispose = RxDispose();
LiveData<List<Plans>> datasLive = LiveData();
List<Plans> datas = [];
@override
void dispose() {
rxDispose.dispose();
stateLive.dispost();
}
void getData(bool clear) {
if (clear) {
page = 1;
datas.clear();
}
ClueApiImpl.getInstance()
.getPlanFeed(
DioUtil.getInstance().getDio(), tagId, "", "", "", "", "", page)
.listen((event) {
if (event.error == 0) {
if (event.data.plans == null || event.data.plans.isEmpty) {
if (page == 1) {
stateLive.notifyView(EMPTY);
} else {
datasLive.notifyView([]);
}
} else {
datas.addAll(event.data.plans);
datasLive.notifyView(datas);
}
if (page == 1) {
stateLive.notifyView(ENDLOADING);
}
} else {
NativeToast.showNativeToast(event.message);
stateLive.notifyView(FAIL);
}
})
.addToDispose(rxDispose)
.onError((err) {
PrintUtil.printBug(err);
stateLive.notifyView(FAIL);
});
}
void loadMore() {
page++;
getData(false);
}
}
......@@ -4,13 +4,34 @@
**/
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/server/api/ClueApi.serv.dart';
import 'package:gm_flutter/ClueModel/server/entity/PlanBarBean.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 TopModel extends BaseModel {
int tabIndex = 0;
List<String> tabs = ["全部", "眼部", "自体脂肪", "轮廓骨骼"];
List<Tabs> tabs = [];
LiveData<String> titleLive = new LiveData();
LiveData<String> imageLive = LiveData();
LiveData<double> textLive = LiveData();
LiveData<int> stateLive = LiveData();
RxDispose rxDispose = RxDispose();
String rank_type;
String imageUrl;
@override
void dispose() {}
void dispose() {
rxDispose.dispose();
titleLive.dispost();
imageLive.dispost();
stateLive.dispost();
textLive.dispost();
}
void selectTab(int index) {
if (tabIndex == index) {
......@@ -18,4 +39,25 @@ class TopModel extends BaseModel {
}
tabIndex = index;
}
void init(Function(int size) back) {
ClueApiImpl.getInstance()
.getPlanBar(DioUtil.getInstance().getDio(), rank_type)
.listen((event) {
if (event.error == 0) {
stateLive.notifyView(ENDLOADING);
imageUrl = event.data.bannerImage;
tabs = event.data.tabs;
back(tabs.length);
} else {
NativeToast.showNativeToast(event.message);
stateLive.notifyView(FAIL);
}
})
.addToDispose(rxDispose)
.onError((error) {
PrintUtil.printBug(error);
stateLive.notifyView(FAIL);
});
}
}
......@@ -2,15 +2,21 @@
* @author lsy
* @date 2020/7/2
**/
import 'dart:ui';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:gm_flutter/ClueModel/page/levelTwo/LevelTwoPage.dart';
import 'package:gm_flutter/ClueModel/page/top/TopModel.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/view/baseTabIndicator.dart';
import 'package:gm_flutter/commonModel/util/DartUtil.dart';
import 'package:pull_to_refresh/pull_to_refresh.dart';
import 'TopList.dart';
class TopPage extends StatefulWidget {
@override
State<StatefulWidget> createState() => TopPageState();
......@@ -18,17 +24,24 @@ class TopPage extends StatefulWidget {
class TopPageState extends BaseState<TopPage> with TickerProviderStateMixin {
RefreshController refreshController = RefreshController();
TabController tabController;
TopModel _model = TopModel();
GlobalKey globalKey = GlobalKey();
@override
void initState() {
tabController = TabController(length: 4, vsync: this);
init();
super.initState();
}
void init() {
_model.init((i) {
setState(() {});
});
}
@override
void dispose() {
_model.dispose();
refreshController.dispose();
super.dispose();
}
......@@ -36,63 +49,94 @@ class TopPageState extends BaseState<TopPage> with TickerProviderStateMixin {
@override
Widget buildItem(BuildContext context) {
return Scaffold(
body: home(),
body: baseStateView(
MediaQuery.of(context).size.width,
MediaQuery.of(context).size.height,
_model.stateLive,
Stack(
children: <Widget>[
Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
child: NotificationListener(
onNotification: (scrollNotification) {
if (scrollNotification is KeepAliveNotification ||
scrollNotification is OverscrollIndicatorNotification) {
return false;
}
if (scrollNotification is ScrollUpdateNotification &&
scrollNotification.metrics.axisDirection.index == 2) {}
print(
"NOT ${scrollNotification} ${scrollNotification is KeepAliveNotification}");
if (scrollNotification.depth == 0) {
if (scrollNotification.metrics.pixels > 80) {
_model.textLive.notifyView(
(scrollNotification.metrics.pixels - 80) / 40 > 1.0
? 1.0
: (scrollNotification.metrics.pixels - 80) /
40);
} else {
_model.textLive.notifyView(0.0);
}
} else if (scrollNotification.depth == 2) {
if (scrollNotification.metrics.pixels < 50 &&
scrollNotification.metrics.pixels > 0) {
_model.textLive.notifyView(1.0);
}
}
return false;
},
child: home(),
),
),
baseSliverBack(() {
Navigator.of(context).pop();
}),
baseSliverTitle(
"title", MediaQuery.of(context).size.width, _model.textLive)
],
), () {
init();
}),
);
}
Widget home() {
return baseRefreshView(refreshController, () {}, null, null,
customScrollView: CustomScrollView(slivers: <Widget>[
SliverAppBar(
pinned: true,
elevation: 0,
expandedHeight: 0,
flexibleSpace: FlexibleSpaceBar(title: Text('二级方案')),
),
SliverToBoxAdapter(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.max,
children: <Widget>[
Container(
height: 50,
color: Colors.pink,
)
],
)),
SliverPersistentHeader(
pinned: true,
delegate: StickyTabBarDelegate(
child: Container(
height: 40,
color: Colors.white,
child: baseTabBar(tabController, getTabs(), (index) {
_model.selectTab(index);
}),
)),
),
SliverFillRemaining(
child: TabBarView(controller: tabController, children: <Widget>[
Container(
color: Colors.red,
),
Container(
color: Colors.red,
),
Container(
color: Colors.red,
),
Container(
color: Colors.blue,
)
]))
]));
List<Widget> list = [];
var d = MediaQueryData.fromWindow(window).padding.top;
for (int i = 0; i < _model.tabs.length; i++) {
list.add(TopList(_model.tabs[i].id, 48 + d).toActive());
}
return DefaultTabController(
length: _model.tabs.length,
child: NestedScrollView(
headerSliverBuilder:
(BuildContext context, bool innerBoxIsScrolled) {
return <Widget>[
SliverOverlapAbsorber(
handle: NestedScrollView.sliverOverlapAbsorberHandleFor(
context),
sliver: baseSliverAppBar(_model.imageUrl)),
SliverPersistentHeader(
pinned: true,
delegate: StickyTabBarDelegate(
child: Container(
height: 40,
color: Colors.white,
child: baseTabBar(null, getTabs(), (index) {
_model.selectTab(index);
}),
)),
),
];
},
body: TabBarView(children: list)));
}
List<Widget> getTabs() {
List<Widget> list = [];
for (int i = 0; i < _model.tabs.length; i++) {
list.add(baseTabBarItem(_model.tabs[i],
list.add(baseTabBarItem(_model.tabs[i].name,
leftPadding: i == 0 ? 24 : 28,
rightPadding: i == _model.tabs.length - 1 ? 24 : 28));
}
......
......@@ -6,11 +6,16 @@ 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/PlanBarBean.dart';
import 'package:gm_flutter/ClueModel/server/entity/PlanCompareDetail.dart';
import 'package:gm_flutter/ClueModel/server/entity/PlanOverViewBean.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';
import 'package:gm_flutter/ClueModel/server/entity/DiscussLowPriceModelBean.dart';
import 'package:gm_flutter/ClueModel/server/entity/DiscussLowPriceAuthBean.dart';
@ServiceCenter()
abstract class ClueApi {
@Get("/api/janus/plans/plan_detail")
......@@ -25,19 +30,36 @@ abstract class ClueApi {
@Query("tab_type") String tab_type, @Query("page") int page);
@Get("api/janus/plans/compare")
PlanCompareDetail getPlanCompareDetail(@Query("plan_ids") List<int> plan_ids);
PlanCompareDetail getPlanCompareDetail(@Query("plan_ids") List<int> planIds);
@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,
);
@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,
);
@Get("api/janus/plans/rank")
PlanBarBean getPlanBar(@Query("rank_type") String rank_type);
@Get("api/janus/plans/plan_phone_authorize")
DiscussLowPriceModelBean getPopviewData(
@Query("plan_id") String planId,
@Query("hospital_id") String hospitalId,
@Query("doctor_id") String doctorId,
);
@Get("api/janus/plans/agree_phone_authorize")
DiscussLowPriceAuthBean givePhoneAuth(
@Query("lead_phone_request_id") int leadPhoneRequestId);
@Get("api/janus/plans/plan_overview")
PlanOverViewBean getPlanOverView(@Query("plan_id") int plan_id);
}
......@@ -20,6 +20,10 @@ 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';
import 'package:gm_flutter/ClueModel/server/entity/PlanBarBean.dart';
import 'package:gm_flutter/ClueModel/server/entity/DiscussLowPriceModelBean.dart';
import 'package:gm_flutter/ClueModel/server/entity/DiscussLowPriceAuthBean.dart';
import 'package:gm_flutter/ClueModel/server/entity/PlanOverViewBean.dart';
const bool inProduction = const bool.fromEnvironment("dart.vm.product");
......@@ -84,9 +88,9 @@ class ClueApiImpl {
});
}
Stream<PlanCompareDetail> getPlanCompareDetail(Dio _dio, List<int> plan_ids) {
Stream<PlanCompareDetail> getPlanCompareDetail(Dio _dio, List<int> planIds) {
return Stream.fromFuture(get(_dio, 'api/janus/plans/compare', data: {
'plan_ids': plan_ids,
'plan_ids': planIds,
})).flatMap((value) {
if (value != null &&
(value.statusCode >= 200 && value.statusCode < 300)) {
......@@ -139,6 +143,67 @@ class ClueApiImpl {
});
}
Stream<PlanBarBean> getPlanBar(Dio _dio, String rank_type) {
return Stream.fromFuture(get(_dio, 'api/janus/plans/rank', data: {
'rank_type': rank_type,
})).flatMap((value) {
if (value != null &&
(value.statusCode >= 200 && value.statusCode < 300)) {
return Stream.fromFuture(compute(parsePlanBarBean, value.toString()));
} else {
throw Exception("--未知网络错误--");
}
});
}
Stream<DiscussLowPriceModelBean> getPopviewData(
Dio _dio, String planId, String hospitalId, String doctorId) {
return Stream.fromFuture(
get(_dio, 'api/janus/plans/plan_phone_authorize', data: {
'plan_id': planId,
'hospital_id': hospitalId,
'doctor_id': doctorId,
})).flatMap((value) {
if (value != null &&
(value.statusCode >= 200 && value.statusCode < 300)) {
return Stream.fromFuture(
compute(parseDiscussLowPriceModelBean, value.toString()));
} else {
throw Exception("--未知网络错误--");
}
});
}
Stream<DiscussLowPriceAuthBean> givePhoneAuth(
Dio _dio, int leadPhoneRequestId) {
return Stream.fromFuture(
get(_dio, 'api/janus/plans/agree_phone_authorize', data: {
'lead_phone_request_id': leadPhoneRequestId,
})).flatMap((value) {
if (value != null &&
(value.statusCode >= 200 && value.statusCode < 300)) {
return Stream.fromFuture(
compute(parseDiscussLowPriceAuthBean, value.toString()));
} else {
throw Exception("--未知网络错误--");
}
});
}
Stream<PlanOverViewBean> getPlanOverView(Dio _dio, int plan_id) {
return Stream.fromFuture(get(_dio, 'api/janus/plans/plan_overview', data: {
'plan_id': plan_id,
})).flatMap((value) {
if (value != null &&
(value.statusCode >= 200 && value.statusCode < 300)) {
return Stream.fromFuture(
compute(parsePlanOverViewBean, value.toString()));
} else {
throw Exception("--未知网络错误--");
}
});
}
///==================base method==================
Future<Response> get(Dio _dio, url, {data, options, cancelToken}) async {
......@@ -299,3 +364,19 @@ PlanBean parsePlanBean(String value) {
PlanFeedBean parsePlanFeedBean(String value) {
return PlanFeedBean.fromJson(json.decode(value));
}
PlanBarBean parsePlanBarBean(String value) {
return PlanBarBean.fromJson(json.decode(value));
}
DiscussLowPriceModelBean parseDiscussLowPriceModelBean(String value) {
return DiscussLowPriceModelBean.fromJson(json.decode(value));
}
DiscussLowPriceAuthBean parseDiscussLowPriceAuthBean(String value) {
return DiscussLowPriceAuthBean.fromJson(json.decode(value));
}
PlanOverViewBean parsePlanOverViewBean(String value) {
return PlanOverViewBean.fromJson(json.decode(value));
}
/*
* @Author: zx
* @Date: 2020-07-04 11:51:02
* @Last Modified by: zx
* @Last Modified time: 2020-07-04 12:52:22
*/
class DiscussLowPriceAuthBean {
int error;
String message;
Null extra;
Null errorExtra;
UserType userType;
Data data;
DiscussLowPriceAuthBean(
{this.error,
this.message,
this.extra,
this.errorExtra,
this.userType,
this.data});
DiscussLowPriceAuthBean.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 {
bool success;
Data({this.success});
Data.fromJson(Map<String, dynamic> json) {
success = json['success'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['success'] = this.success;
return data;
}
}
/*
* @Author: zx
* @Date: 2020-07-03 20:56:15
* @Last Modified by: zx
* @Last Modified time: 2020-07-03 20:57:44
*/
class DiscussLowPriceModelBean {
int error;
String message;
Null extra;
Null errorExtra;
UserType userType;
Data data;
DiscussLowPriceModelBean(
{this.error,
this.message,
this.extra,
this.errorExtra,
this.userType,
this.data});
DiscussLowPriceModelBean.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 {
int leadPhoneRequestId;
int authorizeType;
String icon;
String tip;
String title;
String authorizePhone;
Data(
{this.leadPhoneRequestId,
this.authorizeType,
this.icon,
this.tip,
this.title,
this.authorizePhone});
Data.fromJson(Map<String, dynamic> json) {
leadPhoneRequestId = json['lead_phone_request_id'];
authorizeType = json['authorize_type'];
icon = json['icon'];
tip = json['tip'];
title = json['title'];
authorizePhone = json['authorize_phone'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['lead_phone_request_id'] = this.leadPhoneRequestId;
data['authorize_type'] = this.authorizeType;
data['icon'] = this.icon;
data['tip'] = this.tip;
data['title'] = this.title;
data['authorize_phone'] = this.authorizePhone;
return data;
}
}
/*
* @author lsy
* @date 2020/7/3
**/
class PlanBarBean {
int error;
String message;
Null extra;
Null errorExtra;
UserType userType;
Data data;
PlanBarBean({this.error, this.message, this.extra, this.errorExtra, this.userType, this.data});
PlanBarBean.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 {
String bannerImage;
List<Tabs> tabs;
Data({this.bannerImage, this.tabs});
Data.fromJson(Map<String, dynamic> json) {
bannerImage = json['banner_image'];
if (json['tabs'] != null) {
tabs = new List<Tabs>();
json['tabs'].forEach((v) { tabs.add(new Tabs.fromJson(v)); });
}
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['banner_image'] = this.bannerImage;
if (this.tabs != null) {
data['tabs'] = this.tabs.map((v) => v.toJson()).toList();
}
return data;
}
}
class Tabs {
bool selected;
int id;
String name;
Tabs({this.selected, this.id, this.name});
Tabs.fromJson(Map<String, dynamic> json) {
selected = json['selected'];
id = json['id'];
name = json['name'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['selected'] = this.selected;
data['id'] = this.id;
data['name'] = this.name;
return data;
}
}
/*
* @author lsy
* @date 2020/7/3
**/
class PlanOverViewBean {
int error;
String message;
Null extra;
Null errorExtra;
UserType userType;
Data data;
PlanOverViewBean(
{this.error,
this.message,
this.extra,
this.errorExtra,
this.userType,
this.data});
PlanOverViewBean.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 {
Banner banner;
String name;
String positiveRate;
String salesCount;
String planDescription;
String guidePrice;
List<OverviewAttrs> overviewAttrs;
List<ExplanationAttrs> explanationAttrs;
List<Tabs> tabs;
Data(
{this.banner,
this.name,
this.positiveRate,
this.salesCount,
this.planDescription,
this.guidePrice,
this.overviewAttrs,
this.explanationAttrs,
this.tabs});
Data.fromJson(Map<String, dynamic> json) {
banner =
json['banner'] != null ? new Banner.fromJson(json['banner']) : null;
name = json['name'];
positiveRate = json['positive_rate'];
salesCount = json['sales_count'];
planDescription = json['plan_description'];
guidePrice = json['guide_price'];
if (json['overview_attrs'] != null) {
overviewAttrs = new List<OverviewAttrs>();
json['overview_attrs'].forEach((v) {
overviewAttrs.add(new OverviewAttrs.fromJson(v));
});
}
if (json['explanation_attrs'] != null) {
explanationAttrs = new List<ExplanationAttrs>();
json['explanation_attrs'].forEach((v) {
explanationAttrs.add(new ExplanationAttrs.fromJson(v));
});
}
if (json['tabs'] != null) {
tabs = new List<Tabs>();
json['tabs'].forEach((v) {
tabs.add(new Tabs.fromJson(v));
});
}
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
if (this.banner != null) {
data['banner'] = this.banner.toJson();
}
data['name'] = this.name;
data['positive_rate'] = this.positiveRate;
data['sales_count'] = this.salesCount;
data['plan_description'] = this.planDescription;
data['guide_price'] = this.guidePrice;
if (this.overviewAttrs != null) {
data['overview_attrs'] =
this.overviewAttrs.map((v) => v.toJson()).toList();
}
if (this.explanationAttrs != null) {
data['explanation_attrs'] =
this.explanationAttrs.map((v) => v.toJson()).toList();
}
if (this.tabs != null) {
data['tabs'] = this.tabs.map((v) => v.toJson()).toList();
}
return data;
}
}
class Banner {
String type;
String imageUrl;
String videoUrl;
Banner({this.type, this.imageUrl, this.videoUrl});
Banner.fromJson(Map<String, dynamic> json) {
type = json['type'];
imageUrl = json['image_url'];
videoUrl = json['video_url'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['type'] = this.type;
data['image_url'] = this.imageUrl;
data['video_url'] = this.videoUrl;
return data;
}
}
class OverviewAttrs {
int attrId;
String attrName;
String attrValue;
OverviewAttrs({this.attrId, this.attrName, this.attrValue});
OverviewAttrs.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;
}
}
class Tabs {
String tabType;
String name;
Tabs({this.tabType, this.name});
Tabs.fromJson(Map<String, dynamic> json) {
tabType = json['tab_type'];
name = json['name'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['tab_type'] = this.tabType;
data['name'] = this.name;
return data;
}
}
class ExplanationAttrs {
int attrId;
String attrName;
String attrValue;
ExplanationAttrs({this.attrId, this.attrName, this.attrValue});
ExplanationAttrs.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;
}
}
......@@ -9,7 +9,7 @@ import 'package:gm_flutter/MainRouter/page/proxy/NetProxyPage.dart';
import 'package:gm_flutter/commonModel/base/BaseComponent.dart';
import 'package:gm_flutter/commonModel/base/BaseState.dart';
import 'package:gm_flutter/main.mark.dart';
import 'package:gm_flutter/ClueModel/page/DiscussLowPrice/DiscussLowPricePopView.dart';
import 'TP.dart';
class TestPage extends StatefulWidget {
......@@ -46,12 +46,15 @@ class TestState extends BaseState<TestPage> {
context, RouterCenterImpl().findClueRouter().getProjectDetailsPage());
}));
list.add(listItem("方案对比", () {
JumpUtil.jumpToPageRight(context, RouterCenterImpl().findClueRouter().getPlansCompareFeed());
JumpUtil.jumpToPageRight(
context, RouterCenterImpl().findClueRouter().getPlansCompareFeed());
}));
list.add(listItem("榜单", () {
JumpUtil.jumpToPageRight(context, RouterCenterImpl().findClueRouter().getTopPage());
JumpUtil.jumpToPageRight(
context, RouterCenterImpl().findClueRouter().getTopPage());
}));
list.add(listItem("弹窗", () {
DiscussLowPricePopView.showPopView(context);
}));
return list;
}
......
......@@ -8,9 +8,11 @@ import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter_common/commonModel/eventbus/GlobalEventBus.dart';
import 'package:flutter_common/commonModel/live/LiveData.dart';
import 'package:flutter_common/commonModel/view/iOSLoading.dart';
import 'package:flutter_svg/svg.dart';
import 'package:gm_flutter/commonModel/GMBase.dart';
import 'package:gm_flutter/commonModel/bean/Pair.dart';
import 'package:gm_flutter/commonModel/util/DartUtil.dart';
import 'package:gm_flutter/commonModel/view/ImagesAnimation.dart';
import 'package:gm_flutter/commonModel/view/baseTabIndicator.dart';
......@@ -289,7 +291,7 @@ Widget baseRefreshView(RefreshController refreshController,
bool pullDown = true,
VoidCallback onLoading,
ScrollController scrollController,
CustomScrollView customScrollView}) {
Widget customScrollView}) {
return SmartRefresher(
enablePullDown: pullDown,
enablePullUp: pullUp,
......@@ -307,9 +309,10 @@ Widget baseRefreshView(RefreshController refreshController,
// body = baseText("加载中", 12, Color(0xff545454));
// } else if (mode == LoadStatus.failed) {
// body = baseText("加载失败", 12, Color(0xff545454));
// } else if (mode == LoadStatus.noMore) {
// body = baseText("没有更多数据了", 12, Color(0xff545454));
// }
// } else
if (mode == LoadStatus.noMore) {
body = baseText("没有更多数据了", 12, Color(0xff545454));
}
// else {
// body = Container();
// }
......@@ -422,7 +425,7 @@ Widget baseTabBarItem(String text,
rightPadding = rightPadding ?? 28.0;
double width = leftPadding + text.length * 16.0 + rightPadding;
return Container(
height: 40,
height: 40.0,
width: wantWidth ?? width,
alignment: Alignment.center,
child: Tab(
......@@ -430,3 +433,77 @@ Widget baseTabBarItem(String text,
),
);
}
Widget baseSliverAppBar(String url, {double height, double elevation}) {
return SliverAppBar(
pinned: true,
centerTitle: true,
elevation: elevation ?? 0,
expandedHeight: height ?? 200,
automaticallyImplyLeading: false,
flexibleSpace: FlexibleSpaceBar(
background: Image.network(
url ?? '',
fit: BoxFit.cover,
),
),
);
}
Widget baseSliverBack(VoidCallback tap) {
return Positioned(
top: 49,
left: 15,
child: GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: tap,
child: Container(
width: 30,
height: 30,
decoration:
BoxDecoration(color: Color(0x99FFFFFF), shape: BoxShape.circle),
alignment: Alignment.center,
child: Container(
child: Image.asset("assets/left_arrow.png"),
),
)),
);
}
Widget baseSliverTitle(String text, double width, LiveData liveData) {
return Positioned(
top: 57,
child: StreamBuilder(
stream: liveData.stream,
initialData: liveData.data ?? 0.0,
builder: (c, data) {
return Opacity(
opacity: data.data,
child: Container(
alignment: Alignment.center,
width: width,
child: baseText(text, 18, Color(0xff333333)),
),
);
},
),
);
}
Widget baseStateView(double width, double height, LiveData<int> stateLive,
Widget home, VoidCallback retry) {
return StreamBuilder(
stream: stateLive.stream,
initialData: stateLive.data ?? LOADING,
builder: (c, data) {
if (data.data == LOADING) {
return loadingItem();
} else if (data.data == FAIL) {
return errorItem(width, height, retry);
} else if (data.data == EMPTY) {
return emptyItem(width, height);
}
return home;
},
);
}
......@@ -5,6 +5,7 @@
const LOADING = 0;
const ENDLOADING = 1;
const FAIL = 2;
const EMPTY = 3;
class Pair<T, S> {
dynamic first;
......
......@@ -211,6 +211,13 @@ packages:
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.1.1"
extended_nested_scroll_view:
dependency: "direct main"
description:
name: extended_nested_scroll_view
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.0.0"
file:
dependency: transitive
description:
......@@ -783,4 +790,4 @@ packages:
version: "2.2.1"
sdks:
dart: ">=2.8.0 <3.0.0"
flutter: ">=1.12.13+hotfix.5 <2.0.0"
flutter: ">=1.17.0 <2.0.0"
......@@ -33,6 +33,7 @@ dependencies:
shared_preferences: ^0.5.7+1
lottie: ^0.4.0+1
app_settings: ^4.0.1+1
extended_nested_scroll_view: ^1.0.0
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