diff --git a/.fvm/fvm_config.json b/.fvm/fvm_config.json index d4e14b2a..b8e6b4ff 100644 --- a/.fvm/fvm_config.json +++ b/.fvm/fvm_config.json @@ -1,4 +1,4 @@ { - "flutterSdkVersion": "3.0.0", + "flutterSdkVersion": "2.8.1", "flavors": {} } \ No newline at end of file diff --git a/lib/models/facility/facility_appointment_model.dart b/lib/models/facility/facility_appointment_model.dart index 9411e159..179d50ac 100644 --- a/lib/models/facility/facility_appointment_model.dart +++ b/lib/models/facility/facility_appointment_model.dart @@ -40,11 +40,11 @@ class FacilityAppointmentModel { Color get statusColor { switch (status) { case 1: - return kPrimaryColor; + return kBalckSubColor; case 2: - return Color(0xFF2576E5); + return kDarkPrimaryColor; case 3: - return Color(0xFFFB4702); + return kDangerColor; case 4: return Color(0xFF999999); case 5: @@ -57,15 +57,15 @@ class FacilityAppointmentModel { String get statusValue { switch (status) { case 1: - return '预约成功'; + return '待签到'; case 2: - return '签到成功'; + return '使用中'; case 3: - return '预约作废'; + return '超时作废'; case 4: - return '已取消'; + return '取消预约'; case 5: - return '已结束'; + return '使用结束'; default: return '未知状态'; } diff --git a/lib/models/test.dart b/lib/models/test.dart new file mode 100644 index 00000000..77462aa9 --- /dev/null +++ b/lib/models/test.dart @@ -0,0 +1,20 @@ +import 'package:json_annotation/json_annotation.dart'; +import 'package:equatable/equatable.dart'; + +part 'test.g.dart'; + +@JsonSerializable() +class Test extends Equatable { + final int id; + + factory Test.fromJson(Map json) => _$TestFromJson(json); + + @override + List get props => [ + id, + ]; + + const Test({ + required this.id, + }); +} diff --git a/lib/models/test.g.dart b/lib/models/test.g.dart new file mode 100644 index 00000000..180ef7d1 --- /dev/null +++ b/lib/models/test.g.dart @@ -0,0 +1,11 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'test.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +Test _$TestFromJson(Map json) => Test( + id: json['id'] as int, + ); diff --git a/lib/provider/user_provider.dart b/lib/provider/user_provider.dart index 9a047d2a..07135df7 100644 --- a/lib/provider/user_provider.dart +++ b/lib/provider/user_provider.dart @@ -123,7 +123,8 @@ class UserProvider extends ChangeNotifier { '栋' + _defaultHouse!.unitName + '单元' + - _defaultHouse!.estateName; + _defaultHouse!.estateName + + '室'; } } diff --git a/lib/saas_model/my_house/my_family_member_list_model.dart b/lib/saas_model/my_house/my_family_member_list_model.dart index 81ccad45..7978c0dd 100644 --- a/lib/saas_model/my_house/my_family_member_list_model.dart +++ b/lib/saas_model/my_house/my_family_member_list_model.dart @@ -31,7 +31,7 @@ class Member { final int id; final String name; final int identity; - final List avatarImgList; + final List imgList; factory Member.fromJson(Map json) => _$MemberFromJson(json); @@ -39,6 +39,6 @@ class Member { required this.id, required this.name, required this.identity, - required this.avatarImgList, + required this.imgList, }); } diff --git a/lib/saas_model/my_house/my_family_member_list_model.g.dart b/lib/saas_model/my_house/my_family_member_list_model.g.dart index c1d940ba..0ec59a5f 100644 --- a/lib/saas_model/my_house/my_family_member_list_model.g.dart +++ b/lib/saas_model/my_house/my_family_member_list_model.g.dart @@ -23,7 +23,7 @@ Member _$MemberFromJson(Map json) => Member( id: json['id'] as int, name: json['name'] as String, identity: json['identity'] as int, - avatarImgList: (json['avatarImgList'] as List) + imgList: (json['imgList'] as List) .map((e) => ImgModel.fromJson(e as Map)) .toList(), ); diff --git a/lib/ui/community/facility/facility_appointment_card.dart b/lib/ui/community/facility/facility_appointment_card.dart index 2aaf7ec0..98276e5f 100644 --- a/lib/ui/community/facility/facility_appointment_card.dart +++ b/lib/ui/community/facility/facility_appointment_card.dart @@ -1,3 +1,4 @@ +import 'package:aku_new_community/ui/community/facility/pick_facility_page.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; @@ -36,11 +37,16 @@ class FacilityAppointmentCard extends StatelessWidget { Text( name, style: TextStyle( - color: ktextSubColor, + color: ktextThirdColor, ), ), Spacer(), - Text(subTitle), + Text( + subTitle, + style: TextStyle( + color: ktextSubColor, + ), + ), ], ); } @@ -57,13 +63,17 @@ class FacilityAppointmentCard extends StatelessWidget { bool inTime = diffTime >= 0 && diffTime <= 30; if (inTime) button = _FacilityButton( + bold: true, onPressed: () async { var result = await BeeQR.scan(); if (result != null) { final cancel = BotToast.showLoading(); await NetUtil().get( SAASAPI.facilities.signIn, - params: {'appointmentCode': result}, + params: { + 'facilitiesReserveId': model.id, + 'appointmentCode': result + }, showMessage: true, ); cancel(); @@ -74,6 +84,9 @@ class FacilityAppointmentCard extends StatelessWidget { ); else button = _FacilityButton( + outline: true, + border: true, + bold: true, onPressed: () async { bool? result = await Get.dialog( CupertinoAlertDialog( @@ -95,7 +108,7 @@ class FacilityAppointmentCard extends StatelessWidget { final cancel = BotToast.showLoading(); await NetUtil().get( SAASAPI.facilities.cancel, - params: {'facilitiesAppointmentId': model.id}, + params: {'facilitiesReserveId': model.id}, showMessage: true, ); cancel(); @@ -107,11 +120,12 @@ class FacilityAppointmentCard extends StatelessWidget { break; case 2: button = _FacilityButton( + bold: true, onPressed: () async { final cancel = BotToast.showLoading(); await NetUtil().get( SAASAPI.facilities.useStop, - params: {'facilitiesAppointmentId': model.id}, + params: {'facilitiesReserveId': model.id}, showMessage: true, ); cancel(); @@ -120,24 +134,62 @@ class FacilityAppointmentCard extends StatelessWidget { text: '使用结束', ); break; - default: - button = SizedBox(); + button = _FacilityButton( + outline: true, + border: true, + bold: true, + textColor: ktextSubColor, + onPressed: () async { + await Get.to(() => PickFacilityPage()); + }, + text: '重新预约', + ); } - return Row( - children: [ - if (showTip) - Text( - '请在预约时间前30分钟内到场扫码', - style: TextStyle( - color: ktextSubColor, - fontSize: 24.sp, - ), - ), - Spacer(), - button, - ], - ); + return model.status == 3 + ? Column( + children: [ + Container( + color: Colors.black12.withOpacity(0.25), + padding: EdgeInsets.all(10.w), + child: Text( + '作废原因:${model.nullifyReason??''}', + style: TextStyle( + color: Colors.black.withOpacity(0.8), + fontSize: 24.sp, + ), + ), + ), + Row( + children: [ + if (showTip) + Text( + '请在预约时间前30分钟内到场扫码', + style: TextStyle( + color: ktextSubColor, + fontSize: 24.sp, + ), + ), + Spacer(), + button, + ], + ), + ], + ) + : Row( + children: [ + if (showTip) + Text( + '请在预约时间前30分钟内到场扫码', + style: TextStyle( + color: ktextThirdColor, + fontSize: 24.sp, + ), + ), + Spacer(), + button, + ], + ); } @override @@ -202,6 +254,8 @@ class _FacilityButton extends StatelessWidget { final VoidCallback onPressed; final String text; final bool outline; + final bool border; + final bool bold; const _FacilityButton({ Key? key, @@ -210,13 +264,21 @@ class _FacilityButton extends StatelessWidget { required this.text, this.outline = false, this.textColor = ktextPrimary, + this.border = false, + this.bold = false, }) : super(key: key); @override Widget build(BuildContext context) { return MaterialButton( color: outline ? null : color, - shape: StadiumBorder(), + shape: border + ? StadiumBorder( + side: BorderSide( + width: 1, + color: Colors.grey, + )) + : StadiumBorder(), elevation: 0, height: 60.w, minWidth: 168.w, @@ -225,6 +287,7 @@ class _FacilityButton extends StatelessWidget { child: Text( text, style: TextStyle( + fontWeight: bold?FontWeight.bold:FontWeight.normal, color: textColor, fontSize: 26.sp, ), diff --git a/lib/ui/community/facility/facility_preorder_date_picker.dart b/lib/ui/community/facility/facility_preorder_date_picker.dart index 68a47bc6..0b8f57c9 100644 --- a/lib/ui/community/facility/facility_preorder_date_picker.dart +++ b/lib/ui/community/facility/facility_preorder_date_picker.dart @@ -14,6 +14,15 @@ import '../../../utils/network/base_model.dart'; import '../../../utils/network/net_util.dart'; import '../../../widget/buttons/bee_check_radio.dart'; +class FacilityPreorderDate { + static Future> choose( + FacilityTypeDetailModel typeModel, + ) async { + return await Get.bottomSheet( + FacilityPreorderDatePicker(typeModel: typeModel)); + } +} + class FacilityPreorderDatePicker extends StatefulWidget { FacilityTypeDetailModel typeModel; @@ -35,14 +44,15 @@ class _FacilityPreorderDatePickerState List models = []; List _selectIndex = []; - + List _selectDates = []; @override Widget build(BuildContext context) { return BeeChooseDatePicker( height: 700.h, onPressed: () { - Get.back(result: _selectIndex); + Get.back(result: _selectDates); + //print(_selectDates); }, body: Container( height: 600.h, @@ -77,17 +87,20 @@ class _FacilityPreorderDatePickerState 'todayDate': DateTime.now(), }); if (model.success) { - models = (model.data as List).toList(); + models = (model.data as List); } }; return GestureDetector( onTap: () { - print(getNum(start)+index); - if(!models.contains(getNum(start)+index)||isPass(start.add(Duration(minutes: 30 * index)))){ + //print(getNum(start)+index); + if (!models.contains(getNum(start) + index) || + isPass(start.add(Duration(minutes: 30 * index)))) { if (_selectIndex.contains(index)) { _selectIndex.remove(index); + _selectDates.remove(getNum(start) + index); } else { _selectIndex.add(index); + _selectDates.add(getNum(start) + index); } } setState(() {}); @@ -98,7 +111,8 @@ class _FacilityPreorderDatePickerState BeeCheckRadio( value: index, groupValue: _selectIndex, - canCheck: models.contains(getNum(start)+index)||isPass(start.add(Duration(minutes: 30 * index))), + canCheck: models.contains(getNum(start) + index) || + isPass(start.add(Duration(minutes: 30 * index))), ), 30.wb, Text( @@ -115,7 +129,7 @@ class _FacilityPreorderDatePickerState .size(30.sp) .color(Colors.black.withOpacity(0.45)) .make() - : models.contains(getNum(start)+index) + : models.contains(getNum(start) + index) ? '已被他人预约' .text .size(30.sp) @@ -128,14 +142,14 @@ class _FacilityPreorderDatePickerState } } -bool isPass(DateTime date){ - if(date.hour _FacilityPreorderPageState(); } class _FacilityPreorderPageState extends State { - DateTime? startDate; - DateTime? endDate; + List dateList = []; + DateTime? date; - bool get canTap => startDate != null && endDate != null; + bool get canTap => dateList.isNotEmpty; @override Widget build(BuildContext context) { final userProvider = Provider.of(context); return BeeScaffold( - title: '添加预订', + title: '添加预约', systemStyle: SystemStyle.yellowBottomBar, body: ListView( - padding: EdgeInsets.symmetric(vertical: 32.w), + padding: EdgeInsets.symmetric(vertical: 20.w), children: [ Container( + padding: EdgeInsets.all(10.w), color: Colors.white, - child:ListTile( - leading: Image.asset( - R.ASSETS_ICONS_HOUSE_PNG, - height: 60.w, - width: 60.w, + child: ListTile( + leading: BeeAvatarWidget( + width: 90.w, + height: 90.w, + imgs: UserTool.userProvider.userInfoModel!.imgList, ), onTap: () => Get.to(() => AdviceHousePage()), - title: Text(S.of(context)!.tempPlotName), - subtitle: Text(userProvider.defaultHouse!.addressName), - trailing: Icon(CupertinoIcons.chevron_forward), - ), - ), - - - - Text('业主房屋').pSymmetric(h: 32.w), - - BeeDivider( - indent: 32.w, - endIndent: 32.w, - ), - 32.hb, - Text('选择设施').pSymmetric(h: 32.w), - ListTile( - leading: Image.asset( - R.ASSETS_ICONS_FACILITY_PNG, - height: 60.w, - width: 60.w, + title: Text( + UserTool.userProvider.userInfoModel!.name!, + style: TextStyle( + fontSize: 30.sp, + ), + ), + subtitle: Text( + '租户 ' + + userProvider.defaultHouse!.communityName + + userProvider.defaultHouseString, + style: TextStyle( + color: Colors.black.withOpacity(0.45), + fontSize: 26.sp, + ), + ), + trailing: Icon( + CupertinoIcons.chevron_forward, + size: 35.w, + color: Colors.black.withOpacity(0.25), + ), ), - onTap: () async {await Get.to(() => - FacilityTypeDetailPage(facilityModel: widget.facilityModel)); - setState(() {}); - }, - title: Text(S.of(context)!.tempPlotName), - subtitle: Text(widget.typeModel.name), - trailing: Icon(CupertinoIcons.chevron_forward), - ), - BeeDivider( - indent: 32.w, - endIndent: 32.w, ), - 32.hb, - Text('预约时间').pSymmetric(h: 32.w), - SizedBox( - height: 120.w, - child: Row( + 20.hb, + Container( + padding: EdgeInsets.all(40.w), + color: Colors.white, + child: Column( children: [ - MaterialButton( - materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, - height: 120.w, - onPressed: () async { - DateTime? date = await BeeDayPicker.pick(DateTime.now()); - print(date); - if (date != null) { - startDate = date; - Get.bottomSheet(FacilityPreorderDatePicker(typeModel: widget.typeModel,)); - List dateList=FacilityPreorderDatePicker(typeModel: widget.typeModel) as List; - print(dateList); - setState(() {}); - } + GestureDetector( + onTap: () async { + await Get.to(() => FacilityTypeDetailPage( + facilityModel: widget.facilityModel)); + setState(() {}); }, - child: Text( - startDate == null - ? '请选择开始时间' - : DateUtil.formatDate( - startDate, - format: 'yyyy/MM/dd', - ), - style: TextStyle( - color: ktextSubColor, + child: Material( + color: Colors.transparent, + child: Row( + children: [ + SizedBox( + width: 170.w, + child: '选择设施' + .text + .size(28.sp) + .color(Colors.black.withOpacity(0.50)) + .make(), + ), + '${widget.typeModel.name}' + .text + .size(28.sp) + .color(Colors.black.withOpacity(0.85)) + .make(), + Spacer(), + Icon( + CupertinoIcons.chevron_right, + size: 35.w, + color: Colors.black.withOpacity(0.25), + ), + ], ), ), - ).expand(), - Icon(Icons.arrow_forward), - MaterialButton( - materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, - height: 120.w, - onPressed: () async { - DateTime? date = await BeeDatePicker.pick( - startDate == null - ? DateTime.now().add(Duration(minutes: 90)) - : startDate!.add(Duration(minutes: 30)), - min: startDate == null - ? DateTime.now().add(Duration(minutes: 60)) - : startDate!.add(Duration(minutes: 30)), - max: startDate == null - ? DateTime.now().add(Duration(days: 2)) - : (startDate!).add(Duration(days: 2)), - mode: CupertinoDatePickerMode.dateAndTime, - ); + ), + 30.hb, + BeeDivider(), + 30.hb, + GestureDetector( + onTap: () async { + date = await BeeDayPicker.pick(DateTime.now()); if (date != null) { - endDate = date; + dateList = + await FacilityPreorderDate.choose(widget.typeModel); + dateList.sort(); setState(() {}); } }, - child: Text( - endDate == null - ? '请选择结束时间' - : DateUtil.formatDate( - endDate, - format: 'yyyy-MM-dd HH:mm', - ), - style: TextStyle( - color: ktextSubColor, + child: Material( + color: Colors.transparent, + child: Row( + children: [ + SizedBox( + width: 170.w, + child: '预约时间' + .text + .size(28.sp) + .color(Colors.black.withOpacity(0.50)) + .make(), + ), + date != null + ? '${DateUtil.formatDate(date, format: 'yyyy/MM/dd')} ${dateString(dateList)}' + .text + .size(28.sp) + .color(Colors.black.withOpacity(0.85)) + .make() + : '请选择预约时段' + .text + .size(28.sp) + .color(Colors.black.withOpacity(0.85)) + .make(), + Spacer(), + Icon( + CupertinoIcons.chevron_right, + size: 35.w, + color: Colors.black.withOpacity(0.25), + ), + ], ), ), - ).expand(), + ), ], ), ), - BeeDivider( - indent: 32.w, - endIndent: 32.w, - ), ], ), - bottomNavi: BottomButton( - onPressed: canTap - ? () async { - // if (dateDifferenceIsTrue) { - final cancel = BotToast.showLoading(); - var model = await NetUtil().post( - SAASAPI.facilities.insert, - params: { - 'estateId': userProvider.defaultHouse!.id, - 'type':widget.facilityModel.type, - 'facilitiesCategoryId':widget.facilityModel.id, - 'facilitiesManageId':widget.typeModel.id, - 'appointmentDate':1, - 'appointmentPeriodList':1, - }, - ); - cancel(); - if (model.success == true) { - BotToast.showText(text: '预约成功'); - Get.back(result: true); - } else if (model.msg == '该时段已被预约') { - await Get.dialog(_hasBeenOrder()); - } else { - BotToast.showText(text: '预约失败'); + bottomNavi: Padding( + padding: EdgeInsets.only( + left: 32.w, + right: 32.w, + bottom: MediaQuery.of(context).padding.bottom + 32.w), + child: BeeLongButton( + onPressed: canTap + ? () async { + // if (dateDifferenceIsTrue) { + final cancel = BotToast.showLoading(); + var model = await NetUtil().post( + SAASAPI.facilities.insert, + params: { + 'estateId': userProvider.defaultHouse!.id, + 'type': widget.facilityModel.type, + 'facilitiesCategoryId': widget.facilityModel.id, + 'facilitiesManageId': widget.typeModel.id, + 'appointmentDate': DateUtil.formatDate(date,format: 'yyyy-MM-dd HH:mm:ss'), + 'appointmentPeriodList': dateList, + }, + ); + cancel(); + if (model.success == true) { + BotToast.showText(text: '预约成功'); + Get.back(result: true); + } else if (model.msg == '该时段已被预约') { + await Get.dialog(_hasBeenOrder()); + } else { + BotToast.showText(text: '预约失败'); + } + // } else { + // BotToast.showText(text: '预约时间必须为半小时的整数倍'); + // } } - // } else { - // BotToast.showText(text: '预约时间必须为半小时的整数倍'); - // } - } - : null, - child: Text('确认提交'), + : null, + text: '确认提交', + ), ), ); } - bool get dateDifferenceIsTrue { - if (startDate != null && endDate != null) { - int _diff = endDate!.difference(startDate!).inMinutes; - if (_diff < 30) { - return false; - } else if (_diff % 30 != 0) { - return false; - } - return true; - } - return false; - } - Widget _hasBeenOrder() { return CupertinoAlertDialog( title: '此设施已被预约' @@ -241,8 +245,8 @@ class _FacilityPreorderPageState extends State { '取消'.text.size(30.sp).color(ktextPrimary).isIntrinsic.make()), CupertinoActionSheetAction( onPressed: () { - Get.off( - () => FacilityOrderDateListPage(facilitiesId: widget.typeModel.id)); + Get.off(() => + FacilityOrderDateListPage(facilitiesId: widget.typeModel.id)); }, child: '查看'.text.size(30.sp).color(kPrimaryColor).isIntrinsic.make()), @@ -250,3 +254,17 @@ class _FacilityPreorderPageState extends State { ); } } + +DateTime getDate(int dateNum) { + DateTime startDate = DateTime( + DateTime.now().year, DateTime.now().month, DateTime.now().day, 0, 0, 0); + return startDate.add(Duration(minutes: 30 * (dateNum - 1))); +} + +String dateString(List dates){ + if(dates.length==1) + return '${DateUtil.formatDate(getDate(dates.first), format: 'HH:mm')}-${DateUtil.formatDate(getDate(dates.first).add(Duration(minutes: 30)), format: 'HH:mm')}'; + else{ + return '${DateUtil.formatDate(getDate(dates.first), format: 'HH:mm')}-${DateUtil.formatDate(getDate(dates.first).add(Duration(minutes: 30)), format: 'HH:mm')}等'; + } +} \ No newline at end of file diff --git a/lib/ui/profile/new_house/member_view.dart b/lib/ui/profile/new_house/member_view.dart index bcd11ec3..41569d91 100644 --- a/lib/ui/profile/new_house/member_view.dart +++ b/lib/ui/profile/new_house/member_view.dart @@ -82,7 +82,7 @@ class _MemberViewState extends State { crossAxisCount: 4, children: [ ...model.members - .map((e) => _avatar(e.avatarImgList,Identify.values[e.identity], e.name)) + .map((e) => _avatar(e.imgList,Identify.values[e.identity], e.name)) .toList() ], shrinkWrap: true,