Commit 80cd9bc6a18cfa9b33ecf3253f2b636e5007423d

Authored by wdn127929
1 parent 662bac04

预订联系人部分

  1 +import 'package:flutter/material.dart';
  2 +import 'package:flutter_easyrefresh/easy_refresh.dart';
  3 +import 'package:flutter_screenutil/flutter_screenutil.dart';
  4 +import 'package:one_key/constant/state.dart';
  5 +import 'package:one_key/provider/contant_show_model.dart';
  6 +import 'package:one_key/provider/user_model.dart';
  7 +import 'package:one_key/res/colors.dart';
  8 +
  9 +import 'package:one_key/widgets/page_exception.dart';
  10 +import 'package:one_key/widgets/v_empty_view.dart';
  11 +import 'package:provider/provider.dart';
  12 +
  13 +class ContantLeftPage extends StatefulWidget {
  14 + ContantLeftPage({Key key}) : super(key: key);
  15 +
  16 + @override
  17 + _ContantLeftPageState createState() => _ContantLeftPageState();
  18 +}
  19 +
  20 +class _ContantLeftPageState extends State<ContantLeftPage> {
  21 + EasyRefreshController _controller;
  22 + ContantShowModel contantShowModel;
  23 +
  24 + @override
  25 + void initState() {
  26 + super.initState();
  27 + _controller = EasyRefreshController();
  28 +
  29 + WidgetsBinding.instance.addPostFrameCallback((_) {
  30 + _getContantData();
  31 + });
  32 + }
  33 +
  34 + _getContantData() async {
  35 + Map<String, String> params = {
  36 + "sid": Provider.of<UserModel>(context, listen: false).user.sellerid,
  37 + };
  38 + await contantShowModel.getUserHistorys(context, params);
  39 + }
  40 +
  41 + @override
  42 + Widget build(BuildContext context) {
  43 + contantShowModel = Provider.of<ContantShowModel>(context, listen: true);
  44 + return Expanded(
  45 + child: Consumer<ContantShowModel>(
  46 + builder: (context, model, _) {
  47 + if (model.pageStateLeft != PageState.Success) {
  48 + return ExceptionPage(
  49 + pageState: model.pageStateLeft,
  50 + callback: () {
  51 + // offset = 0;
  52 + // getMessages();
  53 + _getContantData();
  54 + },
  55 + emptyMsg: "暂时没有联系人哦",
  56 + emptyImg: "empty_search",
  57 + showMsg: "加载中,请稍后...",
  58 + );
  59 + } else {
  60 + return EasyRefresh.custom(
  61 + controller: _controller,
  62 + slivers: [
  63 + SliverList(delegate: SliverChildBuilderDelegate(
  64 + (BuildContext context, int index) {
  65 + return Container(
  66 + padding: EdgeInsets.symmetric(
  67 + horizontal: ScreenUtil().setWidth(40),
  68 + vertical: ScreenUtil().setWidth(30)),
  69 + height: ScreenUtil().setWidth(74 * 2),
  70 + decoration: BoxDecoration(
  71 + border: Border(
  72 + bottom: BorderSide(
  73 + width: ScreenUtil().setWidth(2),
  74 + color: MyColours.color_E0E0E0))),
  75 + child: Column(
  76 + crossAxisAlignment: CrossAxisAlignment.start,
  77 + children: [
  78 + Text(model.userHistorys[index].rname,
  79 + style: TextStyle(
  80 + color: MyColours.color_333333,
  81 + fontSize: ScreenUtil().setSp(32))),
  82 + VEmptyView(10),
  83 + Text(model.userHistorys[index].phone,
  84 + style: TextStyle(
  85 + color: MyColours.color_999999,
  86 + fontSize: ScreenUtil().setSp(30)))
  87 + ],
  88 + ),
  89 + );
  90 + }))
  91 + ],
  92 + // onRefresh: () async {
  93 + // // offset = 0;
  94 + // // getMessages(showLoading: false);
  95 + // },
  96 + // onLoad: () async {
  97 + // // offset++;
  98 + // // getMessages(showLoading: false);
  99 + // },
  100 + );
  101 + }
  102 + },
  103 + ),
  104 + );
  105 + }
  106 +}
  1 +import 'package:flutter/material.dart';
  2 +import 'package:flutter/services.dart';
  3 +
  4 +import 'package:contacts_service/contacts_service.dart';
  5 +import 'package:flutter_screenutil/screenutil.dart';
  6 +import 'package:intl/intl.dart';
  7 +import 'package:one_key/pages/my/contant_left_page.dart';
  8 +import 'package:one_key/provider/contant_show_model.dart';
  9 +import 'package:one_key/res/colors.dart';
  10 +import 'package:one_key/widgets/custom_tab_indicator.dart';
  11 +import 'package:one_key/widgets/system_app_bar.dart';
  12 +import 'package:provider/provider.dart';
  13 +
  14 +class ContactListPage extends StatefulWidget {
  15 + @override
  16 + _ContactListPageState createState() => _ContactListPageState();
  17 +}
  18 +
  19 +class _ContactListPageState extends State<ContactListPage> {
  20 + List<Contact> _contacts;
  21 + List _tabBarTitle;
  22 +
  23 + @override
  24 + void initState() {
  25 + _tabBarTitle = ['预订联系人', '手机联系人'];
  26 + super.initState();
  27 + refreshContacts();
  28 + }
  29 +
  30 + Future<void> refreshContacts() async {
  31 + // Load without thumbnails initially.
  32 + var contacts = (await ContactsService.getContacts(
  33 + withThumbnails: false, iOSLocalizedLabels: false))
  34 + .toList();
  35 +// var contacts = (await ContactsService.getContactsForPhone("8554964652"))
  36 +// .toList();
  37 + setState(() {
  38 + _contacts = contacts;
  39 + });
  40 +
  41 + // Lazy load thumbnails after rendering initial contacts.
  42 + for (final contact in contacts) {
  43 + ContactsService.getAvatar(contact).then((avatar) {
  44 + if (avatar == null) return; // Don't redraw if no change.
  45 + setState(() => contact.avatar = avatar);
  46 + });
  47 + }
  48 + }
  49 +
  50 + void updateContact() async {
  51 + Contact ninja = _contacts
  52 + .toList()
  53 + .firstWhere((contact) => contact.familyName.startsWith("Ninja"));
  54 + ninja.avatar = null;
  55 + await ContactsService.updateContact(ninja);
  56 +
  57 + refreshContacts();
  58 + }
  59 +
  60 + _openContactForm() async {
  61 + try {
  62 + var contact =
  63 + await ContactsService.openContactForm(iOSLocalizedLabels: false);
  64 + refreshContacts();
  65 + } on FormOperationException catch (e) {
  66 + switch (e.errorCode) {
  67 + case FormOperationErrorCode.FORM_OPERATION_CANCELED:
  68 + case FormOperationErrorCode.FORM_COULD_NOT_BE_OPEN:
  69 + case FormOperationErrorCode.FORM_OPERATION_UNKNOWN_ERROR:
  70 + default:
  71 + print(e.errorCode);
  72 + }
  73 + }
  74 + }
  75 +
  76 + @override
  77 + Widget build(BuildContext context) {
  78 + return Scaffold(
  79 + backgroundColor: MyColours.color_ffffff,
  80 + appBar: SystemAppBar('联系人'),
  81 + body: SafeArea(
  82 + child: DefaultTabController(
  83 + length: 2,
  84 + child: Stack(
  85 + children: <Widget>[
  86 + TabBarView(
  87 + physics: NeverScrollableScrollPhysics(),
  88 + children: <Widget>[
  89 + ChangeNotifierProvider<ContantShowModel>(
  90 + create: (_) => ContantShowModel(),
  91 + child: ContantLeftPage()),
  92 + Container()
  93 + ],
  94 + ),
  95 + Positioned(
  96 + child: Container(
  97 + padding:
  98 + EdgeInsets.only(bottom: ScreenUtil().setWidth(10)),
  99 + margin: EdgeInsets.symmetric(
  100 + horizontal: ScreenUtil().setWidth(30)),
  101 + child: TabBar(
  102 + indicator: CustomTabIndicator(
  103 + radius: 0,
  104 + ),
  105 + indicatorColor: MyColours.color_199095,
  106 + indicatorSize: TabBarIndicatorSize.tab,
  107 + // indicatorPadding: EdgeInsets.symmetric(
  108 + // horizontal: ScreenUtil().setWidth(12)),
  109 + labelColor: MyColours.color_199095,
  110 + labelStyle: TextStyle(
  111 + fontSize: ScreenUtil().setSp(32),
  112 + fontWeight: FontWeight.bold),
  113 + labelPadding: EdgeInsets.zero,
  114 + unselectedLabelStyle:
  115 + TextStyle(fontWeight: FontWeight.normal),
  116 + unselectedLabelColor: MyColours.color_999999,
  117 + tabs: _tabBarTitle.map((value) {
  118 + return Tab(
  119 + child: Text(value),
  120 + );
  121 + }).toList()),
  122 + ))
  123 + ],
  124 + ))));
  125 + }
  126 +}
