完成设施页面接口对接

hmxc
小赖 4 years ago
parent 23e9551f51
commit ed410f40f8

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

@ -158,6 +158,9 @@ class R {
/// ![preview](file:///Users/akufe/Documents/aku_community/assets/icons/consult.png) /// ![preview](file:///Users/akufe/Documents/aku_community/assets/icons/consult.png)
static const String ASSETS_ICONS_CONSULT_PNG = 'assets/icons/consult.png'; static const String ASSETS_ICONS_CONSULT_PNG = 'assets/icons/consult.png';
/// ![preview](file:///Users/akufe/Documents/aku_community/assets/icons/facility.png)
static const String ASSETS_ICONS_FACILITY_PNG = 'assets/icons/facility.png';
/// ![preview](file:///Users/akufe/Documents/aku_community/assets/icons/file.png) /// ![preview](file:///Users/akufe/Documents/aku_community/assets/icons/file.png)
static const String ASSETS_ICONS_FILE_PNG = 'assets/icons/file.png'; static const String ASSETS_ICONS_FILE_PNG = 'assets/icons/file.png';

@ -1,6 +1,6 @@
class API { class API {
///HOST ///HOST
static const String host = 'http://test.kaidalai.cn'; static const String host = 'http://39.103.177.88:8804';
/// ///
static const String baseURL = '$host/IntelligentCommunity/app'; static const String baseURL = '$host/IntelligentCommunity/app';
@ -296,4 +296,16 @@ class _Facility {
/// ///
String get appointment => '/user/facilitiesAppointment/list'; String get appointment => '/user/facilitiesAppointment/list';
///
String get add => '/user/facilitiesAppointment/insert';
///
String get scan => '/user/facilitiesAppointment/signIn';
///
String get cancel => '/user/facilitiesAppointment/cancel';
///使
String get stop => '/user/facilitiesAppointment/useStop';
} }

@ -1,3 +1,4 @@
import 'package:aku_community/base/base_style.dart';
import 'package:flustars/flustars.dart'; import 'package:flustars/flustars.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:json_annotation/json_annotation.dart'; import 'package:json_annotation/json_annotation.dart';
@ -39,7 +40,7 @@ class FacilityAppointmentModel {
Color get statusColor { Color get statusColor {
switch (status) { switch (status) {
case 1: case 1:
return Colors.blue; return kPrimaryColor;
case 2: case 2:
return Color(0xFF2576E5); return Color(0xFF2576E5);
case 3: case 3:
@ -56,7 +57,7 @@ class FacilityAppointmentModel {
String get statusValue { String get statusValue {
switch (status) { switch (status) {
case 1: case 1:
return '未签到'; return '预约成功';
case 2: case 2:
return '签到成功'; return '签到成功';
case 3: case 3:

@ -0,0 +1,53 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:qr_code_scanner/qr_code_scanner.dart';
class BeeQR {
static Future<String?> scan() async {
return await Get.to(() => _QRScanPage());
}
}
class _QRScanPage extends StatefulWidget {
_QRScanPage({Key? key}) : super(key: key);
@override
__QRScanPageState createState() => __QRScanPageState();
}
class __QRScanPageState extends State<_QRScanPage> {
final GlobalKey qrKey = GlobalKey(debugLabel: 'QR');
QRViewController? _controller;
bool _doneTag = false;
@override
void dispose() {
_controller?.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: SizedBox(
width: double.infinity,
height: double.infinity,
child: QRView(
key: qrKey,
overlay: QrScannerOverlayShape(
borderRadius: 8,
),
onQRViewCreated: (controller) {
_controller = controller;
controller.scannedDataStream.listen((event) {
if (!_doneTag) {
_doneTag = true;
Get.back(result: event.code);
}
});
},
),
),
);
}
}

@ -1,11 +1,20 @@
import 'package:aku_community/base/base_style.dart';
import 'package:aku_community/constants/api.dart';
import 'package:aku_community/models/facility/facility_appointment_model.dart'; import 'package:aku_community/models/facility/facility_appointment_model.dart';
import 'package:aku_community/ui/common/qr_scan.dart';
import 'package:aku_community/utils/network/net_util.dart';
import 'package:aku_community/widget/bee_divider.dart'; import 'package:aku_community/widget/bee_divider.dart';
import 'package:bot_toast/bot_toast.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:aku_community/utils/headers.dart'; import 'package:aku_community/utils/headers.dart';
import 'package:get/get.dart';
class FacilityAppointmentCard extends StatelessWidget { class FacilityAppointmentCard extends StatelessWidget {
final FacilityAppointmentModel model; final FacilityAppointmentModel model;
const FacilityAppointmentCard({Key? key, required this.model}) final VoidCallback onUpdate;
const FacilityAppointmentCard(
{Key? key, required this.model, required this.onUpdate})
: super(key: key); : super(key: key);
Widget _renderTile({ Widget _renderTile({
@ -21,7 +30,12 @@ class FacilityAppointmentCard extends StatelessWidget {
width: 40.w, width: 40.w,
), ),
12.wb, 12.wb,
Text(name), Text(
name,
style: TextStyle(
color: ktextSubColor,
),
),
Spacer(), Spacer(),
Text(subTitle), Text(subTitle),
], ],
@ -30,9 +44,95 @@ class FacilityAppointmentCard extends StatelessWidget {
Widget _renderButton() { Widget _renderButton() {
var showTip = model.status == 1 || model.status == 2; var showTip = model.status == 1 || model.status == 2;
late Widget button;
switch (model.status) {
case 1:
//1.(30)
if (model.appointmentStart == null) button = SizedBox();
int diffTime =
model.appointmentStart!.difference(DateTime.now()).inMinutes;
bool inTime = diffTime >= 0 && diffTime <= 30;
if (inTime)
button = _FacilityButton(
onPressed: () async {
var result = await BeeQR.scan();
if (result != null) {
final cancel = BotToast.showLoading();
await NetUtil().get(
API.manager.facility.scan,
params: {'appointmentCode': result},
showMessage: true,
);
cancel();
onUpdate();
}
},
text: '扫码签到',
);
else
button = _FacilityButton(
onPressed: () async {
bool? result = await Get.dialog(
CupertinoAlertDialog(
title: Text('取消预约'),
content: Text('您确定要取消预约吗?'),
actions: [
CupertinoDialogAction(
child: Text('先等等'),
onPressed: () => Get.back(),
),
CupertinoDialogAction(
child: Text('取消预约'),
onPressed: () => Get.back(result: true),
),
],
),
);
if (result == true) {
final cancel = BotToast.showLoading();
await NetUtil().get(
API.manager.facility.cancel,
params: {'facilitiesAppointmentId': model.id},
showMessage: true,
);
cancel();
onUpdate();
}
},
text: '取消预约',
);
break;
case 2:
button = _FacilityButton(
onPressed: () async {
final cancel = BotToast.showLoading();
await NetUtil().get(
API.manager.facility.stop,
params: {'facilitiesAppointmentId': model.id},
showMessage: true,
);
cancel();
onUpdate();
},
text: '使用结束',
);
break;
default:
button = SizedBox();
}
return Row( return Row(
children: [ children: [
if (showTip) Text('请在预约时间前30分钟内到场扫码'), if (showTip)
Text(
'请在预约时间前30分钟内到场扫码',
style: TextStyle(
color: ktextSubColor,
fontSize: 24.sp,
),
),
Spacer(),
button,
], ],
); );
} }
@ -92,3 +192,39 @@ class FacilityAppointmentCard extends StatelessWidget {
); );
} }
} }
class _FacilityButton extends StatelessWidget {
final Color color;
final Color textColor;
final VoidCallback onPressed;
final String text;
final bool outline;
const _FacilityButton({
Key? key,
this.color = kPrimaryColor,
required this.onPressed,
required this.text,
this.outline = false,
this.textColor = ktextPrimary,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialButton(
color: outline ? null : color,
shape: StadiumBorder(),
elevation: 0,
height: 60.w,
minWidth: 168.w,
padding: EdgeInsets.zero,
onPressed: onPressed,
child: Text(
text,
style: TextStyle(
color: textColor,
fontSize: 26.sp,
),
),
);
}
}

@ -1,8 +1,11 @@
import 'package:aku_community/ui/community/facility/facility_appointment_view.dart'; import 'package:aku_community/ui/community/facility/facility_appointment_view.dart';
import 'package:aku_community/ui/community/facility/facility_preview_page.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:aku_community/widget/bee_scaffold.dart'; import 'package:aku_community/widget/bee_scaffold.dart';
import 'package:aku_community/widget/tab_bar/bee_tab_bar.dart'; import 'package:aku_community/widget/tab_bar/bee_tab_bar.dart';
import 'package:get/get.dart';
class FacilityAppointmentPage extends StatefulWidget { class FacilityAppointmentPage extends StatefulWidget {
FacilityAppointmentPage({Key? key}) : super(key: key); FacilityAppointmentPage({Key? key}) : super(key: key);
@ -31,6 +34,12 @@ class _FacilityAppointmentPageState extends State<FacilityAppointmentPage>
Widget build(BuildContext context) { Widget build(BuildContext context) {
return BeeScaffold( return BeeScaffold(
title: '设施预约', title: '设施预约',
actions: [
IconButton(
icon: Icon(CupertinoIcons.add_circled),
onPressed: () => Get.to(() => FacilityPreorderPage()),
),
],
appBarBottom: BeeTabBar( appBarBottom: BeeTabBar(
controller: _tabController, controller: _tabController,
tabs: ['我的预约', '历史预约'], tabs: ['我的预约', '历史预约'],

@ -50,7 +50,12 @@ class _FacilityAppointmentViewState extends State<FacilityAppointmentView> {
return ListView.separated( return ListView.separated(
padding: EdgeInsets.all(32.w), padding: EdgeInsets.all(32.w),
itemBuilder: (context, index) { itemBuilder: (context, index) {
return FacilityAppointmentCard(model: items[index]); return FacilityAppointmentCard(
model: items[index],
onUpdate: () {
_refreshController.callRefresh();
},
);
}, },
separatorBuilder: (_, __) => 32.hb, separatorBuilder: (_, __) => 32.hb,
itemCount: items.length, itemCount: items.length,

@ -1,25 +0,0 @@
import 'package:flutter/material.dart';
import 'package:aku_community/widget/bee_scaffold.dart';
class FacilityPage extends StatefulWidget {
FacilityPage({Key? key}) : super(key: key);
@override
_FacilityPageState createState() => _FacilityPageState();
}
class _FacilityPageState extends State<FacilityPage> {
@override
Widget build(BuildContext context) {
return BeeScaffold(
title: '设施预约',
actions: [
IconButton(
icon: Icon(Icons.add_circle_outline_rounded, color: Colors.black87),
onPressed: () {},
),
],
);
}
}

@ -0,0 +1,177 @@
import 'package:aku_community/base/base_style.dart';
import 'package:aku_community/constants/api.dart';
import 'package:aku_community/constants/app_theme.dart';
import 'package:aku_community/provider/app_provider.dart';
import 'package:aku_community/ui/community/facility/pick_facility_page.dart';
import 'package:aku_community/ui/profile/house/pick_my_house_page.dart';
import 'package:aku_community/utils/headers.dart';
import 'package:aku_community/utils/network/net_util.dart';
import 'package:aku_community/widget/bee_divider.dart';
import 'package:aku_community/widget/bee_scaffold.dart';
import 'package:aku_community/widget/buttons/bottom_button.dart';
import 'package:aku_community/widget/picker/bee_date_picker.dart';
import 'package:bot_toast/bot_toast.dart';
import 'package:flustars/flustars.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:provider/provider.dart';
import 'package:aku_community/models/facility/facility_type_model.dart';
class FacilityPreorderPage extends StatefulWidget {
FacilityPreorderPage({Key? key}) : super(key: key);
@override
_FacilityPreorderPageState createState() => _FacilityPreorderPageState();
}
class _FacilityPreorderPageState extends State<FacilityPreorderPage> {
FacilityTypeModel? typeModel;
DateTime? startDate;
DateTime? endDate;
bool get canTap => startDate != null && endDate != null && typeModel != null;
@override
Widget build(BuildContext context) {
final appProvider = Provider.of<AppProvider>(context);
return BeeScaffold(
title: '添加预订',
bodyColor: Colors.white,
systemStyle: SystemStyle.yellowBottomBar,
body: ListView(
padding: EdgeInsets.symmetric(vertical: 32.w),
children: [
Text('业主房屋').pSymmetric(h: 32.w),
ListTile(
leading: Image.asset(
R.ASSETS_ICONS_HOUSE_PNG,
height: 60.w,
width: 60.w,
),
onTap: () => Get.to(() => PickMyHousePage()),
title: Text(S.of(context)!.tempPlotName),
subtitle: Text(appProvider.selectedHouse?.roomName ?? '选择房间'),
trailing: Icon(CupertinoIcons.chevron_forward),
),
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,
),
onTap: () async {
FacilityTypeModel? model = await Get.to(() => PickFacilityPage());
if (model != null) typeModel = model;
setState(() {});
},
title: Text(S.of(context)!.tempPlotName),
subtitle: Text(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(
children: [
MaterialButton(
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
height: 120.w,
onPressed: () async {
DateTime? date = await BeeDatePicker.pick(
DateTime.now(),
mode: CupertinoDatePickerMode.dateAndTime,
min: DateTime.now().subtract(Duration(seconds: 1)),
max: DateTime.now().add(Duration(days: 30)),
);
if (date != null) {
startDate = date;
setState(() {});
}
},
child: Text(
startDate == null
? '请选择开始时间'
: DateUtil.formatDate(
startDate,
format: 'yyyy-MM-dd HH:mm',
),
style: TextStyle(
color: ktextSubColor,
),
),
).expand(),
Icon(Icons.arrow_forward),
MaterialButton(
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
height: 120.w,
onPressed: () async {
DateTime? date = await BeeDatePicker.pick(
startDate == null ? DateTime.now() : startDate!,
min: startDate == null
? DateTime.now().subtract(Duration(seconds: 1))
: startDate!,
max: startDate == null
? DateTime.now().add(Duration(days: 1))
: (startDate!).add(Duration(days: 1)),
mode: CupertinoDatePickerMode.dateAndTime,
);
if (date != null) {
endDate = date;
setState(() {});
}
},
child: Text(
endDate == null
? '请选择结束时间'
: DateUtil.formatDate(
endDate,
format: 'yyyy-MM-dd HH:mm',
),
style: TextStyle(
color: ktextSubColor,
),
),
).expand(),
],
),
),
BeeDivider(
indent: 32.w,
endIndent: 32.w,
),
],
),
bottomNavi: BottomButton(
onPressed: canTap
? () async {
final cancel = BotToast.showLoading();
var model = await NetUtil().post(
API.manager.facility.add,
params: {
'estateId': appProvider.selectedHouse?.estateId ?? 0,
'facilitiesManageId': typeModel!.id,
'appointmentStartDate': NetUtil.getDate(startDate!),
'appointmentEndDate': NetUtil.getDate(endDate!),
},
showMessage: true,
);
cancel();
if (model.status == true) Get.back(result: true);
}
: null,
child: Text('确认提交'),
),
);
}
}

@ -5,6 +5,7 @@ import 'package:aku_community/constants/api.dart';
import 'package:aku_community/model/common/img_model.dart'; import 'package:aku_community/model/common/img_model.dart';
import 'package:aku_community/models/facility/facility_type_model.dart'; import 'package:aku_community/models/facility/facility_type_model.dart';
import 'package:aku_community/utils/headers.dart'; import 'package:aku_community/utils/headers.dart';
import 'package:get/get.dart';
class FacilityTypeCard extends StatelessWidget { class FacilityTypeCard extends StatelessWidget {
final FacilityTypeModel model; final FacilityTypeModel model;
@ -13,6 +14,8 @@ class FacilityTypeCard extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return MaterialButton( return MaterialButton(
color: Colors.white,
elevation: 0,
padding: EdgeInsets.zero, padding: EdgeInsets.zero,
clipBehavior: Clip.antiAlias, clipBehavior: Clip.antiAlias,
shape: RoundedRectangleBorder( shape: RoundedRectangleBorder(
@ -64,29 +67,13 @@ class FacilityTypeCard extends StatelessWidget {
], ],
), ),
), ),
MaterialButton(
height: 52.w,
minWidth: 168.w,
padding: EdgeInsets.zero,
elevation: 0,
shape: StadiumBorder(),
color: kPrimaryColor,
onPressed: () {},
child: Text(
'填写预约',
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 26.sp,
),
),
),
32.wb, 32.wb,
], ],
), ),
24.hb, 24.hb,
], ],
), ),
onPressed: () {}, onPressed: () => Get.back(result: model),
); );
} }
} }

@ -10,11 +10,14 @@ class BeeDatePicker {
static Future<DateTime?> pick( static Future<DateTime?> pick(
DateTime initDate, { DateTime initDate, {
CupertinoDatePickerMode mode = CupertinoDatePickerMode.date, CupertinoDatePickerMode mode = CupertinoDatePickerMode.date,
DateTime? min,
DateTime? max,
}) async { }) async {
return await Get.bottomSheet(_BeeDatePicker( return await Get.bottomSheet(_BeeDatePicker(
date: initDate, date: initDate,
mode: mode, mode: mode,
min: DateTime.now().subtract(Duration(days: 1)), min: min ?? DateTime.now().subtract(Duration(days: 1)),
max: max,
)); ));
} }

@ -858,6 +858,13 @@ packages:
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "2.0.0" version: "2.0.0"
qr_code_scanner:
dependency: "direct main"
description:
name: qr_code_scanner
url: "https://pub.flutter-io.cn"
source: hosted
version: "0.4.0"
qr_flutter: qr_flutter:
dependency: "direct main" dependency: "direct main"
description: description:

@ -67,6 +67,7 @@ dependencies:
collection: ^1.15.0 collection: ^1.15.0
json_annotation: ^4.0.1 json_annotation: ^4.0.1
waterfall_flow: ^3.0.1 waterfall_flow: ^3.0.1
qr_code_scanner: ^0.4.0
dev_dependencies: dev_dependencies:
flutter_test: flutter_test:

Loading…
Cancel
Save