diff --git a/assets/manage/circuit.png b/assets/manage/circuit.png new file mode 100644 index 0000000..f488f4a Binary files /dev/null and b/assets/manage/circuit.png differ diff --git a/assets/manage/security.png b/assets/manage/security.png new file mode 100644 index 0000000..b4f4c6b Binary files /dev/null and b/assets/manage/security.png differ diff --git a/assets/manage/wall.png b/assets/manage/wall.png new file mode 100644 index 0000000..244eecf Binary files /dev/null and b/assets/manage/wall.png differ diff --git a/assets/manage/waterway.png b/assets/manage/waterway.png new file mode 100644 index 0000000..1906a07 Binary files /dev/null and b/assets/manage/waterway.png differ diff --git a/assets/manage/window.png b/assets/manage/window.png new file mode 100644 index 0000000..eaa7c05 Binary files /dev/null and b/assets/manage/window.png differ diff --git a/lib/main.dart b/lib/main.dart index 3bf5523..0ba12a3 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -5,7 +5,9 @@ import 'package:aku_community_manager/provider/outdoor_provider.dart'; import 'package:aku_community_manager/provider/user_provider.dart'; import 'package:aku_community_manager/ui/home/home_page.dart'; import 'package:bot_toast/bot_toast.dart'; +import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_localizations/flutter_localizations.dart'; import 'package:get/get.dart'; import 'package:provider/provider.dart'; @@ -22,9 +24,11 @@ class MyApp extends StatelessWidget { ChangeNotifierProvider(create: (context) => UserProvider()), ChangeNotifierProvider(create: (context) => AppProvider()), ChangeNotifierProvider(create: (context) => FixProvider()), - ChangeNotifierProvider(create: (context)=> GreenManageProvider()), - ChangeNotifierProvider(create: (context)=>InspectionManageProvider()), - ChangeNotifierProvider(create: (context)=>OutdoorProvider()), + ChangeNotifierProvider(create: (context) => GreenManageProvider()), + ChangeNotifierProvider(create: (context) => InspectionManageProvider()), + ChangeNotifierProvider(create: (context) => OutdoorProvider()), + ChangeNotifierProvider(create: (context) => GreenManageProvider()), + ChangeNotifierProvider(create: (context) => InspectionManageProvider()), ], child: GetMaterialApp( title: '小蜜蜂管家', @@ -33,6 +37,14 @@ class MyApp extends StatelessWidget { navigatorObservers: [ BotToastNavigatorObserver(), ], + localizationsDelegates: [ + GlobalCupertinoLocalizations.delegate, + GlobalMaterialLocalizations.delegate, + GlobalWidgetsLocalizations.delegate, + ], + supportedLocales: [ + const Locale('zh'), + ], ), ); } diff --git a/lib/mock_models/decoration/decoration_data.dart b/lib/mock_models/decoration/decoration_data.dart index 73344b0..e607017 100644 --- a/lib/mock_models/decoration/decoration_data.dart +++ b/lib/mock_models/decoration/decoration_data.dart @@ -4,6 +4,24 @@ import 'package:aku_community_manager/mock_models/fix/fixer_model.dart'; class DecorationData { static List allModels = [ DecorationModel( + type: DecorationType.WAIT_HAND_OUT, + statusType: DecorationStatusType.PROGRESS, + decorationDate: DateTime(2020, 1, 23, 12, 23, 0), + userHomeModel: UserHomeModel( + userName: '林居明', + plot: '深圳华茂悦峰', + detailAddr: '2幢-2单元-501室', + phone: '19995430126', + ), + decorationTeamModel: DecorationTeamModel( + name: '深圳莫川装修有限公司', + userName: '李惠政', + phone: '19298540192', + ), + cycleCheck: CycleCheck(), + ), + DecorationModel( + decorationDate: DateTime(2020, 1, 23, 12, 23, 0), type: DecorationType.DONE, statusType: DecorationStatusType.DONE, userHomeModel: UserHomeModel( @@ -11,7 +29,6 @@ class DecorationData { plot: '深圳华茂悦峰', detailAddr: '1幢-1单元-302室', phone: '18201939840', - decorationStatus: false, ), decorationTeamModel: DecorationTeamModel( name: '深圳莫川装修有限公司', @@ -19,7 +36,6 @@ class DecorationData { phone: '19298540192', ), cycleCheck: CycleCheck( - decorationDate: DateTime(2020, 1, 23, 12, 23, 0), authPerson: FixerModel(name: '林鸿章', phone: '18294859301'), startDate: DateTime(2020, 1, 23, 20, 23, 0), checkCycle: 7, @@ -31,7 +47,6 @@ class DecorationData { ], ), workFinishCheck: WorkFinishCheck( - decorationDate: DateTime(2020, 1, 23, 12, 23, 0), authPerson: FixerModel(name: '林鸿章', phone: '18294859301'), startDate: DateTime(2020, 1, 23, 20, 23, 0), checkDetails: [ diff --git a/lib/mock_models/decoration/decoration_model.dart b/lib/mock_models/decoration/decoration_model.dart index 091bcbc..5ebf0eb 100644 --- a/lib/mock_models/decoration/decoration_model.dart +++ b/lib/mock_models/decoration/decoration_model.dart @@ -1,5 +1,6 @@ import 'package:aku_community_manager/mock_models/fix/fixer_model.dart'; import 'package:flutter/material.dart'; +import 'package:aku_community_manager/const/resource.dart'; enum DecorationType { ///待指派 @@ -41,9 +42,18 @@ Map checkTypeStringMap = { '安防': CHECK_TYPE.SECURITY, }; +Map checkAssetMap = { + CHECK_TYPE.ELECTRIC: R.ASSETS_MANAGE_CIRCUIT_PNG, + CHECK_TYPE.WATER: R.ASSETS_MANAGE_WATERWAY_PNG, + CHECK_TYPE.WALL: R.ASSETS_MANAGE_WALL_PNG, + CHECK_TYPE.DOOR_AND_WINDOWS: R.ASSETS_MANAGE_WINDOW_PNG, + CHECK_TYPE.SECURITY: R.ASSETS_MANAGE_SECURITY_PNG, +}; + class DecorationModel { DecorationType type; DecorationStatusType statusType; + DateTime decorationDate; UserHomeModel userHomeModel; DecorationTeamModel decorationTeamModel; CycleCheck cycleCheck; @@ -62,6 +72,7 @@ class DecorationModel { @required this.statusType, @required this.userHomeModel, @required this.decorationTeamModel, + @required this.decorationDate, this.cycleCheck, this.workFinishCheck, this.checkInfomations, @@ -74,13 +85,11 @@ class UserHomeModel { String detailAddr; String userName; String phone; - bool decorationStatus; UserHomeModel({ this.plot, this.detailAddr, this.userName, this.phone, - this.decorationStatus, }); } @@ -98,7 +107,6 @@ class DecorationTeamModel { ///周期检查 class CycleCheck { - DateTime decorationDate; FixerModel authPerson; DateTime startDate; @@ -106,7 +114,6 @@ class CycleCheck { int checkCycle; List checkDetails; CycleCheck({ - this.decorationDate, this.authPerson, this.startDate, this.checkCycle, @@ -115,12 +122,10 @@ class CycleCheck { } class WorkFinishCheck { - DateTime decorationDate; FixerModel authPerson; DateTime startDate; List checkDetails; WorkFinishCheck({ - this.decorationDate, this.authPerson, this.startDate, this.checkDetails, @@ -152,6 +157,7 @@ class CheckInfomation { class CheckDetail { CHECK_TYPE type; bool status; + String get assetpath => checkAssetMap[type]; CheckDetail({ @required this.type, this.status = true, diff --git a/lib/mock_models/fix/fixer_model.dart b/lib/mock_models/fix/fixer_model.dart index dbf0528..1c8834b 100644 --- a/lib/mock_models/fix/fixer_model.dart +++ b/lib/mock_models/fix/fixer_model.dart @@ -7,6 +7,9 @@ enum FIXER_TYPE { ///水泥组 CEMENT, + + ///物业组 + PROPERTY, } class FixerModel { @@ -28,6 +31,8 @@ class FixerTypedModel { case FIXER_TYPE.CEMENT: return '水泥组'; break; + case FIXER_TYPE.PROPERTY: + return '物业组'; default: return ''; } @@ -66,4 +71,14 @@ class FixerTypedModel { ], ), ]; + + static List propertyModels = [ + FixerTypedModel( + type: FIXER_TYPE.PROPERTY, + fixers: [ + FixerModel(name: '李国师傅', phone: '18923747283'), + FixerModel(name: '章则林师傅', phone: '18910298345'), + ], + ), + ]; } diff --git a/lib/provider/fix_provider.dart b/lib/provider/fix_provider.dart index 7a91953..9633809 100644 --- a/lib/provider/fix_provider.dart +++ b/lib/provider/fix_provider.dart @@ -58,5 +58,7 @@ class FixProvider extends ChangeNotifier { } List _fixerModels = FixerTypedModel.models; + List _propertyModels = FixerTypedModel.propertyModels; List get fixerModels => _fixerModels; + List get propertyModels => _propertyModels; } diff --git a/lib/style/app_style.dart b/lib/style/app_style.dart index abf1225..05536e0 100644 --- a/lib/style/app_style.dart +++ b/lib/style/app_style.dart @@ -20,6 +20,16 @@ class AppStyle { ///背景色 static const backgroundColor = Color(0xFFF9F9F9); + ///成功色 + static const successColor = Color(0xFF32B814); + + static const subSuccessColor = Color(0xFFE5FFDF); + + ///失败色 + static const failColor = Color(0xFFFF4501); + + static const subFailColor = Color(0xFFFFE5DB); + ///字体格式 final barTitleStyle = TextStyle( color: primaryTextColor, diff --git a/lib/ui/settings/settings_page.dart b/lib/ui/settings/settings_page.dart index 543d634..e264d03 100644 --- a/lib/ui/settings/settings_page.dart +++ b/lib/ui/settings/settings_page.dart @@ -61,12 +61,20 @@ class _SettingsPageState extends State { ? Padding( padding: EdgeInsets.symmetric(horizontal: 64.w), child: AkuMaterialButton( + radius: 8.w, color: AppStyle.primaryColor, onPressed: () { userProvider.setisSigned(false); Get.offAll(HomePage()); }, - child: Text('退出登录'), + child: Text( + '退出登录', + style: TextStyle( + color: AppStyle.primaryTextColor, + fontWeight: FontWeight.bold, + fontSize: 32.w, + ), + ), ), ) : SizedBox(), diff --git a/lib/ui/sub_pages/decoration_manager/decoration_check_card_widget.dart b/lib/ui/sub_pages/decoration_manager/decoration_check_card_widget.dart new file mode 100644 index 0000000..a8aa760 --- /dev/null +++ b/lib/ui/sub_pages/decoration_manager/decoration_check_card_widget.dart @@ -0,0 +1,47 @@ +import 'package:aku_community_manager/mock_models/decoration/decoration_model.dart'; +import 'package:aku_community_manager/style/app_style.dart'; +import 'package:aku_community_manager/tools/widget_tool.dart'; +import 'package:flutter/material.dart'; +import 'package:aku_community_manager/tools/screen_tool.dart'; + +class DecorationCheckCardWidget extends StatelessWidget { + final CHECK_TYPE type; + final bool checked; + const DecorationCheckCardWidget( + {Key key, @required this.type, this.checked = false}) + : super(key: key); + + @override + Widget build(BuildContext context) { + return Container( + height: 160.w, + width: 124.w, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Image.asset( + checkAssetMap[type], + height: 56.w, + width: 56.w, + ), + AkuBox.h(4), + Text( + checkTypeMap[type], + style: TextStyle( + color: AppStyle.primaryTextColor, + fontSize: 24.sp, + ), + ), + ], + ), + decoration: BoxDecoration( + border: Border.all( + color: checked ? AppStyle.primaryTextColor : Color(0xFFE8E8E8), + width: 3.w, + ), + borderRadius: BorderRadius.circular(8.w), + color: checked ? Color(0xFFFFF3CC) : Colors.white, + ), + ); + } +} diff --git a/lib/ui/sub_pages/decoration_manager/decoration_check_row.dart b/lib/ui/sub_pages/decoration_manager/decoration_check_row.dart new file mode 100644 index 0000000..3fcaf9e --- /dev/null +++ b/lib/ui/sub_pages/decoration_manager/decoration_check_row.dart @@ -0,0 +1,68 @@ +import 'package:aku_community_manager/mock_models/decoration/decoration_model.dart'; +import 'package:aku_community_manager/tools/widget_tool.dart'; +import 'package:aku_community_manager/ui/sub_pages/decoration_manager/decoration_check_card_widget.dart'; +import 'package:flutter/material.dart'; + +import 'package:aku_community_manager/tools/screen_tool.dart'; + +class DecorationCheckRow extends StatefulWidget { + final List details; + final Function(List details) onChange; + final bool canTap; + DecorationCheckRow( + {Key key, @required this.details, this.onChange, this.canTap = false}) + : super(key: key); + + @override + _DecorationCheckRowState createState() => _DecorationCheckRowState(); +} + +class _DecorationCheckRowState extends State { + List _tempCheckDetails = []; + List _checkedDetails = []; + @override + void initState() { + super.initState(); + _tempCheckDetails = widget.details; + widget.details.forEach((element) { + _checkedDetails.add(element); + }); + } + + @override + Widget build(BuildContext context) { + return SizedBox( + height: 160.w, + child: ListView.separated( + scrollDirection: Axis.horizontal, + itemBuilder: (context, index) { + return GestureDetector( + onTap: !widget.canTap + ? null + : () { + widget.onChange(_checkedDetails); + setState(() { + _checkedDetails.indexOf(_tempCheckDetails[index]) != -1 + ? _checkedDetails.remove(_tempCheckDetails[index]) + : _checkedDetails.add(_tempCheckDetails[index]); + }); + }, + child: Material( + color: Colors.transparent, + child: DecorationCheckCardWidget( + type: _tempCheckDetails[index], + checked: !widget.canTap + ? false + : _checkedDetails.indexOf(_tempCheckDetails[index]) != -1, + ), + ), + ); + }, + itemCount: _tempCheckDetails.length, + separatorBuilder: (context, index) { + return AkuBox.w(16); + }, + ), + ); + } +} diff --git a/lib/ui/sub_pages/decoration_manager/decoration_checkbox.dart b/lib/ui/sub_pages/decoration_manager/decoration_checkbox.dart new file mode 100644 index 0000000..e5978b3 --- /dev/null +++ b/lib/ui/sub_pages/decoration_manager/decoration_checkbox.dart @@ -0,0 +1,109 @@ +import 'package:aku_community_manager/style/app_style.dart'; +import 'package:aku_community_manager/tools/widget_tool.dart'; +import 'package:flutter/material.dart'; + +class DecorationCheckBox extends StatefulWidget { + final bool initValue; + final Function(bool state) onChange; + DecorationCheckBox({Key key, this.initValue = true, this.onChange}) + : super(key: key); + + @override + _DecorationCheckBoxState createState() => _DecorationCheckBoxState(); +} + +class _DecorationCheckBoxState extends State { + bool _nowValue; + @override + void initState() { + super.initState(); + _nowValue = widget.initValue; + } + + @override + Widget build(BuildContext context) { + return Row( + mainAxisSize: MainAxisSize.min, + children: [ + _buildBox( + rawChecked: true, + color: AppStyle.successColor, + subColor: AppStyle.subSuccessColor, + title: '正常', + icon: Icons.check, + ), + AkuBox.w(56), + _buildBox( + rawChecked: false, + color: AppStyle.failColor, + subColor: AppStyle.subFailColor, + title: '异常', + icon: Icons.check, + ), + ], + ); + } + + _buildBox( + {bool rawChecked, + Color color, + Color subColor, + String title, + IconData icon}) { + final checked = _nowValue == rawChecked; + return GestureDetector( + onTap: widget.onChange == null + ? null + : () { + setState(() { + _nowValue = rawChecked; + }); + widget.onChange(_nowValue); + }, + child: Material( + color: Colors.transparent, + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + AnimatedContainer( + height: 40.w, + width: 40.w, + curve: Curves.easeInOutCubic, + child: _buildIcon(icon, color, checked), + duration: Duration(milliseconds: 300), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(20.w), + border: Border.all( + color: checked ? color : Color(0xFFE8E8E8), + ), + color: checked ? subColor : subColor.withOpacity(0), + ), + ), + AkuBox.w(16), + AkuBox.h(96), + _buildText(title, color, checked), + ], + ), + ), + ); + } + + _buildText(String title, Color color, bool checked) { + return Text( + title, + style: TextStyle( + color: checked ? color : AppStyle.minorTextColor, + fontSize: 24.sp, + fontWeight: FontWeight.bold, + ), + ); + } + + _buildIcon(IconData icon, Color color, bool checked) { + return Icon( + icon, + color: checked ? color : Color(0xFFE8E8E8), + size: 32.w, + ); + } +} diff --git a/lib/ui/sub_pages/decoration_manager/decoration_department_page.dart b/lib/ui/sub_pages/decoration_manager/decoration_department_page.dart new file mode 100644 index 0000000..c981799 --- /dev/null +++ b/lib/ui/sub_pages/decoration_manager/decoration_department_page.dart @@ -0,0 +1,188 @@ +import 'package:aku_community_manager/const/resource.dart'; +import 'package:aku_community_manager/mock_models/decoration/decoration_model.dart'; +import 'package:aku_community_manager/mock_models/fix/fix_model.dart'; +import 'package:aku_community_manager/mock_models/fix/fixer_model.dart'; +import 'package:aku_community_manager/provider/fix_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/tools/screen_tool.dart'; +import 'package:aku_ui/common_widgets/aku_material_button.dart'; +import 'package:expandable/expandable.dart'; +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:provider/provider.dart'; + +class DecorationDepartmentPage extends StatefulWidget { + final DecorationModel model; + DecorationDepartmentPage({Key key, @required this.model}) : super(key: key); + + @override + _DecorationDepartmentPageState createState() => + _DecorationDepartmentPageState(); +} + +class _DecorationDepartmentPageState extends State { + FixerModel _pickedFixer; + @override + Widget build(BuildContext context) { + final fixProvider = Provider.of(context); + + return AkuScaffold( + title: '装修指派', + body: ListView.builder( + padding: EdgeInsets.symmetric(vertical: 16.w), + itemBuilder: (context, index) { + return _buildItem(fixProvider.propertyModels[index], index); + }, + itemCount: fixProvider.propertyModels.length, + ), + bottom: AkuMaterialButton( + height: 96.w, + onPressed: _pickedFixer == null + ? null + : () { + widget.model.cycleCheck.authPerson = _pickedFixer; + Get.back(); + }, + color: AppStyle.primaryColor, + nullColor: AppStyle.primaryColor.withOpacity(0.5), + child: Text( + '选择完成', + style: TextStyle( + color: _pickedFixer == null + ? AppStyle.minorTextColor + : AppStyle.primaryTextColor, + fontSize: 32.w, + fontWeight: FontWeight.bold, + ), + ), + ), + ); + } + + _buildItem(FixerTypedModel model, int index) { + return Container( + decoration: BoxDecoration( + border: Border( + top: index == 0 + ? BorderSide.none + : BorderSide(color: Color(0xFFE8E8E8), width: 1.w), + bottom: BorderSide(color: Color(0xFFE8E8E8), width: 1.w), + ), + ), + child: Material( + color: Colors.white, + child: ExpandablePanel( + controller: ExpandableController(initialExpanded: true), + header: Container( + height: 96.w, + alignment: Alignment.centerLeft, + padding: EdgeInsets.symmetric(horizontal: 32.w), + child: Text( + model.typeName, + style: TextStyle( + color: AppStyle.primaryTextColor, + fontSize: 32.sp, + fontWeight: FontWeight.bold, + ), + ), + ), + collapsed: SizedBox(), + expanded: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Divider( + color: Color(0xFFE8E8E8), + height: 1.w, + thickness: 1.w, + ), + ...model.fixers.map((e) { + return Column( + mainAxisSize: MainAxisSize.min, + children: [ + AkuMaterialButton( + height: 96.w, + onPressed: () { + if (_pickedFixer?.name != e.name) { + _pickedFixer = e; + } else { + _pickedFixer = null; + } + setState(() {}); + }, + child: Row( + children: [ + AkuBox.w(72), + Checkbox( + checkColor: AppStyle.primaryTextColor, + activeColor: AppStyle.primaryColor, + value: _pickedFixer?.name == e.name, + onChanged: (state) { + if (_pickedFixer == null) { + _pickedFixer = e; + } else { + _pickedFixer = null; + } + setState(() {}); + }, + materialTapTargetSize: + MaterialTapTargetSize.shrinkWrap, + ), + Image.asset( + R.ASSETS_MESSAGE_IC_PEOPLE_PNG, + height: 40.w, + width: 40.w, + ), + Text( + e.name, + style: TextStyle( + color: AppStyle.primaryTextColor, + fontSize: 28.w, + fontWeight: FontWeight.bold, + ), + ), + Spacer(), + Image.asset( + R.ASSETS_MESSAGE_IC_PHONE_PNG, + height: 40.w, + width: 40.w, + ), + Text( + e.phone, + style: TextStyle( + color: AppStyle.primaryTextColor, + fontSize: 28.w, + fontWeight: FontWeight.bold, + ), + ), + AkuBox.w(101), + ], + ), + ), + model.fixers.last == e + ? SizedBox() + : Divider( + indent: 32.w, + endIndent: 32.w, + height: 1.w, + thickness: 1.w, + color: Color(0xFFE8E8E8), + ), + ], + ); + }).toList() + ], + ), + theme: ExpandableThemeData( + tapHeaderToExpand: true, + iconPlacement: ExpandablePanelIconPlacement.right, + iconPadding: EdgeInsets.only(top: 32.w, right: 32.w), + iconSize: 32.w, + iconColor: AppStyle.minorTextColor, + ), + ), + ), + ); + } +} diff --git a/lib/ui/sub_pages/decoration_manager/decoration_manager_card.dart b/lib/ui/sub_pages/decoration_manager/decoration_manager_card.dart index 08b36db..1072249 100644 --- a/lib/ui/sub_pages/decoration_manager/decoration_manager_card.dart +++ b/lib/ui/sub_pages/decoration_manager/decoration_manager_card.dart @@ -3,12 +3,15 @@ import 'package:aku_community_manager/mock_models/users/user_info_model.dart'; 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/sub_pages/decoration_manager/decoration_manager_detail_page.dart'; +import 'package:aku_community_manager/ui/sub_pages/decoration_manager/decoration_util.dart'; import 'package:aku_community_manager/ui/widgets/inner/aku_chip_box.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'; import 'package:aku_community_manager/const/resource.dart'; +import 'package:get/get.dart'; import 'package:provider/provider.dart'; class DecorationManagerCard extends StatefulWidget { @@ -35,7 +38,7 @@ class _DecorationManagerCardState extends State { AkuBox.w(16), Text( DateUtil.formatDate( - widget.model.cycleCheck.decorationDate, + widget.model.decorationDate, format: 'yyyy-MM-dd HH:mm:ss', ), style: TextStyle( @@ -45,9 +48,15 @@ class _DecorationManagerCardState extends State { ), Spacer(), Text( - _getTagName(), + DecorationUIUtil(context).getTagName( + widget.model.type, + widget.model.statusType, + ), style: TextStyle( - color: _getTagColor(), + color: DecorationUIUtil(context).getTagColor( + widget.model.type, + widget.model.statusType, + ), fontSize: 24.w, ), ), @@ -83,7 +92,9 @@ class _DecorationManagerCardState extends State { Align( alignment: Alignment.centerRight, child: AkuMaterialButton( - onPressed: () {}, + onPressed: () { + Get.to(DecorationManagerDetailPage(model: widget.model)); + }, height: 64.w, minWidth: 160.w, color: AppStyle.primaryColor, @@ -134,49 +145,4 @@ class _DecorationManagerCardState extends State { ], ); } - - _getTagName() { - Map managerMap = { - DecorationType.WAIT_HAND_OUT: '待指派', - DecorationType.HAND_OUT: '已指派', - DecorationType.DONE: '已执行', - }; - - Map fixerMap = { - DecorationType.HAND_OUT: '待执行', - DecorationType.DONE: '已执行', - }; - - Map defaultMap = { - DecorationStatusType.DONE: '装修完成', - DecorationStatusType.PROGRESS: '装修中', - }; - - switch (role) { - case USER_ROLE.MANAGER: - return managerMap[widget.model.type]; - break; - case USER_ROLE.PROPERTY: - return fixerMap[widget.model.type]; - break; - default: - return defaultMap[widget.model.statusType]; - break; - } - } - - Color _getTagColor() { - if (role == USER_ROLE.MANAGER || role == USER_ROLE.PROPERTY) { - if (widget.model.type == DecorationType.WAIT_HAND_OUT || - widget.model.type == DecorationType.HAND_OUT) { - return Color(0xFFFF4501); - } else - return AppStyle.minorTextColor; - } else { - if (widget.model.statusType == DecorationStatusType.PROGRESS) { - return Color(0xFFFF4501); - } else - return Color(0xFF32B814); - } - } } diff --git a/lib/ui/sub_pages/decoration_manager/decoration_manager_detail_page.dart b/lib/ui/sub_pages/decoration_manager/decoration_manager_detail_page.dart new file mode 100644 index 0000000..e44f94b --- /dev/null +++ b/lib/ui/sub_pages/decoration_manager/decoration_manager_detail_page.dart @@ -0,0 +1,630 @@ +import 'package:aku_community_manager/mock_models/decoration/decoration_model.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/sub_pages/decoration_manager/decoration_check_row.dart'; +import 'package:aku_community_manager/ui/sub_pages/decoration_manager/decoration_checkbox.dart'; +import 'package:aku_community_manager/ui/sub_pages/decoration_manager/decoration_department_page.dart'; +import 'package:aku_community_manager/ui/sub_pages/decoration_manager/decoration_util.dart'; +import 'package:aku_community_manager/ui/widgets/common/aku_back_button.dart'; +import 'package:aku_community_manager/ui/widgets/common/aku_scaffold.dart'; +import 'package:aku_community_manager/ui/widgets/inner/aku_title_box.dart'; +import 'package:aku_community_manager/tools/screen_tool.dart'; +import 'package:aku_community_manager/const/resource.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:expandable/expandable.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; + +class DecorationManagerDetailPage extends StatefulWidget { + final DecorationModel model; + DecorationManagerDetailPage({Key key, @required this.model}) + : super(key: key); + + @override + _DecorationManagerDetailStatePage createState() => + _DecorationManagerDetailStatePage(); +} + +class _DecorationManagerDetailStatePage + extends State { + bool get isWaitHandOut => widget.model.type == DecorationType.WAIT_HAND_OUT; + @override + Widget build(BuildContext context) { + return AkuScaffold( + title: '装修详情', + body: ListView( + padding: EdgeInsets.symmetric(vertical: 16.w), + children: [ + _buildInfo(), + widget.model.workFinishCheck == null + ? SizedBox() + : _buildFinishWorkCheck(), + _buildCycleCheck(), + widget.model.type == DecorationType.WAIT_HAND_OUT + ? SizedBox() + : _buildCheckDetail(), + ], + ), + ); + } + + _buildInfo() { + return AkuTitleBox( + title: '装修信息', + spacing: 24, + suffix: Text( + DecorationUIUtil(context).getTagName( + widget.model.type, + widget.model.statusType, + ), + style: TextStyle( + color: DecorationUIUtil(context).getTagColor( + widget.model.type, + widget.model.statusType, + ), + fontSize: 24.w, + ), + ), + children: [ + _buildInfoCard( + tag: '家', + midTop: widget.model.userHomeModel.plot, + midBottom: widget.model.userHomeModel.detailAddr, + name: '业主:' + widget.model.userHomeModel.userName, + phone: widget.model.userHomeModel.phone, + rightTopWidget: Placeholder(), + ), + AkuBox.h(16), + _buildInfoCard( + tag: '装', + midTop: widget.model.decorationTeamModel.name, + name: '负责人:' + widget.model.decorationTeamModel.userName, + phone: widget.model.decorationTeamModel.phone, + ), + ], + ); + } + + _buildInfoCard({ + String tag, + String midTop, + String midBottom, + String name, + String phone, + Widget rightTopWidget = const SizedBox(), + }) { + return Stack( + children: [ + Container( + child: Column( + children: [ + Expanded( + child: Row( + children: [ + AkuBox.w(32), + Container( + height: 96.w, + width: 96.w, + alignment: Alignment.center, + child: Text( + tag, + style: TextStyle( + color: AppStyle.secondaryColor, + fontWeight: FontWeight.bold, + fontSize: 32.sp, + ), + ), + decoration: BoxDecoration( + color: Color(0xFFE9F2FF), + borderRadius: BorderRadius.circular(48.w), + ), + ), + AkuBox.w(24), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + Text( + midTop, + style: TextStyle( + color: AppStyle.primaryTextColor, + fontSize: 32.sp, + fontWeight: FontWeight.bold, + ), + ), + midBottom == null + ? SizedBox() + : Text( + midBottom, + style: TextStyle( + color: AppStyle.primaryTextColor, + fontSize: 32.sp, + fontWeight: FontWeight.bold, + ), + ), + ], + ), + ), + ], + )), + Divider( + height: 1.w, + thickness: 1.w, + ), + Row( + children: [ + AkuBox.h(88), + AkuBox.w(32), + Image.asset( + R.ASSETS_MESSAGE_IC_PEOPLE_PNG, + height: 40.w, + width: 40.w, + ), + Text( + name, + style: TextStyle( + color: AppStyle.minorTextColor, + fontSize: 24.sp, + ), + ), + Spacer(), + Image.asset( + R.ASSETS_MESSAGE_IC_PHONE_PNG, + height: 40.w, + width: 40.w, + ), + Text( + '电话:$phone', + style: TextStyle( + color: AppStyle.minorTextColor, + fontSize: 24.sp, + ), + ), + AkuBox.w(42), + ], + ), + ], + ), + height: 248.w, + decoration: BoxDecoration( + color: Color(0xFFF9F9F9), + borderRadius: BorderRadius.circular(8.w), + ), + ), + Positioned( + top: -30.w, + right: -30.w, + width: 140.w, + height: 140.w, + child: rightTopWidget, + ), + ], + ); + } + + _buildFinishWorkCheck() { + return AkuTitleBox( + title: '完工检查', + spacing: 24, + children: [ + _buildRow( + title: '开始装修时间', + subTitle: DateUtil.formatDate( + widget.model.decorationDate, + format: 'yyyy-MM-dd', + ), + ), + _buildRow( + title: '接受人', + subTitle: widget.model.workFinishCheck?.authPerson?.name, + ), + _buildRow(title: '所属项目', subTitle: '装修管理'), + _buildRow( + title: '开始日期', + subTitle: DateUtil.formatDate( + widget.model.workFinishCheck?.startDate, + format: 'yyyy-MM-dd', + ), + ), + Padding( + padding: EdgeInsets.symmetric( + vertical: 28.w, + ), + child: Text( + '检查内容', + style: TextStyle( + color: AppStyle.primaryTextColor, + fontSize: 28.w, + ), + ), + ), + DecorationCheckRow( + details: widget.model.workFinishCheck?.checkDetails, + onChange: (details) {}, + ), + ], + ); + } + + _buildCycleCheck() { + return AkuTitleBox( + title: '周期检查', + spacing: 24, + children: [ + _buildRow( + title: '开始装修时间', + subTitle: DateUtil.formatDate( + widget.model.decorationDate, + format: 'yyyy-MM-dd', + ), + ), + _buildRow( + title: '接受人', + subTitle: widget.model.cycleCheck?.authPerson?.name, + onTap: isWaitHandOut + ? () { + Get.to(DecorationDepartmentPage( + model: widget.model, + )).then((value) => setState(() {})); + } + : null, + ), + _buildRow(title: '所属项目', subTitle: '装修管理'), + _buildRow( + title: '开始日期', + subTitle: DateUtil.formatDate( + widget.model.cycleCheck?.startDate, + format: 'yyyy-MM-dd', + ), + onTap: isWaitHandOut + ? () { + showAkuSheet( + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Row( + children: [ + AkuBox.h(96), + AkuBackButton.text(), + Spacer(), + Text( + '开始日期', + style: TextStyle( + color: AppStyle.primaryTextColor, + fontSize: 32.sp, + fontWeight: FontWeight.bold, + ), + ), + Spacer(), + AkuMaterialButton( + minWidth: (64 + 56).w, + onPressed: () { + Get.back(); + }, + child: Text( + '确定', + style: TextStyle( + color: AppStyle.secondaryColor, + fontSize: 28.sp, + ), + ), + ), + ], + ), + Container( + height: 500.w, + child: CupertinoDatePicker( + onDateTimeChanged: (dateTime) { + widget.model.cycleCheck.startDate = dateTime; + }, + ), + ), + ], + ), + ).then((value) { + setState(() {}); + }); + } + : null, + ), + _buildRow( + title: '检查周期', + subTitle: widget.model.cycleCheck.checkCycle == null + ? null + : '${widget.model.cycleCheck.checkCycle}天', + onTap: isWaitHandOut + ? () { + showAkuSheet( + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Row( + children: [ + AkuBox.h(96), + AkuBackButton.text(), + Spacer(), + Text( + '检查周期', + style: TextStyle( + color: AppStyle.primaryTextColor, + fontSize: 32.sp, + fontWeight: FontWeight.bold, + ), + ), + Spacer(), + AkuMaterialButton( + minWidth: (64 + 56).w, + onPressed: () { + Get.back(); + }, + child: Text( + '确定', + style: TextStyle( + color: AppStyle.secondaryColor, + fontSize: 28.sp, + ), + ), + ), + ], + ), + Container( + height: 500.w, + child: CupertinoPicker( + children: [ + Center( + child: Text('1天'), + ), + Center( + child: Text('3天'), + ), + Center( + child: Text('7天'), + ), + Center( + child: Text('14天'), + ), + Center( + child: Text('30天'), + ), + ], + itemExtent: 88.w, + onSelectedItemChanged: (int value) { + int realValue = 0; + switch (value) { + case 0: + realValue = 1; + break; + case 1: + realValue = 3; + break; + case 2: + realValue = 7; + break; + case 3: + realValue = 14; + break; + case 4: + realValue = 30; + break; + } + widget.model.cycleCheck.checkCycle = realValue; + }, + ), + ), + ], + ), + ).then((value) { + setState(() {}); + }); + } + : null, + ), + Padding( + padding: EdgeInsets.symmetric( + vertical: 28.w, + ), + child: Text( + '检查内容', + style: TextStyle( + color: AppStyle.primaryTextColor, + fontSize: 28.w, + ), + ), + ), + DecorationCheckRow( + details: [ + CHECK_TYPE.ELECTRIC, + CHECK_TYPE.WATER, + CHECK_TYPE.WALL, + CHECK_TYPE.DOOR_AND_WINDOWS, + CHECK_TYPE.SECURITY, + ], + onChange: (details) { + widget.model.cycleCheck.checkDetails = details; + }, + canTap: isWaitHandOut, + ) + ], + ); + } + + _buildCheckDetail() { + return AkuTitleBox( + title: '执行信息', + spacing: 24, + children: widget.model.checkInfomations.map((e) { + return Container( + decoration: BoxDecoration( + border: Border( + bottom: BorderSide( + color: Color(0xFFE8E8E8), + width: 1.w, + ), + ), + ), + child: ExpandablePanel( + theme: ExpandableThemeData( + tapHeaderToExpand: true, + iconPlacement: ExpandablePanelIconPlacement.right, + iconPadding: EdgeInsets.only(top: 32.w), + iconSize: 32.w, + iconColor: AppStyle.minorTextColor, + ), + header: Row( + children: [ + AkuBox.h(96), + Text( + '${DateUtil.formatDate(e.checkDate, format: 'yyyy-MM-dd')} ' + + e.checkType, + style: TextStyle( + color: AppStyle.primaryTextColor, + fontWeight: FontWeight.bold, + fontSize: 28.sp, + ), + ), + Spacer(), + Text( + e.checkAllResult ? '正常' : '异常', + style: TextStyle( + color: e.checkAllResult + ? Color(0xFF32B814) + : Color(0xFFFF4501), + fontSize: 28.sp, + ), + ), + ], + ), + expanded: Column( + mainAxisSize: MainAxisSize.min, + children: [ + ...e.details.map((e) { + return Container( + height: 96.w, + decoration: BoxDecoration( + border: Border( + top: BorderSide( + color: Color(0xFFE8E8E8), + width: 1.w, + ), + ), + ), + child: Row( + children: [ + AkuBox.w(48), + Image.asset( + e.assetpath, + height: 40.w, + ), + Text( + e.typeValue, + style: TextStyle( + fontSize: 28.sp, + color: AppStyle.primaryTextColor, + fontWeight: FontWeight.bold, + ), + ), + Spacer(), + DecorationCheckBox( + initValue: e.status, + ), + Spacer(), + ], + ), + ); + }).toList(), + Container( + decoration: BoxDecoration( + border: Border( + top: BorderSide( + width: 1.w, + color: Color(0xFFE8E8E8), + ), + ), + ), + height: 96.w, + padding: EdgeInsets.symmetric(horizontal: 32.w), + alignment: Alignment.centerLeft, + child: Text.rich( + TextSpan( + children: [ + TextSpan( + text: '检查描述:', + style: TextStyle( + color: AppStyle.minorTextColor, + ), + ), + TextSpan( + text: e.info, + ), + ], + style: TextStyle( + color: AppStyle.primaryTextColor, + fontSize: 28.sp, + ), + ), + ), + ), + ], + ), + ), + ); + }).toList(), + ); + } + + _buildRow({ + String title, + String subTitle, + VoidCallback onTap, + }) { + return Material( + color: Colors.transparent, + child: InkWell( + onTap: onTap, + child: Container( + decoration: BoxDecoration( + border: Border( + bottom: BorderSide(color: Color(0xFFE8E8E8), width: 1.w)), + ), + child: InkWell( + child: Row( + children: [ + AkuBox.h(96), + Text( + title, + style: TextStyle( + color: AppStyle.primaryTextColor, + fontSize: 28.w, + ), + ), + Spacer(), + Text( + TextUtil.isEmpty(subTitle) ? '请选择' : subTitle, + style: TextStyle( + color: TextUtil.isEmpty(subTitle) + ? AppStyle.minorTextColor + : AppStyle.primaryTextColor, + fontSize: 28.w, + fontWeight: FontWeight.bold, + ), + ), + onTap == null ? SizedBox() : AkuBox.w(24), + onTap == null + ? SizedBox() + : Icon( + Icons.arrow_forward_ios, + size: 32.w, + color: AppStyle.minorTextColor, + ), + ], + ), + ), + ), + ), + ); + } +} diff --git a/lib/ui/sub_pages/decoration_manager/decoration_util.dart b/lib/ui/sub_pages/decoration_manager/decoration_util.dart new file mode 100644 index 0000000..e939efa --- /dev/null +++ b/lib/ui/sub_pages/decoration_manager/decoration_util.dart @@ -0,0 +1,58 @@ +import 'package:aku_community_manager/mock_models/decoration/decoration_model.dart'; +import 'package:aku_community_manager/mock_models/users/user_info_model.dart'; +import 'package:aku_community_manager/provider/user_provider.dart'; +import 'package:aku_community_manager/style/app_style.dart'; +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; + +class DecorationUIUtil { + BuildContext context; + USER_ROLE get role => + Provider.of(context, listen: false).userInfoModel.role; + + DecorationUIUtil(this.context); + String getTagName(DecorationType type, DecorationStatusType statusType) { + Map managerMap = { + DecorationType.WAIT_HAND_OUT: '待指派', + DecorationType.HAND_OUT: '已指派', + DecorationType.DONE: '已执行', + }; + + Map fixerMap = { + DecorationType.HAND_OUT: '待执行', + DecorationType.DONE: '已执行', + }; + + Map defaultMap = { + DecorationStatusType.DONE: '装修完成', + DecorationStatusType.PROGRESS: '装修中', + }; + + switch (role) { + case USER_ROLE.MANAGER: + return managerMap[type]; + break; + case USER_ROLE.PROPERTY: + return fixerMap[type]; + break; + default: + return defaultMap[statusType]; + break; + } + } + + Color getTagColor(DecorationType type, DecorationStatusType statusType) { + if (role == USER_ROLE.MANAGER || role == USER_ROLE.PROPERTY) { + if (type == DecorationType.WAIT_HAND_OUT || + type == DecorationType.HAND_OUT) { + return Color(0xFFFF4501); + } else + return AppStyle.minorTextColor; + } else { + if (statusType == DecorationStatusType.PROGRESS) { + return Color(0xFFFF4501); + } else + return Color(0xFF32B814); + } + } +} diff --git a/lib/ui/tool_pages/scan_page.dart b/lib/ui/tool_pages/scan_page.dart index cd7c3c7..ac7ebaf 100644 --- a/lib/ui/tool_pages/scan_page.dart +++ b/lib/ui/tool_pages/scan_page.dart @@ -1,3 +1,7 @@ +import 'dart:async'; + +import 'package:aku_community_manager/tools/screen_tool.dart'; +import 'package:aku_community_manager/ui/widgets/common/aku_back_button.dart'; import 'package:bot_toast/bot_toast.dart'; import 'package:flutter/material.dart'; import 'package:qr_code_scanner/qr_code_scanner.dart'; @@ -12,10 +16,25 @@ class ScanPage extends StatefulWidget { class _ScanPageState extends State { GlobalKey qrKey = GlobalKey(debugLabel: 'QR'); QRViewController _qrViewController; + String tempText; + Timer _timer; + bool _barMove = false; + + @override + void initState() { + super.initState(); + _timer = Timer.periodic(Duration(milliseconds: 1000), (timer) { + if (mounted) + setState(() { + _barMove = !_barMove; + }); + }); + } @override void dispose() { _qrViewController?.dispose(); + _timer?.cancel(); super.dispose(); } @@ -29,20 +48,47 @@ class _ScanPageState extends State { onQRViewCreated: (controller) { _qrViewController = controller; controller.scannedDataStream.listen((event) { - BotToast.showText(text: event); + if (tempText != event) { + tempText = event; + BotToast.showText(text: event); + } }); }, ), Center( - child: Container( - height: 200, - width: 200, - decoration: BoxDecoration( - border: Border.all( - color: Colors.red, - width: 1, + child: Stack( + children: [ + Container( + height: 200, + width: 200, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(8), + border: Border.all( + color: Colors.red, + width: 1, + ), + ), ), - ), + AnimatedPositioned( + top: _barMove ? 10 : 190, + child: Container( + width: 200, + height: 2, + color: Colors.red, + ), + curve: Curves.easeInOutCubic, + duration: Duration(milliseconds: 300), + ), + ], + ), + ), + Positioned( + left: 10, + top: 10 + statusBarHeight, + child: Material( + color: Colors.black45, + borderRadius: BorderRadius.circular(40), + child: AkuBackButton.close(brightness: Brightness.dark), ), ), ], diff --git a/lib/ui/widgets/inner/show_bottom_sheet.dart b/lib/ui/widgets/inner/show_bottom_sheet.dart index e1c3d6c..bdc51a9 100644 --- a/lib/ui/widgets/inner/show_bottom_sheet.dart +++ b/lib/ui/widgets/inner/show_bottom_sheet.dart @@ -6,7 +6,7 @@ import 'package:get/get.dart'; import 'package:aku_community_manager/tools/screen_tool.dart'; ///show bottom sheet -showAkuSheet({ +Future showAkuSheet({ Widget child, }) async { await Get.bottomSheet( @@ -20,12 +20,7 @@ showAkuSheet({ ); } -Future showItemSheet({ - String title, - List items, - String selectItem, - Function(String result) onTap, -}) async { +Future showNormalSheet(String title, List children) async { await showAkuSheet( child: Column( mainAxisSize: MainAxisSize.min, @@ -49,27 +44,38 @@ Future showItemSheet({ 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(), + ...children, ], ), ); } + +Future showItemSheet({ + String title, + List items, + String selectItem, + Function(String result) onTap, +}) async { + await showNormalSheet( + title, + 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()); +} diff --git a/pubspec.lock b/pubspec.lock index f59367b..d2f6c2f 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -141,6 +141,11 @@ packages: url: "https://pub.flutter-io.cn" source: hosted version: "2.1.6" + flutter_localizations: + dependency: "direct main" + description: flutter + source: sdk + version: "0.0.0" flutter_plugin_android_lifecycle: dependency: transitive description: @@ -202,6 +207,13 @@ packages: url: "https://pub.flutter-io.cn" source: hosted version: "1.1.1" + intl: + dependency: transitive + description: + name: intl + url: "https://pub.flutter-io.cn" + source: hosted + version: "0.16.1" matcher: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 5a8ecaf..c180439 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -23,6 +23,8 @@ environment: dependencies: flutter: sdk: flutter + flutter_localizations: + sdk: flutter # The following adds the Cupertino Icons font to your application. # Use with the CupertinoIcons class for iOS style icons.