@@ -268,20 +268,6 @@ class MyPageState extends State<MyPage> with WidgetsBindingObserver { @@ -268,20 +268,6 @@ class MyPageState extends State<MyPage> with WidgetsBindingObserver {
268 // ], 268 // ],
269 // ), 269 // ),
270 VEmptyView(40), 270 VEmptyView(40),
271 -  
272 - // MyItem(  
273 - // title: "我的员工",  
274 - // content: "",  
275 - // callback: () {  
276 - // Utils.goMiniProgramZm(context, "roomtype/roomtype");  
277 - // },  
278 - // ),  
279 - // MyDivider(  
280 - // double.infinity,  
281 - // ScreenUtil().setHeight(1),  
282 - // color: MyColours.color_f3f3f3,  
283 - // ),  
284 -  
285 MyItem( 271 MyItem(
286 title: "线上券创建", 272 title: "线上券创建",
287 content: '', 273 content: '',
@@ -289,11 +275,23 @@ class MyPageState extends State<MyPage> with WidgetsBindingObserver { @@ -289,11 +275,23 @@ class MyPageState extends State<MyPage> with WidgetsBindingObserver {
289 NavigatorUtil.goCouponPage(context); 275 NavigatorUtil.goCouponPage(context);
290 }, 276 },
291 ), 277 ),
  278 +
292 MyDivider( 279 MyDivider(
293 double.infinity, 280 double.infinity,
294 ScreenUtil().setHeight(1), 281 ScreenUtil().setHeight(1),
295 color: MyColours.color_f3f3f3, 282 color: MyColours.color_f3f3f3,
296 ), 283 ),
  284 +
  285 + MyItem(
  286 + title: "联系人",
  287 + content: "",
  288 + callback: () {
  289 + // Utils.goMiniProgramZm(context, "roomtype/roomtype");
  290 + NavigatorUtil.goMyContantPage(context);
  291 + },
  292 + ),
  293 +
  294 + VEmptyView(40),
297 MyItem( 295 MyItem(
298 title: "短信管理", 296 title: "短信管理",
299 content: 297 content:
  1 +import 'package:flutter/material.dart';
  2 +import 'package:one_key/constant/constant.dart';
  3 +import 'package:one_key/constant/error.dart';
  4 +import 'package:one_key/constant/state.dart';
  5 +import 'package:one_key/models/user_history_entity.dart';
  6 +import 'package:one_key/net/base_resp.dart';
  7 +import 'package:one_key/net/dio_util.dart';
  8 +import 'package:one_key/net/http_url.dart';
  9 +
  10 +class ContantShowModel extends ChangeNotifier {
  11 + PageState pageStateLeft = PageState.Loading;
  12 + List<UserHistoryEntity> userHistorys = []; //历史录入
  13 +
  14 +
  15 +
  16 + //获取历史录入
  17 + getUserHistorys(BuildContext context, Map<String, String> params) async {
  18 + BaseResp<List> baseResp = await DioUtil()
  19 + .request<List>(context, Method.get, HttpUrl.get_reserve_user,
  20 + data: params, showLoading: false)
  21 + .catchError((error) {
  22 + print(error.toString());
  23 + if (error is MyError) {
  24 + switch (error.type) {
  25 + case 1:
  26 + pageStateLeft = PageState.ConnectivityError;
  27 + break;
  28 + case 2:
  29 + pageStateLeft = PageState.ConnectivityTimeOut;
  30 + break;
  31 + default:
  32 + pageStateLeft = PageState.ConnectivityError;
  33 + break;
  34 + }
  35 + }
  36 + notifyListeners();
  37 + });
  38 + if (baseResp != null && baseResp.code == Constant.status_success) {
  39 + userHistorys = baseResp.data.map<UserHistoryEntity>((value) {
  40 + return UserHistoryEntity.fromJson(value);
  41 + }).toList();
  42 + if (userHistorys.length == 0) {
  43 + pageStateLeft = PageState.Empty;
  44 + } else {
  45 + pageStateLeft = PageState.Success;
  46 + }
  47 + notifyListeners();
  48 + }
  49 + }
  50 +}
@@ -301,4 +301,10 @@ class NavigatorUtil { @@ -301,4 +301,10 @@ class NavigatorUtil {
301 "${Routes.my_integral_page}?sunModel=${FluroConvertUtils.object2string(sunModel)}", 301 "${Routes.my_integral_page}?sunModel=${FluroConvertUtils.object2string(sunModel)}",
302 replace: replace); 302 replace: replace);
303 } 303 }
  304 +
  305 + /// 我的联系人页面
  306 + static Future<dynamic> goMyContantPage(BuildContext context,
  307 + {replace = false, IntegralSunModel sunModel}) {
  308 + return _navigateTo(context, "${Routes.my_contant_page}", replace: replace);
  309 + }
304 } 310 }
@@ -34,6 +34,7 @@ import 'package:one_key/pages/login/web_page.dart'; @@ -34,6 +34,7 @@ import 'package:one_key/pages/login/web_page.dart';
34 import 'package:one_key/pages/message/message_order_menu.dart'; 34 import 'package:one_key/pages/message/message_order_menu.dart';
35 import 'package:one_key/pages/my/base_info.dart'; 35 import 'package:one_key/pages/my/base_info.dart';
36 import 'package:one_key/pages/my/book_time_set.dart'; 36 import 'package:one_key/pages/my/book_time_set.dart';
  37 +import 'package:one_key/pages/my/contant_page.dart';
