diff --git a/assets/static_fix/light1.png b/assets/static_fix/light1.png new file mode 100644 index 0000000..0865edc Binary files /dev/null and b/assets/static_fix/light1.png differ diff --git a/assets/static_fix/light2.png b/assets/static_fix/light2.png new file mode 100644 index 0000000..4445a36 Binary files /dev/null and b/assets/static_fix/light2.png differ diff --git a/assets/static_fix/light3.png b/assets/static_fix/light3.png new file mode 100644 index 0000000..64f9de7 Binary files /dev/null and b/assets/static_fix/light3.png differ diff --git a/lib/mock_models/fix/fix_model.dart b/lib/mock_models/fix/fix_model.dart index 3f1f6cd..44db53f 100644 --- a/lib/mock_models/fix/fix_model.dart +++ b/lib/mock_models/fix/fix_model.dart @@ -49,6 +49,24 @@ class FixModel { static List initList() { return [ + FixModel( + title: '小区大道路灯坏了。', + dateStart: DateTime(2020, 10, 25, 14, 28, 56), + type: FIX_ENUM.HAND_OUT, + imgs: [ + R.ASSETS_STATIC_FIX_LIGHT1_PNG, + R.ASSETS_STATIC_FIX_LIGHT2_PNG, + R.ASSETS_STATIC_FIX_LIGHT3_PNG, + ], + detail: FixDetailModel( + userName: '杨建', + userPhoneNumber: '18882928888', + fixArea: 'C区', + fixStatuses: [ + FixStatus(title: '申请保修', date: DateTime(2020, 10, 23, 10, 28, 56)), + ], + ), + ), FixModel( title: '小区西大门车栏坏了,请物业尽快修理更换。', dateStart: DateTime(2020, 10, 21, 7, 28, 56), @@ -147,6 +165,16 @@ enum FIX_PAYMENT_TYPE { PAY, } +Map fixPaymentMap = { + FIX_PAYMENT_TYPE.FREE: '无偿服务', + FIX_PAYMENT_TYPE.PAY: '有偿服务', +}; + +Map fixPaymentStringMap = { + '无偿服务': FIX_PAYMENT_TYPE.FREE, + '有偿服务': FIX_PAYMENT_TYPE.PAY, +}; + ///工单子类 enum FIX_SUB_TYPE { ///一般单 @@ -156,6 +184,16 @@ enum FIX_SUB_TYPE { HURRY, } +Map fixSubTypeMap = { + FIX_SUB_TYPE.NORMAL: '一般单', + FIX_SUB_TYPE.HURRY: '加急单', +}; + +Map fixSubTypeStringMap = { + '一般单': FIX_SUB_TYPE.NORMAL, + '加急单': FIX_SUB_TYPE.HURRY, +}; + ///工单时限 enum FIX_DATE_LIMIT { HOUR_24, @@ -163,6 +201,18 @@ enum FIX_DATE_LIMIT { HOUR_8, } +Map fixDateLimitMap = { + FIX_DATE_LIMIT.HOUR_24: '24小时内处理', + FIX_DATE_LIMIT.HOUR_12: '12小时内处理', + FIX_DATE_LIMIT.HOUR_8: '8小时内处理', +}; + +Map fixDateLimitStringMap = { + '24小时内处理': FIX_DATE_LIMIT.HOUR_24, + '12小时内处理': FIX_DATE_LIMIT.HOUR_12, + '8小时内处理': FIX_DATE_LIMIT.HOUR_8, +}; + class FixDetailModel { ///报修人 String userName; diff --git a/lib/provider/fix_provider.dart b/lib/provider/fix_provider.dart index 590ae5e..0f3b19c 100644 --- a/lib/provider/fix_provider.dart +++ b/lib/provider/fix_provider.dart @@ -30,6 +30,10 @@ class FixProvider extends ChangeNotifier { .where((element) => element.type == FIX_ENUM.WAIT_PICKUP) .toList(); + List _fixerModels = _fixModels + .where((element) => element.type != FIX_ENUM.HAND_OUT) + .toList(); + switch (role) { case USER_ROLE.MANAGER: return [ @@ -46,7 +50,7 @@ class FixProvider extends ChangeNotifier { _waitPickUpModels, _processingModels, _doneModels, - _fixModels, + _fixerModels, ][index]; break; } diff --git a/lib/ui/login/login_page.dart b/lib/ui/login/login_page.dart index 5782e43..4afa613 100644 --- a/lib/ui/login/login_page.dart +++ b/lib/ui/login/login_page.dart @@ -72,8 +72,10 @@ class _LoginPageState extends State { onChanged: (text) { setState(() {}); }, + maxLength: 11, keyboardType: TextInputType.phone, decoration: InputDecoration( + counterText: '', suffixIconConstraints: BoxConstraints( minHeight: 0, minWidth: 0, diff --git a/lib/ui/sub_pages/business_and_fix/business_and_fix_detail_page.dart b/lib/ui/sub_pages/business_and_fix/business_and_fix_detail_page.dart index a47b94c..5f8f4f8 100644 --- a/lib/ui/sub_pages/business_and_fix/business_and_fix_detail_page.dart +++ b/lib/ui/sub_pages/business_and_fix/business_and_fix_detail_page.dart @@ -5,6 +5,8 @@ import 'package:aku_community_manager/provider/user_provider.dart'; import 'package:aku_community_manager/style/app_style.dart'; import 'package:aku_community_manager/tools/widget_tool.dart'; import 'package:aku_community_manager/ui/widgets/common/aku_scaffold.dart'; +import 'package:aku_community_manager/ui/widgets/inner/show_bottom_sheet.dart'; +import 'package:aku_ui/common_widgets/aku_material_button.dart'; import 'package:common_utils/common_utils.dart'; import 'package:flutter/material.dart'; import 'package:aku_community_manager/tools/screen_tool.dart'; @@ -25,6 +27,7 @@ class _BusinessAndFixDetailPageState extends State { return userProvider.userInfoModel.role; } + bool get isHandOut => widget.model.type == FIX_ENUM.HAND_OUT; FixDetailModel get detailModel => widget.model.detail; String get fixType { @@ -102,11 +105,115 @@ class _BusinessAndFixDetailPageState extends State { padding: EdgeInsets.symmetric(vertical: 16.w), children: [ _buildInfo(), - _buildType(), + _buildType(widget.model.type == FIX_ENUM.HAND_OUT), _buildProcess(), - _buildResult(), + detailModel.result == null ? SizedBox() : _buildResult(), ], ), + bottom: Builder( + builder: (context) { + final userProvider = + Provider.of(context, listen: false); + if (widget.model.type == FIX_ENUM.HAND_OUT) { + return AkuMaterialButton( + color: AppStyle.primaryColor, + nullColor: AppStyle.minorColor, + onPressed: detailModel.type != null && + detailModel.subType != null && + detailModel.limit != null + ? () {} + : null, + child: Text( + '立即派单', + style: TextStyle( + fontWeight: FontWeight.bold, + ), + ), + ); + } else if (widget.model.type == FIX_ENUM.WAIT_PICKUP) { + if (userProvider.userInfoModel.role == USER_ROLE.MANAGER) { + return AkuMaterialButton( + color: AppStyle.primaryColor, + nullColor: AppStyle.minorColor, + onPressed: () {}, + child: Text( + '改派', + style: TextStyle( + fontWeight: FontWeight.bold, + ), + ), + ); + } else { + return AkuMaterialButton( + color: AppStyle.primaryColor, + nullColor: AppStyle.minorColor, + onPressed: () {}, + child: Text( + '立即接单', + style: TextStyle( + fontWeight: FontWeight.bold, + ), + ), + ); + } + } else if (widget.model.type == FIX_ENUM.PROCESSING && + userProvider.userInfoModel.role == USER_ROLE.FIXER) + return Container( + height: 96.w, + alignment: Alignment.center, + decoration: BoxDecoration( + color: Colors.white, + boxShadow: [ + BoxShadow( + offset: Offset(0, -10.w), + blurRadius: 10.w, + color: Color(0xFFF9F9F9), + ) + ], + ), + child: Row( + children: [ + AkuBox.w(32), + MaterialButton( + height: 72.w, + minWidth: 304.w, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(4.w), + side: BorderSide( + width: 2.w, + color: AppStyle.primaryColor, + ), + ), + onPressed: () {}, + child: Text( + '申请延时', + style: TextStyle( + fontWeight: FontWeight.bold, + ), + ), + ), + Spacer(), + AkuMaterialButton( + height: 72.w, + minWidth: 304.w, + radius: 4.w, + color: AppStyle.primaryColor, + onPressed: () {}, + child: Text( + '处理完成', + style: TextStyle( + fontWeight: FontWeight.bold, + ), + ), + ), + AkuBox.w(32), + ], + ), + ); + else + return SizedBox(); + }, + ), ); } @@ -160,13 +267,64 @@ class _BusinessAndFixDetailPageState extends State { ); } - _buildType() { + _buildType(bool canTap) { return _buildRawBox( title: '工单类型', children: [ - _buildTypeTile('派单类型', fixType, false), - _buildTypeTile('工单时限', dateLimit, false), - _buildTypeTile('工单子类', subType, false), + _buildTypeTile( + '派单类型', + fixType, + canTap, + helpContent: '请选择服务类型', + onTap: () { + showItemSheet( + title: '派单类型', + items: ['无偿服务', '有偿服务'], + selectItem: fixPaymentMap[detailModel.type], + onTap: (result) { + detailModel.type = fixPaymentStringMap[result]; + }, + ).then((_) { + setState(() {}); + }); + }, + ), + _buildTypeTile( + '工单时限', + dateLimit, + canTap, + helpContent: '请选择工单时限', + onTap: () { + showItemSheet( + title: '工单时限', + items: ['24小时内处理', '12小时内处理', '8小时内处理'], + selectItem: fixDateLimitMap[detailModel.limit], + onTap: (result) { + detailModel.limit = fixDateLimitStringMap[result]; + }, + ).then((_) { + setState(() {}); + }); + }, + ), + _buildTypeTile( + '工单子类', + subType, + canTap, + helpContent: '请选择工单子类', + onTap: () { + showItemSheet( + title: '工单子类', + items: ['一般单', '加急单'], + selectItem: fixSubTypeMap[detailModel.subType], + onTap: (result) { + detailModel.subType = fixSubTypeStringMap[result]; + }, + ).then((_) { + setState(() {}); + }); + }, + ), ], ); } @@ -276,11 +434,12 @@ class _BusinessAndFixDetailPageState extends State { ); } - Widget _buildTypeTile(String title, String content, bool canTap) { + Widget _buildTypeTile(String title, String content, bool canTap, + {VoidCallback onTap, String helpContent}) { return Material( color: Colors.transparent, child: InkWell( - onTap: canTap ? () {} : null, + onTap: canTap ? onTap : null, child: Row( children: [ AkuBox.h(96), @@ -293,13 +452,23 @@ class _BusinessAndFixDetailPageState extends State { ), Spacer(), Text( - content, + TextUtil.isEmpty(content) ? helpContent : content, style: TextStyle( fontSize: 28.sp, fontWeight: FontWeight.bold, - color: AppStyle.primaryTextColor, + color: TextUtil.isEmpty(content) + ? AppStyle.minorTextColor + : AppStyle.primaryTextColor, ), ), + isHandOut ? AkuBox.w(24) : SizedBox(), + isHandOut + ? Icon( + Icons.arrow_forward_ios, + size: 24.w, + color: AppStyle.minorTextColor, + ) + : SizedBox(), ], ), ), diff --git a/lib/ui/sub_pages/business_and_fix/business_and_fix_page.dart b/lib/ui/sub_pages/business_and_fix/business_and_fix_page.dart index 96fef6d..b6cb750 100644 --- a/lib/ui/sub_pages/business_and_fix/business_and_fix_page.dart +++ b/lib/ui/sub_pages/business_and_fix/business_and_fix_page.dart @@ -29,11 +29,8 @@ class _BusinessAndFixPageState extends State case USER_ROLE.FIXER: return ['待接单', '处理中', '已处理', '全部']; break; - case USER_ROLE.SECURITY: - return []; - break; default: - return []; + return ['待接单', '处理中', '已处理', '全部']; break; } } diff --git a/lib/ui/sub_pages/business_and_fix/business_fix_card.dart b/lib/ui/sub_pages/business_and_fix/business_fix_card.dart index 7b912ec..05ff7f9 100644 --- a/lib/ui/sub_pages/business_and_fix/business_fix_card.dart +++ b/lib/ui/sub_pages/business_and_fix/business_fix_card.dart @@ -52,64 +52,70 @@ class _BusinessFixCardState extends State { @override Widget build(BuildContext context) { - return Container( - padding: EdgeInsets.all(24), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisSize: MainAxisSize.min, - children: [ - Row( - children: [ - Container( - child: Text( - '报事报修', - style: TextStyle( - color: AppStyle.secondaryColor, - fontSize: 20.sp, - fontWeight: FontWeight.bold, + return GestureDetector( + onTap: () { + Get.to(BusinessAndFixDetailPage(model: widget.model)); + }, + child: Container( + padding: EdgeInsets.all(24.w), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + Row( + children: [ + Container( + child: Text( + '报事报修', + style: TextStyle( + color: AppStyle.secondaryColor, + fontSize: 20.sp, + fontWeight: FontWeight.bold, + ), + ), + padding: + EdgeInsets.symmetric(vertical: 6.w, horizontal: 16.w), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(2.w), + border: + Border.all(width: 2.w, color: AppStyle.secondaryColor), ), ), - padding: EdgeInsets.symmetric(vertical: 6.w, horizontal: 16.w), - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(2.w), - border: - Border.all(width: 2.w, color: AppStyle.secondaryColor), - ), - ), - AkuBox.w(16), - Expanded( - child: Text( - dateStart, - style: TextStyle( - color: AppStyle.minorTextColor, - fontSize: 22.sp, + AkuBox.w(16), + Expanded( + child: Text( + dateStart, + style: TextStyle( + color: AppStyle.minorTextColor, + fontSize: 22.sp, + ), ), ), + fixTypeWidget, + ], + ), + AkuBox.h(24), + Text( + widget.model.title, + style: TextStyle( + color: AppStyle.primaryTextColor, + fontSize: 28.sp, + fontWeight: FontWeight.bold, ), - fixTypeWidget, - ], - ), - AkuBox.h(24), - Text( - widget.model.title, - style: TextStyle( - color: AppStyle.primaryTextColor, - fontSize: 28.sp, - fontWeight: FontWeight.bold, ), - ), - AkuBox.h(16), - _buildImgs(), - _buildBottomCard(), - ], - ), - margin: EdgeInsets.symmetric( - horizontal: 32.w, - vertical: 8.w, - ), - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.circular(8.w), + AkuBox.h(16), + _buildImgs(), + _buildBottomCard(), + ], + ), + margin: EdgeInsets.symmetric( + horizontal: 32.w, + vertical: 8.w, + ), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8.w), + ), ), ); } diff --git a/lib/ui/widgets/common/aku_back_button.dart b/lib/ui/widgets/common/aku_back_button.dart index 71ddd6e..c4dead4 100644 --- a/lib/ui/widgets/common/aku_back_button.dart +++ b/lib/ui/widgets/common/aku_back_button.dart @@ -1,19 +1,32 @@ +import 'package:aku_community_manager/style/app_style.dart'; +import 'package:aku_ui/common_widgets/aku_material_button.dart'; import 'package:flutter/material.dart'; import 'package:aku_community_manager/tools/screen_tool.dart'; class AkuBackButton extends StatefulWidget { final Brightness brightness; final IconData icon; + final bool text; + AkuBackButton({ Key key, this.brightness = Brightness.light, this.icon = Icons.arrow_back_ios, + this.text = false, }) : super(key: key); AkuBackButton.close({ Key key, this.brightness = Brightness.light, this.icon = Icons.clear, + this.text = false, + }) : super(key: key); + + AkuBackButton.text({ + Key key, + this.brightness = Brightness.light, + this.icon, + this.text = true, }) : super(key: key); @override @@ -24,18 +37,32 @@ class _AkuBackButtonState extends State { @override Widget build(BuildContext context) { return Navigator.canPop(context) - ? IconButton( - icon: Icon( - widget.icon, - size: 32.w, - color: widget.brightness == Brightness.light - ? Color(0xFF333333) - : Color(0xFFEEEEEE), - ), - onPressed: () { - Navigator.pop(context); - }, - ) + ? widget.text + ? AkuMaterialButton( + padding: EdgeInsets.symmetric(horizontal: 32.w), + onPressed: () { + Navigator.pop(context); + }, + child: Text( + '取消', + style: TextStyle( + color: AppStyle.primaryTextColor, + fontSize: 28.w, + fontWeight: FontWeight.bold, + ), + )) + : IconButton( + icon: Icon( + widget.icon, + size: 32.w, + color: widget.brightness == Brightness.light + ? Color(0xFF333333) + : Color(0xFFEEEEEE), + ), + onPressed: () { + Navigator.pop(context); + }, + ) : SizedBox(); } } diff --git a/lib/ui/widgets/inner/show_bottom_sheet.dart b/lib/ui/widgets/inner/show_bottom_sheet.dart new file mode 100644 index 0000000..e1c3d6c --- /dev/null +++ b/lib/ui/widgets/inner/show_bottom_sheet.dart @@ -0,0 +1,75 @@ +import 'package:aku_community_manager/style/app_style.dart'; +import 'package:aku_community_manager/ui/widgets/common/aku_back_button.dart'; +import 'package:aku_ui/common_widgets/aku_material_button.dart'; +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:aku_community_manager/tools/screen_tool.dart'; + +///show bottom sheet +showAkuSheet({ + Widget child, +}) async { + await Get.bottomSheet( + Material( + color: Colors.white, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.vertical(top: Radius.circular(16.w)), + ), + child: child, + ), + ); +} + +Future showItemSheet({ + String title, + List items, + String selectItem, + Function(String result) onTap, +}) async { + await showAkuSheet( + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Row( + children: [ + Expanded( + child: Align( + alignment: Alignment.centerLeft, + child: AkuBackButton.text(), + ), + ), + Text( + title, + style: TextStyle( + color: AppStyle.primaryTextColor, + fontSize: 32.w, + fontWeight: FontWeight.bold, + ), + ), + Spacer(), + ], + ), + ...items.map((e) { + return AkuMaterialButton( + height: 96.w, + minWidth: double.infinity, + onPressed: () { + Get.back(); + onTap(e); + }, + child: Text( + e, + style: TextStyle( + fontWeight: FontWeight.bold, + fontSize: 32.sp, + color: e == selectItem + ? AppStyle.secondaryColor + : AppStyle.primaryTextColor, + ), + ), + ); + }).toList(), + ], + ), + ); +}