Commit c6262e53 authored by 林生雨's avatar 林生雨

Merge branch 'featrue/duxin' into 'test'

Featrue/duxin

See merge request !12
parents 1a78c166 478d8063
import 'package:flutter/material.dart';
class StickyTabBarDelegate extends SliverPersistentHeaderDelegate {
final Widget child;
StickyTabBarDelegate({@required this.child});
@override
Widget build(
BuildContext context, double shrinkOffset, bool overlapsContent) {
return this.child;
}
@override
double get maxExtent => 40;
@override
double get minExtent => 40;
@override
bool shouldRebuild(SliverPersistentHeaderDelegate oldDelegate) {
return true;
}
}
...@@ -25,7 +25,7 @@ class LevelOneList extends StatefulWidget { ...@@ -25,7 +25,7 @@ class LevelOneList extends StatefulWidget {
} }
class LevelOneListState extends State<LevelOneList> class LevelOneListState extends State<LevelOneList>
with AutomaticKeepAliveClientMixin{ with AutomaticKeepAliveClientMixin {
LevelOneListModel _model = LevelOneListModel(); LevelOneListModel _model = LevelOneListModel();
RefreshController refreshController = RefreshController(); RefreshController refreshController = RefreshController();
...@@ -83,7 +83,7 @@ class LevelOneListState extends State<LevelOneList> ...@@ -83,7 +83,7 @@ class LevelOneListState extends State<LevelOneList>
return SliverList( return SliverList(
delegate: SliverChildBuilderDelegate( delegate: SliverChildBuilderDelegate(
(BuildContext context, int index) { (BuildContext context, int index) {
if(index==_model.data.length){ if (index == _model.data.length) {
return Container( return Container(
height: 40, height: 40,
color: Color(0xffF7F6FA), color: Color(0xffF7F6FA),
...@@ -93,7 +93,7 @@ class LevelOneListState extends State<LevelOneList> ...@@ -93,7 +93,7 @@ class LevelOneListState extends State<LevelOneList>
,lowPrice: (){ ,lowPrice: (){
},); },);
}, },
childCount: _model.data.length+1, childCount: _model.data.length + 1,
), ),
); );
}, },
......
...@@ -10,18 +10,13 @@ import 'package:extended_nested_scroll_view/extended_nested_scroll_view.dart' ...@@ -10,18 +10,13 @@ import 'package:extended_nested_scroll_view/extended_nested_scroll_view.dart'
as extend; as extend;
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:gm_flutter/ClueModel/page/common/StickyTabBarDelegate.dart';
import 'package:gm_flutter/ClueModel/page/levelOne/LevelOneList.dart'; import 'package:gm_flutter/ClueModel/page/levelOne/LevelOneList.dart';
import 'package:gm_flutter/ClueModel/page/levelOne/LevelOneModel.dart'; import 'package:gm_flutter/ClueModel/page/levelOne/LevelOneModel.dart';
import 'package:gm_flutter/ClueModel/page/levelTwo/LevelTwoPage.dart';
import 'package:gm_flutter/commonModel/App.dart';
import 'package:gm_flutter/commonModel/GMBase.dart'; import 'package:gm_flutter/commonModel/GMBase.dart';
import 'package:gm_flutter/commonModel/base/BaseComponent.dart'; import 'package:gm_flutter/commonModel/base/BaseComponent.dart';
import 'package:gm_flutter/commonModel/base/BaseState.dart'; import 'package:gm_flutter/commonModel/base/BaseState.dart';
import 'package:gm_flutter/commonModel/base/BaseUtil.dart';
import 'package:gm_flutter/commonModel/cache/CacheManager.dart';
import 'package:gm_flutter/commonModel/eventbus/SimpleEventBus.dart'; import 'package:gm_flutter/commonModel/eventbus/SimpleEventBus.dart';
import 'package:gm_flutter/commonModel/util/DartUtil.dart';
import 'package:gm_flutter/commonModel/view/baseRefreshIndicator.dart'; import 'package:gm_flutter/commonModel/view/baseRefreshIndicator.dart';
import 'package:gm_flutter/main.mark.dart'; import 'package:gm_flutter/main.mark.dart';
import 'package:pull_to_refresh/pull_to_refresh.dart'; import 'package:pull_to_refresh/pull_to_refresh.dart';
......
/*
* @author lsy
* @date 2020/6/29
**/
import 'package:flutter/material.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/server/api/ClueApi.serv.dart';
import 'package:gm_flutter/ClueModel/server/entity/PlanOverViewBean.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 LevelOneModel extends BaseModel {
LiveData<int> stateLive = LiveData();
LiveData<double> textLive = LiveData();
RxDispose rxDispose = RxDispose();
List<Tabs> tabsList = [];
int plan_id = 0;
PlanOverData planoverItem;
void init(VoidCallback callback) {
ClueApiImpl.getInstance()
.getPlanOverView(DioUtil.getInstance().getDio(), plan_id)
.listen((event) {
if (event.error == 0) {
planoverItem = event.data;
tabsList = event.data.tabs;
stateLive.notifyView(ENDLOADING);
callback();
} else {
NativeToast.showNativeToast(event.message);
stateLive.notifyView(FAIL);
}
})
.addToDispose(rxDispose)
.onError((err) {
PrintUtil.printBug(err);
stateLive.notifyView(FAIL);
});
}
int currentIndex = 0;
@override
void dispose() {
stateLive.dispost();
textLive.dispost();
}
void selectTab(int index) {}
}
/*
* @author lsy
* @date 2020/6/29
**/
import 'package:flutter/material.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/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:pull_to_refresh/pull_to_refresh.dart';
class LevelTwoModel extends BaseModel {
LiveData<double> appBarLive = LiveData();
LiveData<List<String>> rectLive = LiveData();
LiveData<List<String>> explainLive = LiveData();
LiveData<bool> showTab = LiveData();
LiveData<int> topIndexLive = new LiveData();
LiveData<double> topScrollLive = new LiveData();
LiveData<bool> loadingLive = LiveData();
RxDispose rxDispose = RxDispose();
LiveData<Pair<int, List<Cards>>> cardsLive = LiveData();
Map<int, List<Cards>> data = new Map();
List list = ["plan", "hospital", "doctor", "diary"];
List pageList = [1, 1, 1, 1];
List pageHeightList = [118, 149, 118, 118];
void refreshView(bool clear, {RefreshController refreshListener}) {
Future.delayed(Duration(seconds: 1), () {
Cards cards = Cards(
cardType: "plan",
plan: Plan(planName: "ww", minPrice: "50", maxPrice: "500"));
List<Cards> a = [
cards,
cards,
cards,
cards,
cards,
cards,
cards,
cards,
cards,
cards,
cards,
cards,
];
List<Cards> b = [cards];
print("INDEX ${currentIndex}");
if (currentIndex == 1) {
data[currentIndex] = b;
} else {
data[currentIndex] = a;
}
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 currentIndex = 0;
@override
void dispose() {
showTab.dispost();
cardsLive.dispost();
appBarLive.dispost();
rectLive.dispost();
topIndexLive.dispost();
topScrollLive.dispost();
loadingLive.dispost();
}
void selectPage(int index) {
if (currentIndex == index) {
return;
}
currentIndex = index;
if (data[currentIndex] == null) {
cardsLive.notifyView(Pair(LOADING, null));
refreshView(true);
} else {
cardsLive.notifyView(Pair(ENDLOADING, data[currentIndex]));
}
}
void loadMore() {}
}
/* /*
* @author dx * @author lsy
* @date 2020-06-29 * @date 2020/6/29
**/ **/
import 'dart:async';
import 'dart:math'; import 'dart:math';
import 'dart:ui';
import 'package:cached_network_image/cached_network_image.dart'; import 'package:extended_nested_scroll_view/extended_nested_scroll_view.dart'
import 'package:flutter/gestures.dart'; as extend;
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_common/commonModel/picker/base/BaseBottomPicker.dart'; import 'package:flutter_common/commonModel/picker/base/BaseBottomPicker.dart';
import 'package:gm_flutter/ClueModel/page/levelOne/LevelOneItem.dart'; import 'package:gm_flutter/ClueModel/page/common/StickyTabBarDelegate.dart';
import 'package:gm_flutter/ClueModel/page/levelTwo/LevelTwoModel.dart'; import 'package:gm_flutter/ClueModel/page/levelOne/LevelOneList.dart';
import 'package:gm_flutter/ClueModel/page/levelOne/LevelOneModel.dart';
import 'package:gm_flutter/ClueModel/page/mechanismBox/MechanismBoxPage.dart'; import 'package:gm_flutter/ClueModel/page/mechanismBox/MechanismBoxPage.dart';
import 'package:gm_flutter/ClueModel/server/entity/LevelOneFeedList.dart';
import 'package:gm_flutter/ClueModel/view/FiveStarView.dart';
import 'package:gm_flutter/commonModel/base/BaseState.dart';
import 'package:gm_flutter/commonModel/base/BaseUtil.dart';
import 'package:gm_flutter/commonModel/base/BaseComponent.dart'; import 'package:gm_flutter/commonModel/base/BaseComponent.dart';
import 'package:gm_flutter/commonModel/base/BaseState.dart';
import 'package:gm_flutter/commonModel/eventbus/SimpleEventBus.dart';
import 'package:gm_flutter/commonModel/view/baseRefreshIndicator.dart';
import 'package:gm_flutter/main.mark.dart';
import 'package:pull_to_refresh/pull_to_refresh.dart'; import 'package:pull_to_refresh/pull_to_refresh.dart';
import 'package:gm_flutter/commonModel/bean/Pair.dart';
class LevelTwoPage extends StatefulWidget { class LevelTwoPage extends StatefulWidget {
@override @override
_LevelTwoPageState createState() => _LevelTwoPageState(); State<StatefulWidget> createState() => LevelTwoState();
} }
class _LevelTwoPageState extends BaseState<LevelTwoPage> class LevelTwoState extends BaseState<LevelTwoPage>
with SingleTickerProviderStateMixin { with SingleTickerProviderStateMixin {
LevelTwoModel _model = new LevelTwoModel(); int planId = 10;
LevelOneModel _model = new LevelOneModel();
RefreshController _refreshController = RefreshController(); RefreshController _refreshController = RefreshController();
PageController pageController = new PageController(); GlobalKey keyTop = new GlobalKey();
GlobalKey key1 = new GlobalKey();
double screenWidth;
List<Widget> oneList = new List();
int lastPageIndex = 0;
TabController tabController; TabController tabController;
int index = 0;
@override @override
void initState() { void initState() {
super.initState(); super.initState();
this.tabController = TabController(length: 2, vsync: this); _model.init(() {
_initTabBar();
});
}
void _initTabBar() {
if (tabController != null) {
tabController.removeListener(tabControlerListener);
}
tabController = TabController(
initialIndex: index, length: _model.tabsList.length, vsync: this);
tabController.addListener(tabControlerListener);
setState(() {});
} }
@override @override
void dispose() { void dispose() {
tabController?.removeListener(tabControlerListener);
tabController?.dispose();
_model.dispose(); _model.dispose();
pageController.dispose();
_refreshController.dispose(); _refreshController.dispose();
super.dispose(); super.dispose();
} }
void tabControlerListener() {
if (index != tabController.index) {
index = tabController.index;
}
}
@override @override
Widget buildItem(BuildContext context) { Widget buildItem(BuildContext context) {
oneList.clear();
oneList.add(good());
oneList.add(rect());
oneList.add(explain());
oneList.add(Container(
height: 5,
color: Color(0xffF7F6FA),
));
screenWidth = MediaQuery.of(context).size.width;
return Scaffold( return Scaffold(
body: Stack( backgroundColor: Colors.white,
body: SafeArea(
top: false,
child: baseStateView(
MediaQuery.of(context).size.width,
MediaQuery.of(context).size.height,
_model.stateLive,
Container(
child: BaseNestedScrollViewRefreshIndicator(
onRefresh: () async {
Completer completer = new Completer();
_model.init(() {
_initTabBar();
SimpleEventBus.instance()
.notifyListener("LevelOneList", "");
completer.complete();
});
return completer.future;
},
child: newHomeWarp()),
), () {
_model.init(() {
_initTabBar();
});
})));
}
Widget newHomeWarp() {
return Stack(
children: <Widget>[ children: <Widget>[
CustomScrollView(slivers: <Widget>[ Container(
SliverAppBar( width: MediaQuery.of(context).size.width,
pinned: true, height: MediaQuery.of(context).size.height,
elevation: 0, child: NotificationListener(
expandedHeight: 0, onNotification: (scrollNotification) {
flexibleSpace: FlexibleSpaceBar(title: Text('二级方案')), if (scrollNotification is KeepAliveNotification ||
), scrollNotification is OverscrollIndicatorNotification) {
SliverToBoxAdapter( return false;
child: Column( }
crossAxisAlignment: CrossAxisAlignment.start, if (scrollNotification is ScrollUpdateNotification &&
mainAxisSize: MainAxisSize.max, scrollNotification.metrics.axisDirection.index == 2) {}
children: <Widget>[good(), rect(), explain()], 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: newHome(),
)), )),
baseSliverTitle(_model.planoverItem?.name,
MediaQuery.of(context).size.width, _model.textLive),
baseSliverBack(() {
Navigator.of(context).pop();
}),
bottomWidget()
],
);
}
Widget newHome() {
List<Widget> list = [];
var d = MediaQueryData.fromWindow(window).padding.top;
for (int i = 0; i < _model.tabsList.length; i++) {
list.add(extend.NestedScrollViewInnerScrollPositionKeyWidget(
Key("Tab${i}"),
LevelOneList(
planId, _model.tabsList[i].tabType, kToolbarHeight + d)));
}
final double statusBarHeight = MediaQuery.of(context).padding.top;
final double pinnedHeaderHeight = statusBarHeight + kToolbarHeight;
return extend.NestedScrollView(
innerScrollPositionKeyBuilder: () {
String index = 'Tab${tabController.index.toString()}';
return Key(index);
},
headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
return <Widget>[
SliverList(
delegate: SliverChildBuilderDelegate((BuildContext c, int i) {
if (i == 0) {
return Container(
height: pinnedHeaderHeight,
);
}
return oneList[i - 1];
}, childCount: oneList.length + 1)),
SliverPersistentHeader( SliverPersistentHeader(
pinned: true, pinned: true,
delegate: StickyTabBarDelegate( delegate: StickyTabBarDelegate(
child: baseTabBar(tabController, child: Container(
[baseTabBarItem("医院"), baseTabBarItem("医生")], (index) {}, height: 40,
scroll: false), color: Colors.white,
), child: baseTabBar(tabController, getTabs(), (index) {
_model.selectTab(index);
}, scroll: false),
)),
), ),
SliverFillRemaining( ];
child: TabBarView( },
controller: this.tabController, body: TabBarView(controller: tabController, children: list));
children: <Widget>[pages(), pages()])) }
]),
Positioned(left: 0, right: 0, bottom: 0, child: bottomWidget()) List<Widget> getTabs() {
], List<Widget> list = [];
)); for (int i = 0; i < _model.tabsList.length; i++) {
list.add(baseTabBarItem(_model.tabsList[i].name,
leftPadding: i == 0 ? 24 : 28,
rightPadding: i == _model.tabsList.length - 1 ? 24 : 28));
}
return list;
} }
Widget good() { Widget good() {
return StreamBuilder( if (_model.planoverItem == null) {
stream: _model.rectLive.stream, return Container(
initialData: ["w", "w", "q", "w"], height: 54,
builder: (context, data) { );
}
return Padding( return Padding(
padding: EdgeInsets.only(left: 15.0, right: 15.0, top: 8.0), padding: EdgeInsets.only(left: 15.0, right: 15.0, top: 8.0),
child: Row( child: Row(
...@@ -100,7 +229,7 @@ class _LevelTwoPageState extends BaseState<LevelTwoPage> ...@@ -100,7 +229,7 @@ class _LevelTwoPageState extends BaseState<LevelTwoPage>
borderRadius: BorderRadius.circular(17), borderRadius: BorderRadius.circular(17),
border: Border.all(color: Color(0xffF9F8FB), width: 1)), border: Border.all(color: Color(0xffF9F8FB), width: 1)),
child: Image.network( child: Image.network(
'https://img1.gamersky.com/image2019/07/20190725_ll_red_136_2/gamersky_07small_14_201972510258D0.jpg', _model.planoverItem.banner.imageUrl,
width: 86, width: 86,
height: 86, height: 86,
fit: BoxFit.cover, fit: BoxFit.cover,
...@@ -112,7 +241,7 @@ class _LevelTwoPageState extends BaseState<LevelTwoPage> ...@@ -112,7 +241,7 @@ class _LevelTwoPageState extends BaseState<LevelTwoPage>
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.max, mainAxisSize: MainAxisSize.max,
children: <Widget>[ children: <Widget>[
Text('乔雅登玻尿酸(药品类)', Text(_model.planoverItem.name,
style: TextStyle( style: TextStyle(
color: Color(0xff333333), color: Color(0xff333333),
fontSize: 15, fontSize: 15,
...@@ -126,9 +255,9 @@ class _LevelTwoPageState extends BaseState<LevelTwoPage> ...@@ -126,9 +255,9 @@ class _LevelTwoPageState extends BaseState<LevelTwoPage>
style: TextStyle( style: TextStyle(
color: Color(0xff999999), fontSize: 12)), color: Color(0xff999999), fontSize: 12)),
Text( Text(
'¥2000-5000', '¥' + _model.planoverItem.guidePrice,
style: TextStyle( style:
color: Color(0xffFF5963), fontSize: 12), TextStyle(color: Color(0xffFF5963), fontSize: 12),
) )
], ],
) )
...@@ -137,19 +266,17 @@ class _LevelTwoPageState extends BaseState<LevelTwoPage> ...@@ -137,19 +266,17 @@ class _LevelTwoPageState extends BaseState<LevelTwoPage>
], ],
), ),
); );
},
);
} }
Widget rect() { Widget rect() {
return Padding( if (_model.planoverItem == null) {
padding: EdgeInsets.only(top: 20), return Container(
child: StreamBuilder<List<String>>( height: 62,
stream: _model.rectLive.stream, );
initialData: ["w", "w", "q", "w", "w", "w", "q", "w"], }
builder: (c, data) {
List<Widget> list = List(); List<Widget> list = List();
for (int i = 0; i < data.data.length; i += 2) { int i = 0;
_model.planoverItem.overviewAttrs.forEach((element) {
list.add(Expanded( list.add(Expanded(
child: Container( child: Container(
alignment: Alignment.center, alignment: Alignment.center,
...@@ -157,20 +284,21 @@ class _LevelTwoPageState extends BaseState<LevelTwoPage> ...@@ -157,20 +284,21 @@ class _LevelTwoPageState extends BaseState<LevelTwoPage>
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[ children: <Widget>[
baseText(data.data[i], 14, Color(0xff282828), bold: true), baseText(element.attrName, 14, Color(0xff282828), bold: true),
baseText(data.data[i + 1], 11, Color(0xff999999)), baseText(element.attrValue, 11, Color(0xff999999)),
], ],
), ),
), ),
)); ));
if (i < data.data.length - 2) { if (i != _model.planoverItem?.overviewAttrs.length - 1) {
list.add(Container( list.add(Container(
width: 0.5, width: 0.5,
height: 18, height: 18,
color: Color(0xFFE5E5E5), color: Color(0xFFE5E5E5),
)); ));
} }
} i++;
});
return Container( return Container(
decoration: BoxDecoration( decoration: BoxDecoration(
borderRadius: BorderRadius.circular(4), borderRadius: BorderRadius.circular(4),
...@@ -184,16 +312,9 @@ class _LevelTwoPageState extends BaseState<LevelTwoPage> ...@@ -184,16 +312,9 @@ class _LevelTwoPageState extends BaseState<LevelTwoPage>
children: list, children: list,
), ),
); );
},
),
);
} }
Widget explain() { Widget explain() {
return StreamBuilder<List<String>>(
stream: _model.explainLive.stream,
initialData: ["www", "www", "www", "??"],
builder: (c, data) {
List<Widget> list = []; List<Widget> list = [];
list.add(Container( list.add(Container(
height: 31, height: 31,
...@@ -206,6 +327,13 @@ class _LevelTwoPageState extends BaseState<LevelTwoPage> ...@@ -206,6 +327,13 @@ class _LevelTwoPageState extends BaseState<LevelTwoPage>
GestureDetector( GestureDetector(
onTap: () { onTap: () {
//TODO //TODO
Map<String, dynamic> map = {};
map["page_name"] = "plan_home";
map["referrer_link"] = [];
RouterCenterImpl()
.findMainRouter()
.buriedEvent("on_click_navbar_search", map);
}, },
behavior: HitTestBehavior.opaque, behavior: HitTestBehavior.opaque,
child: baseText("了解更多", 12, Color(0xff3FB5AF)), child: baseText("了解更多", 12, Color(0xff3FB5AF)),
...@@ -213,19 +341,21 @@ class _LevelTwoPageState extends BaseState<LevelTwoPage> ...@@ -213,19 +341,21 @@ class _LevelTwoPageState extends BaseState<LevelTwoPage>
], ],
), ),
)); ));
for (int i = 0; i < data.data.length; i += 2) { if (_model.planoverItem != null) {
_model.planoverItem.explanationAttrs.forEach((element) {
list.add(Container( list.add(Container(
height: 28, height: 28,
child: Row( child: Row(
children: <Widget>[ children: <Widget>[
baseText(data.data[i], 13, Color(0xff999999)), baseText(element.attrName, 13, Color(0xff999999)),
Container( Container(
margin: EdgeInsets.only(left: 12), margin: EdgeInsets.only(left: 12),
child: baseText(data.data[i + 1], 13, Color(0xff666666)), child: baseText(element.attrValue, 13, Color(0xff666666)),
) )
], ],
), ),
)); ));
});
} }
return Container( return Container(
margin: EdgeInsets.only(left: 15, right: 15, bottom: 20), margin: EdgeInsets.only(left: 15, right: 15, bottom: 20),
...@@ -234,14 +364,16 @@ class _LevelTwoPageState extends BaseState<LevelTwoPage> ...@@ -234,14 +364,16 @@ class _LevelTwoPageState extends BaseState<LevelTwoPage>
children: list, children: list,
), ),
); );
},
);
} }
// 底部按钮
Widget bottomWidget() { Widget bottomWidget() {
return Container( return Align(
alignment: Alignment.bottomCenter,
child: Container(
width: double.maxFinite, width: double.maxFinite,
height: 55, height: 55,
color: Colors.white,
child: Row( child: Row(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center,
...@@ -268,7 +400,7 @@ class _LevelTwoPageState extends BaseState<LevelTwoPage> ...@@ -268,7 +400,7 @@ class _LevelTwoPageState extends BaseState<LevelTwoPage>
behavior: HitTestBehavior.opaque, behavior: HitTestBehavior.opaque,
onTap: () { onTap: () {
BaseBottomPicker() BaseBottomPicker()
..setPicker(MechanismBox()) ..setPicker(MechanismBox(12))
..show(context); ..show(context);
}, },
child: Container( child: Container(
...@@ -299,207 +431,6 @@ class _LevelTwoPageState extends BaseState<LevelTwoPage> ...@@ -299,207 +431,6 @@ class _LevelTwoPageState extends BaseState<LevelTwoPage>
) )
], ],
), ),
);
}
Widget pages() {
return Container(
margin: EdgeInsets.only(top: 5),
width: double.maxFinite,
child: ListView.builder(
physics: NeverScrollableScrollPhysics(),
itemBuilder: (c, index) {
return Text('$index');
},
itemCount: 5,
));
}
}
Widget DoctorItem(BuildContext context, cards) {
if (cards.doctor == null && isDebug) {
throw new Exception();
}
return GestureDetector(
child: Container(
margin: EdgeInsets.only(left: 15, right: 15),
height: 127,
child: Stack(
children: <Widget>[
Positioned(
top: 15,
child: Container(
width: 45,
height: 45,
child: ClipOval(
child: CachedNetworkImage(
imageUrl: cards.doctor.portrait,
),
),
),
),
Positioned(
left: 57,
top: 18,
child: Row(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.end,
children: <Widget>[
baseText(cards.doctor.name, 15, Color(0xff333333), bold: true),
Container(
margin: EdgeInsets.only(left: 4),
child: baseText(cards.doctor.name, 15, Color(0xff333333),
bold: true),
)
],
),
),
Positioned(
top: 42,
right: 0,
child: Row(
crossAxisAlignment: CrossAxisAlignment.end,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
baseText("¥", 12, Color(0xffFF5963)),
baseText("${cards.doctor.minPrice}-${cards.doctor.maxPrice}",
15, Color(0xffFF5963)),
],
),
),
Positioned(
bottom: 15,
right: 0,
child: lowPriceWidget(),
),
Positioned(
bottom: 15,
right: 187,
child: askWidget(),
),
],
),
),
);
}
Widget HospitalItem(BuildContext context, cards) {
if (cards.hospital == null && isDebug) {
throw new Exception();
}
return GestureDetector(
onTap: () {},
child: Container(
margin: EdgeInsets.only(left: 15, right: 15),
height: 149,
child: Stack(
children: <Widget>[
Positioned(
left: 0,
top: 15,
child: Container(
width: 45,
height: 45,
child: ClipOval(
child: CachedNetworkImage(
imageUrl: cards.hospital.portrait,
),
),
),
),
Positioned(
left: 57,
top: 17.5,
child: baseText(cards.hospital.name, 15, Color(0xff333333),
bold: true),
),
Positioned(
top: 42.5,
right: 0,
child: Row(
crossAxisAlignment: CrossAxisAlignment.end,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
baseText("¥", 12, Color(0xffFF5963)),
baseText(
"${cards.hospital.minPrice}-${cards.hospital.maxPrice}",
15,
Color(0xffFF5963)),
],
),
),
Positioned(
bottom: 15,
right: 0,
child: lowPriceWidget(),
),
Positioned(
bottom: 15,
right: 187,
child: askWidget(),
),
Positioned(
bottom: 67,
left: 57,
child: baseText(cards.hospital.address, 12, Color(0xff666666)),
),
Positioned(
left: 57,
top: 43.5,
child: FiveStarView(cards.hospital.star, 5),
)
],
),
)); ));
}
Widget lowPriceWidget() {
return GestureDetector(
behavior: HitTestBehavior.opaque,
child: Container(
width: 122,
height: 37,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(18.5), color: Color(0xffFFF5F5)),
alignment: Alignment.center,
child: baseText("获取底价", 14, Color(0xffFF5963), bold: true),
),
);
}
Widget askWidget() {
return GestureDetector(
behavior: HitTestBehavior.opaque,
child: Container(
width: 122,
height: 37,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(18.5), color: Color(0xffEEFDFD)),
alignment: Alignment.center,
child: baseText("咨询", 14, Color(0xff3FB5AF), bold: true),
),
);
}
class StickyTabBarDelegate extends SliverPersistentHeaderDelegate {
final Widget child;
StickyTabBarDelegate({@required this.child});
@override
Widget build(
BuildContext context, double shrinkOffset, bool overlapsContent) {
return this.child;
}
@override
double get maxExtent => 40;
@override
double get minExtent => 40;
@override
bool shouldRebuild(SliverPersistentHeaderDelegate oldDelegate) {
return true;
} }
} }
import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_common/commonModel/picker/base/BaseBottomPicker.dart'; import 'package:flutter_common/commonModel/picker/base/BaseBottomPicker.dart';
import 'package:flutter_common/commonModel/toast/NativeToast.dart';
import 'package:gm_flutter/ClueModel/view/FiveStarView.dart';
import 'package:gm_flutter/commonModel/base/BaseComponent.dart';
import 'package:gm_flutter/ClueModel/page/mechanismBox/MechanismModel.dart';
import 'package:gm_flutter/commonModel/bean/Pair.dart';
class MechanismBox implements IBottomPicker { class MechanismBox implements IBottomPicker {
VoidCallback dismissCall; VoidCallback dismissCall;
TextEditingController textController = TextEditingController(); TextEditingController textController = TextEditingController();
MechanismModel _model = new MechanismModel();
List<int> doctor_ids = new List();
@required
final int plan_id;
MechanismBox(this.plan_id) : super();
@override @override
initState(dismissCall, BuildContext context) { initState(dismissCall, BuildContext context) {
this.dismissCall = dismissCall; this.dismissCall = dismissCall;
_model.getQuestions(plan_id);
} }
Widget build(BuildContext context) { Widget build(BuildContext context) {
...@@ -19,15 +34,49 @@ class MechanismBox implements IBottomPicker { ...@@ -19,15 +34,49 @@ class MechanismBox implements IBottomPicker {
width: mq.size.width, width: mq.size.width,
height: mq.size.height - 140, height: mq.size.height - 140,
color: Colors.white, color: Colors.white,
child: Stack( child: StreamBuilder(
stream: _model.stateLive.stream,
initialData: _model.stateLive.data ?? LOADING,
builder: (c, data) {
if (data.data == FAIL) {
return errorItem(MediaQuery.of(context).size.width,
MediaQuery.of(context).size.height, () {
_model.getQuestions(plan_id);
});
}
if (data.data == LOADING) {
return loadingItem();
}
return setupHome(mq, keyHeight);
},
)),
);
}
@override
void dispose() {
textController.dispose();
}
setupHome(mq, keyHeight) {
return Column(
mainAxisSize: MainAxisSize.max,
children: <Widget>[ children: <Widget>[
Container( title(mq),
mechanismList(mq, keyHeight),
bottomMessage()
],
);
}
// 弹窗标题
Widget title(mq) {
return Container(
margin: EdgeInsets.only(left: 20, right: 20), margin: EdgeInsets.only(left: 20, right: 20),
width: mq.size.width, width: mq.size.width,
decoration: BoxDecoration( decoration: BoxDecoration(
border: Border( border:
bottom: Border(bottom: BorderSide(width: 1, color: Color(0xffE5E5E5)))),
BorderSide(width: 1, color: Color(0xffE5E5E5)))),
height: 50, height: 50,
child: Stack( child: Stack(
alignment: Alignment.center, alignment: Alignment.center,
...@@ -56,38 +105,106 @@ class MechanismBox implements IBottomPicker { ...@@ -56,38 +105,106 @@ class MechanismBox implements IBottomPicker {
)) ))
], ],
), ),
), );
Container( }
height: mq.size.height - 140 - 96 - 50,
// 机构列表
Widget mechanismList(mq, keyHeight) {
return Container(
height: mq.size.height - 140 - 96 - 50 - keyHeight,
width: mq.size.width, width: mq.size.width,
margin: EdgeInsets.only(top: 50), padding: EdgeInsets.only(left: 15, right: 15),
padding: EdgeInsets.only(left: 20, right: 20),
child: ListView.separated( child: ListView.separated(
itemCount: 100, itemCount: 100,
itemBuilder: (BuildContext context, int index) { itemBuilder: (BuildContext context, int index) {
return ListTile(title: Text("$index")); return HospitalItem(context, index);
}, },
separatorBuilder: (BuildContext context, int index) { separatorBuilder: (BuildContext context, int index) {
return Divider(color: Color(0xffE5E5E5)); return Divider(color: Color(0xffE5E5E5));
}, },
)), ));
}
// 机构卡片
Widget HospitalItem(BuildContext context, int index) {
return GestureDetector(
onTap: () {},
child: Container(
height: 94.5,
child: Stack(
children: <Widget>[
Positioned( Positioned(
bottom: keyHeight == 0 ? 0 : keyHeight,
left: 0, left: 0,
width: double.maxFinite, top: 35,
height: 96,
child: Container( child: Container(
height: 17,
width: 17,
child: true
? Image.asset("assets/icon-checked.png")
: Image.asset("assets/icon-check.png"),
)),
Positioned(
left: 32,
top: 21,
child: Container(
width: 45,
height: 45,
child: ClipOval(
child: CachedNetworkImage(
// imageUrl: cards.hospital.portrait,
imageUrl:
'https://img1.gamersky.com/image2019/07/20190725_ll_red_136_2/gamersky_07small_14_201972510258D0.jpg',
),
),
),
),
Positioned(
left: 89,
top: 17.5,
// child: baseText(cards.hospital.name, 15, Color(0xff333333),
// bold: true),
child: baseText('22222', 15, Color(0xff333333), bold: true),
),
Positioned(
top: 42.5,
right: 0,
child: Row(
crossAxisAlignment: CrossAxisAlignment.end,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
baseText("¥", 12, Color(0xffFF5963)),
baseText("${1}-${2}", 15, Color(0xffFF5963)),
],
),
),
Positioned(
bottom: 21,
left: 89,
// child: baseText(cards.hospital.address, 12, Color(0xff666666)),
child: baseText('dsssssssss', 12, Color(0xff666666)),
),
Positioned(
left: 89,
top: 38.5,
child: FiveStarView(2, 5),
)
],
),
));
}
// 底部输入框部分
Widget bottomMessage() {
return Container(
height: 96, height: 96,
color: Color(0xffF9F8FB), color: Color(0xffF9F8FB),
child: Column( child: Column(
children: <Widget>[ children: <Widget>[
Container( Container(
height: 25, height: 25,
color: Colors.black,
width: double.maxFinite, width: double.maxFinite,
margin: EdgeInsets.only(top: 12), margin: EdgeInsets.only(top: 12),
child: ListView( child: Row(
scrollDirection: Axis.horizontal, //横向滚动
children: <Widget>[ children: <Widget>[
Container( Container(
margin: EdgeInsets.only(left: 15, right: 8), margin: EdgeInsets.only(left: 15, right: 8),
...@@ -99,60 +216,23 @@ class MechanismBox implements IBottomPicker { ...@@ -99,60 +216,23 @@ class MechanismBox implements IBottomPicker {
color: Color(0xff666666), color: Color(0xff666666),
fontSize: 12), fontSize: 12),
)), )),
Container( Expanded(
height: 25, child: StreamBuilder<List<String>>(
margin: EdgeInsets.only(right: 12), stream: _model.questionsLive.stream,
padding: EdgeInsets.only(left: 8, right: 8), initialData: _model.questionsLive.data ?? null,
decoration: BoxDecoration( builder: (c, e) {
border: Border.all( if (e.data == null) {
color: Color(0xffE5E5E5), width: 0.5), return Container();
color: Color(0xffffffff), }
borderRadius: BorderRadius.circular(20)), List<String> questions = e.data;
child: Text( return ListView.builder(
'有优惠活动吗?', scrollDirection: Axis.horizontal, //横向滚动
style: TextStyle( itemBuilder: (c, index) {
fontSize: 12, return GestureDetector(
color: Color(0xff666666), onTap: () {
height: 1.8), textController.text += questions[index];
), },
), child: Container(
Container(
height: 25,
margin: EdgeInsets.only(right: 12),
padding: EdgeInsets.only(left: 8, right: 8),
decoration: BoxDecoration(
border: Border.all(
color: Color(0xffE5E5E5),
width: 0.5),
color: Color(0xffffffff),
borderRadius:
BorderRadius.circular(20)),
child: Text(
'111有优惠活动吗?',
style: TextStyle(
fontSize: 12,
color: Color(0xff666666),
height: 1.8),
)),
Container(
height: 25,
margin: EdgeInsets.only(right: 12),
padding: EdgeInsets.only(left: 8, right: 8),
decoration: BoxDecoration(
border: Border.all(
color: Color(0xffE5E5E5),
width: 0.5),
color: Color(0xffffffff),
borderRadius:
BorderRadius.circular(20)),
child: Text(
'111有优惠活动吗?',
style: TextStyle(
fontSize: 12,
color: Color(0xff666666),
height: 1.8),
)),
Container(
height: 25, height: 25,
margin: EdgeInsets.only(right: 12), margin: EdgeInsets.only(right: 12),
padding: EdgeInsets.only(left: 8, right: 8), padding: EdgeInsets.only(left: 8, right: 8),
...@@ -164,43 +244,62 @@ class MechanismBox implements IBottomPicker { ...@@ -164,43 +244,62 @@ class MechanismBox implements IBottomPicker {
borderRadius: borderRadius:
BorderRadius.circular(20)), BorderRadius.circular(20)),
child: Text( child: Text(
'111有优惠活动吗?', questions[index],
style: TextStyle( style: TextStyle(
fontSize: 12, fontSize: 12,
color: Color(0xff666666), color: Color(0xff666666),
height: 1.8), height: 1.8),
))
],
), ),
), ),
);
},
itemCount: questions.length,
);
}),
)
],
)),
Container( Container(
height: 35, height: 35,
margin: width: double.maxFinite,
EdgeInsets.only(top: 12, left: 15, right: 15), margin: EdgeInsets.only(top: 12, left: 15, right: 15),
decoration: BoxDecoration( decoration: BoxDecoration(
border: Border.all( border: Border.all(color: Color(0xffE5E5E5), width: 0.5),
color: Color(0xffE5E5E5), width: 0.5),
color: Color(0xffffffff), color: Color(0xffffffff),
borderRadius: BorderRadius.circular(35)), borderRadius: BorderRadius.circular(35)),
child: TextField( child: StreamBuilder(
stream: _model.messageLive.stream,
initialData: _model.messageLive.data ?? null,
builder: (context, snapshot) {
return TextField(
controller: textController, controller: textController,
keyboardType: TextInputType.text, keyboardType: TextInputType.text,
textInputAction: TextInputAction.send, textInputAction: TextInputAction.send,
onSubmitted: (txt) {}, onSubmitted: (txt) {
if (!(doctor_ids.length > 3 ||
doctor_ids.length < 1)) {
NativeToast.showNativeToast('请选择1-3个机构咨询');
} else {
if (txt == '') {
NativeToast.showNativeToast('text');
} else {
_model.sendMessage(doctor_ids, txt, plan_id);
dismissCall();
textController.text = '';
NativeToast.showNativeToast('消息已发送成功');
}
}
},
style: TextStyle(fontSize: 12),
maxLines: 1,
decoration: InputDecoration( decoration: InputDecoration(
contentPadding: EdgeInsets.all(16.0), contentPadding: EdgeInsets.only(
labelText: '文案文案文案不知道文案是啥', left: 16, top: 0, bottom: 12, right: 16),
border: InputBorder.none)), hintText: '请输入您想了解的问题',
) border: InputBorder.none));
], },
))) ))
], ],
)), ));
);
}
@override
void dispose() {
textController.dispose();
} }
} }
/*
* @author lsy
* @date 2020/6/29
**/
import 'dart:math';
import 'package:flutter/material.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/server/api/ClueApi.serv.dart';
import 'package:gm_flutter/commonModel/net/DioUtil.dart';
import 'package:gm_flutter/commonModel/rx/RxDispose.dart';
import 'package:gm_flutter/commonModel/util/PrintUtil.dart';
import 'package:gm_flutter/commonModel/bean/Pair.dart';
class MechanismModel extends BaseModel {
LiveData<List<String>> questionsLive = LiveData();
LiveData<int> stateLive = LiveData();
LiveData messageLive = LiveData();
RxDispose rxDispose = RxDispose();
getQuestions(int plan_id) {
ClueApiImpl.getInstance()
.getConsultQuestions(DioUtil.getInstance().getDio(), plan_id)
.listen((event) {
if (event.error == 0) {
stateLive.notifyView(ENDLOADING);
questionsLive.notifyView(event.data.questions);
} else {
stateLive.notifyView(FAIL);
questionsLive.notifyView(null);
NativeToast.showNativeToast(event.message);
}
})
.addToDispose(rxDispose)
.onError((err) {
stateLive.notifyView(FAIL);
questionsLive.notifyView(null);
PrintUtil.printBug(err);
});
}
sendMessage(List<int> doctor_ids, String question, int plan_id) {
ClueApiImpl.getInstance()
.sendMessage(
DioUtil.getInstance().getDio(), doctor_ids, question, plan_id)
.listen((event) {
if (event.error == 0) {
messageLive.notifyView(event.data.success);
} else {
NativeToast.showNativeToast(event.message);
}
})
.addToDispose(rxDispose)
.onError((err) {
PrintUtil.printBug(err);
});
}
@override
void dispose() {
questionsLive.dispost();
stateLive.dispost();
rxDispose.dispose();
}
}
...@@ -10,7 +10,7 @@ import 'package:flutter/cupertino.dart'; ...@@ -10,7 +10,7 @@ import 'package:flutter/cupertino.dart';
import 'package:extended_nested_scroll_view/extended_nested_scroll_view.dart' import 'package:extended_nested_scroll_view/extended_nested_scroll_view.dart'
as extend; as extend;
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:gm_flutter/ClueModel/page/levelTwo/LevelTwoPage.dart'; import 'package:gm_flutter/ClueModel/page/common/StickyTabBarDelegate.dart';
import 'package:gm_flutter/ClueModel/page/top/TopModel.dart'; import 'package:gm_flutter/ClueModel/page/top/TopModel.dart';
import 'package:gm_flutter/ClueModel/util/PosUtil.dart'; import 'package:gm_flutter/ClueModel/util/PosUtil.dart';
import 'package:gm_flutter/commonModel/base/BaseComponent.dart'; import 'package:gm_flutter/commonModel/base/BaseComponent.dart';
......
...@@ -3,11 +3,14 @@ ...@@ -3,11 +3,14 @@
* @date 2020/6/28 * @date 2020/6/28
**/ **/
import 'package:flutter_common/Annotations/anno/Get.dart'; import 'package:flutter_common/Annotations/anno/Get.dart';
import 'package:flutter_common/Annotations/anno/Post.dart';
import 'package:flutter_common/Annotations/anno/Query.dart'; 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/ConsultQuestionsBean.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/PlanBarBean.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/PlanCompareDetail.dart';
import 'package:gm_flutter/ClueModel/server/entity/PlanConsultBean.dart';
import 'package:gm_flutter/ClueModel/server/entity/PlanOverViewBean.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/PlansCompareFeed.dart';
import 'package:gm_flutter/ClueModel/server/entity/ProjectDetailsItem.dart'; import 'package:gm_flutter/ClueModel/server/entity/ProjectDetailsItem.dart';
...@@ -46,6 +49,13 @@ abstract class ClueApi { ...@@ -46,6 +49,13 @@ abstract class ClueApi {
@Query("page") int page, @Query("page") int page,
); );
@Get("/api/janus/plans/consult_questions")
ConsultQuestionsBean getConsultQuestions(@Query("plan_id") int plan_id);
@Post("api/janus/plans/plan_consult")
PlanConsultBean sendMessage(@Query("doctor_ids") List<int> doctor_ids,
@Query("question") String question, @Query("plan_id") int plan_id);
@Get("api/janus/plans/rank") @Get("api/janus/plans/rank")
PlanBarBean getPlanBar(@Query("rank_type") String rank_type); PlanBarBean getPlanBar(@Query("rank_type") String rank_type);
......
...@@ -20,6 +20,8 @@ import 'package:gm_flutter/ClueModel/server/entity/LevelOneFeedList.dart'; ...@@ -20,6 +20,8 @@ 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/PlanBean.dart';
import 'package:gm_flutter/ClueModel/server/entity/PlanFeedBean.dart'; import 'package:gm_flutter/ClueModel/server/entity/PlanFeedBean.dart';
import 'package:gm_flutter/ClueModel/server/entity/ConsultQuestionsBean.dart';
import 'package:gm_flutter/ClueModel/server/entity/PlanConsultBean.dart';
import 'package:gm_flutter/ClueModel/server/entity/PlanBarBean.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/DiscussLowPriceModelBean.dart';
import 'package:gm_flutter/ClueModel/server/entity/DiscussLowPriceAuthBean.dart'; import 'package:gm_flutter/ClueModel/server/entity/DiscussLowPriceAuthBean.dart';
...@@ -143,6 +145,38 @@ class ClueApiImpl { ...@@ -143,6 +145,38 @@ class ClueApiImpl {
}); });
} }
Stream<ConsultQuestionsBean> getConsultQuestions(Dio _dio, int plan_id) {
return Stream.fromFuture(
get(_dio, '/api/janus/plans/consult_questions', data: {
'plan_id': plan_id,
})).flatMap((value) {
if (value != null &&
(value.statusCode >= 200 && value.statusCode < 300)) {
return Stream.fromFuture(
compute(parseConsultQuestionsBean, value.toString()));
} else {
throw Exception("--未知网络错误--");
}
});
}
Stream<PlanConsultBean> sendMessage(
Dio _dio, List<int> doctor_ids, String question, int plan_id) {
return Stream.fromFuture(post(_dio, 'api/janus/plans/plan_consult', data: {
'doctor_ids': doctor_ids,
'question': question,
'plan_id': plan_id,
})).flatMap((value) {
if (value != null &&
(value.statusCode >= 200 && value.statusCode < 300)) {
return Stream.fromFuture(
compute(parsePlanConsultBean, value.toString()));
} else {
throw Exception("--未知网络错误--");
}
});
}
Stream<PlanBarBean> getPlanBar(Dio _dio, String rank_type) { Stream<PlanBarBean> getPlanBar(Dio _dio, String rank_type) {
return Stream.fromFuture(get(_dio, 'api/janus/plans/rank', data: { return Stream.fromFuture(get(_dio, 'api/janus/plans/rank', data: {
'rank_type': rank_type, 'rank_type': rank_type,
...@@ -365,6 +399,14 @@ PlanFeedBean parsePlanFeedBean(String value) { ...@@ -365,6 +399,14 @@ PlanFeedBean parsePlanFeedBean(String value) {
return PlanFeedBean.fromJson(json.decode(value)); return PlanFeedBean.fromJson(json.decode(value));
} }
ConsultQuestionsBean parseConsultQuestionsBean(String value) {
return ConsultQuestionsBean.fromJson(json.decode(value));
}
PlanConsultBean parsePlanConsultBean(String value) {
return PlanConsultBean.fromJson(json.decode(value));
}
PlanBarBean parsePlanBarBean(String value) { PlanBarBean parsePlanBarBean(String value) {
return PlanBarBean.fromJson(json.decode(value)); return PlanBarBean.fromJson(json.decode(value));
} }
......
class ConsultQuestionsBean {
int error;
String message;
Null extra;
Null errorExtra;
UserType userType;
Data data;
ConsultQuestionsBean(
{this.error,
this.message,
this.extra,
this.errorExtra,
this.userType,
this.data});
ConsultQuestionsBean.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<String> questions;
Data({this.questions});
Data.fromJson(Map<String, dynamic> json) {
questions = json['questions'].cast<String>();
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['questions'] = this.questions;
return data;
}
}
class PlanConsultBean {
int error;
String message;
Null extra;
Null errorExtra;
UserType userType;
Data data;
PlanConsultBean(
{this.error,
this.message,
this.extra,
this.errorExtra,
this.userType,
this.data});
PlanConsultBean.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 lsy
* @date 2020/7/3
**/
class PlanOverViewBean {
int error;
String message;
Null extra;
Null errorExtra;
UserType userType;
PlanOverData 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 PlanOverData.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 PlanOverData {
Banner banner;
String name;
String positiveRate;
String salesCount;
String planDescription;
String guidePrice;
List<OverviewAttrs> overviewAttrs;
List<ExplanationAttrs> explanationAttrs;
List<Tabs> tabs;
PlanOverData(
{this.banner,
this.name,
this.positiveRate,
this.salesCount,
this.planDescription,
this.guidePrice,
this.overviewAttrs,
this.explanationAttrs,
this.tabs});
PlanOverData.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;
}
}
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