37 import 'package:one_key/pages/my/my_integral_page.dart'; 38 import 'package:one_key/pages/my/my_integral_page.dart';
38 import 'package:one_key/pages/my/receive_orders_time_set.dart'; 39 import 'package:one_key/pages/my/receive_orders_time_set.dart';
39 import 'package:one_key/pages/my/remark_manager_page.dart'; 40 import 'package:one_key/pages/my/remark_manager_page.dart';
@@ -436,3 +437,13 @@ var myIntegralPageHandler = new Handler( @@ -436,3 +437,13 @@ var myIntegralPageHandler = new Handler(
436 return ChangeNotifierProvider<MyModel>( 437 return ChangeNotifierProvider<MyModel>(
437 create: (_) => MyModel(), child: MyIntegralPage(sunModel: sunModel)); 438 create: (_) => MyModel(), child: MyIntegralPage(sunModel: sunModel));
438 }); 439 });
  440 +///我的联系人
  441 +var myContantPageHandler = new Handler(
  442 + handlerFunc: (BuildContext context, Map<String, List<Object>> params) {
  443 + // IntegralSunModel sunModel = IntegralSunModel.fromJson(json
  444 + // .decode(FluroConvertUtils.fluroCnParamsDecode(params["sunModel"].first)));
  445 + // String urlStr = FluroConvertUtils.fluroCnParamsDecode(params["urlStr"].first);
  446 +
  447 + return ContactListPage();
  448 +});
  449 +
@@ -42,6 +42,8 @@ class Routes { @@ -42,6 +42,8 @@ class Routes {
42 static String enter_store_environment = "/enter_store_environment"; //店铺环境 42 static String enter_store_environment = "/enter_store_environment"; //店铺环境
43 static String complete_create_store = "/complete_create_store"; //创建店铺完成 43 static String complete_create_store = "/complete_create_store"; //创建店铺完成
44 static String my_integral_page = "/my_integral_page"; //我的积分 44 static String my_integral_page = "/my_integral_page"; //我的积分
  45 + static String my_contant_page = "/my_contant_page"; //我的联系人
  46 +
45 47
46 static void configureRoutes(FluroRouter router) { 48 static void configureRoutes(FluroRouter router) {
47 router.notFoundHandler = new Handler( 49 router.notFoundHandler = new Handler(
@@ -92,6 +94,9 @@ class Routes { @@ -92,6 +94,9 @@ class Routes {
92 handler: completeCreateStorePageHandler); 94 handler: completeCreateStorePageHandler);
93 router.define(my_integral_page, 95 router.define(my_integral_page,
94 handler: myIntegralPageHandler); 96 handler: myIntegralPageHandler);
  97 + router.define(my_contant_page,
  98 + handler: myContantPageHandler);
  99 +
95 100
96 } 101 }
97 } 102 }
  1 +import 'package:flutter/material.dart';
  2 +
  3 +import 'package:flutter/cupertino.dart';
  4 +import 'package:flutter/material.dart';
  5 +import 'package:flutter_screenutil/screenutil.dart';
  6 +import 'package:one_key/res/colors.dart';
  7 +
  8 +
  9 +class CustomTabIndicator extends Decoration {
  10 + /// Create an underline style selected tab indicator.
  11 + ///
  12 + /// The [borderSide] and [insets] arguments must not be null.
  13 + const CustomTabIndicator(
  14 + {this.borderSide = const BorderSide(width: 2.0, color: Colors.white),
  15 + this.insets = EdgeInsets.zero,
  16 + this.width,
  17 + this.radius,
  18 + this.color})
  19 + : assert(borderSide != null),
  20 + assert(insets != null);
  21 +
  22 + /// The color and weight of the horizontal line drawn below the selected tab.
  23 + final BorderSide borderSide;
  24 +
  25 + final double radius;
  26 +
  27 + final double width;
  28 +
  29 + final Color color;
  30 +
  31 + /// Locates the selected tab's underline relative to the tab's boundary.
  32 + ///
  33 + /// The [TabBar.indicatorSize] property can be used to define the
  34 + /// tab indicator's bounds in terms of its (centered) tab widget with
  35 + /// [TabIndicatorSize.label], or the entire tab with [TabIndicatorSize.tab].
  36 + final EdgeInsetsGeometry insets;
  37 +
  38 + @override
  39 + Decoration lerpFrom(Decoration a, double t) {
  40 + if (a is CustomTabIndicator) {
  41 + return CustomTabIndicator(
  42 + borderSide: BorderSide.lerp(a.borderSide, borderSide, t),
  43 + insets: EdgeInsetsGeometry.lerp(a.insets, insets, t),
  44 + );
  45 + }
  46 + return super.lerpFrom(a, t);
  47 + }
  48 +
  49 + @override
  50 + Decoration lerpTo(Decoration b, double t) {
  51 + if (b is CustomTabIndicator) {
  52 + return CustomTabIndicator(
  53 + borderSide: BorderSide.lerp(borderSide, b.borderSide, t),
  54 + insets: EdgeInsetsGeometry.lerp(insets, b.insets, t),
  55 + );
  56 + }
  57 + return super.lerpTo(b, t);
  58 + }
  59 +
  60 + @override
  61 + _UnderlinePainter createBoxPainter([VoidCallback onChanged]) {
  62 + return _UnderlinePainter(this, onChanged);
  63 + }
  64 +}
  65 +
  66 +class _UnderlinePainter extends BoxPainter {
  67 + _UnderlinePainter(this.decoration, VoidCallback onChanged)
  68 + : assert(decoration != null),
  69 + super(onChanged);
  70 +
  71 + final CustomTabIndicator decoration;
  72 +
  73 + BorderSide get borderSide => decoration.borderSide;
  74 + EdgeInsetsGeometry get insets => decoration.insets;
  75 +
  76 + // Rect _indicatorRectFor(Rect rect, TextDirection textDirection) {
  77 + // assert(rect != null);
  78 + // assert(textDirection != null);
  79 + // final Rect indicator = insets.resolve(textDirection).deflateRect(rect);
  80 +
  81 + // //取中间坐标
  82 + // double cw = (indicator.left + indicator.right) / 2;
  83 + // return Rect.fromLTWH(
  84 + // cw - decoration.width / 2,
  85 + // indicator.bottom - borderSide.width,
  86 + // decoration.width,
  87 + // borderSide.width);
  88 + // }
  89 + Rect _indicatorRectFor(Rect rect, TextDirection textDirection) {
  90 + assert(rect != null);
  91 + assert(textDirection != null);
  92 + final Rect indicator = insets.resolve(textDirection).deflateRect(rect);
  93 + return Rect.fromLTWH(
  94 + indicator.left,
  95 + indicator.bottom - borderSide.width,
  96 + indicator.width,
  97 + borderSide.width,
  98 + );
  99 + }
  100 +
  101 + // @override
  102 + // void paint(Canvas canvas, Offset offset, ImageConfiguration configuration) {
  103 + // assert(configuration != null);
  104 + // assert(configuration.size != null);
  105 + // final Rect rect = offset & configuration.size;
  106 + // final TextDirection textDirection = configuration.textDirection;
  107 + // final Rect indicator =
  108 + // _indicatorRectFor(rect, textDirection).deflate(borderSide.width / 2.0);
  109 + // final RRect rrect =
  110 + // RRect.fromRectAndRadius(indicator, Radius.circular(40.0));
  111 + // Gradient gradient = LinearGradient(colors: [
  112 + // MyColours.color_3BBFF5,
  113 + // MyColours.color_57a0ff,
  114 + // ]);
  115 + // final Paint paint = borderSide.toPaint()..strokeCap = StrokeCap.square;
  116 + // canvas.drawLine(Offset(rrect.left, rrect.bottom),
  117 + // Offset(rrect.right, rrect.bottom), paint);
  118 + // canvas.drawRRect(
  119 + // rrect,
  120 + // Paint()
  121 + // ..style = PaintingStyle.fill
  122 + // ..shader = gradient.createShader(rect));
  123 +
  124 + // // Gradient gradient =
  125 + // // LinearGradient(colors: [Colors.red[200], Colors.red[800]]);
  126 + // Gradient gradient = LinearGradient(colors: [
  127 + // MyColours.color_3BBFF5,
  128 + // MyColours.color_57a0ff,
  129 + // ]);
  130 + // canvas.drawLine(rect.left, p2, paint)
  131 + // canvas.drawRRect(
  132 + // rrect,
  133 + // Paint()
  134 + // ..style = PaintingStyle.fill
  135 + // ..shader = gradient.createShader(rect));
  136 + // }
  137 + // void paint(Canvas canvas, Offset offset, ImageConfiguration configuration) {
  138 + // assert(configuration != null);
  139 + // assert(configuration.size != null);
  140 + // final Rect rect = offset & configuration.size;
  141 + // final TextDirection textDirection = configuration.textDirection;
  142 + // Gradient gradient = LinearGradient(colors: [
  143 + // MyColours.color_3BBFF5,
  144 + // MyColours.color_57a0ff,
  145 + // ]);
  146 + // final Rect indicator = _indicatorRectFor(rect, textDirection).deflate(borderSide.width / 2.0);
  147 + // final Paint paint = borderSide.toPaint()..strokeCap = StrokeCap.square ..shader = gradient.createShader(rect);
  148 + // canvas.drawLine(indicator.bottomLeft, indicator.bottomRight, paint);
  149 + // }
  150 +
  151 + @override
  152 + void paint(Canvas canvas, Offset offset, ImageConfiguration configuration) {
  153 + assert(configuration != null);
  154 + assert(configuration.size != null);
  155 + final Rect rect = offset & configuration.size;
  156 + final RRect rRect = RRect.fromRectAndRadius(
  157 + Rect.fromLTWH(rect.left + (rect.width - ScreenUtil().setWidth(48*2)) / 2,
  158 + rect.top + rect.height - ScreenUtil().setWidth(20), ScreenUtil().setWidth(48*2), ScreenUtil().setWidth(6)),
  159 + Radius.circular(decoration.radius));
  160 + Gradient gradient = LinearGradient(
  161 + begin: Alignment.topLeft,
  162 + end: Alignment.bottomRight,
  163 + colors: [
  164 + MyColours.color_199095,
  165 + MyColours.color_199095,
  166 + ],
  167 + );
  168 + canvas.drawRRect(
  169 + rRect,
  170 + Paint()
  171 + ..style = PaintingStyle.fill
  172 + ..shader = gradient.createShader(rect));
  173 + }
  174 +}
@@ -116,6 +116,8 @@ dependencies: @@ -116,6 +116,8 @@ dependencies:
116 dotted_border: ^1.0.7 116 dotted_border: ^1.0.7
117 scroll_to_index: ^2.0.0 117 scroll_to_index: ^2.0.0
118 118
  119 + #通讯录
  120 +
119 121
120 122
121 123