471 lines
12 KiB
Dart
471 lines
12 KiB
Dart
import 'dart:async';
|
|
|
|
import 'package:cashier_reserve/common/base/ui_model.dart';
|
|
import 'package:cashier_reserve/common/channel/model/call_log_model.dart';
|
|
import 'package:cashier_reserve/common/channel/channel_manager.dart';
|
|
import 'package:cashier_reserve/common/channel/model/call_status_change_model.dart';
|
|
import 'package:cashier_reserve/common/manager/app_manager.dart';
|
|
import 'package:cashier_reserve/common/manager/event_manager.dart';
|
|
import 'package:cashier_reserve/common/print/print.dart';
|
|
import 'package:cashier_reserve/common/utils/utils.dart';
|
|
import 'package:cashier_reserve/data_model/reserve/reserve_log_model.dart';
|
|
import 'package:cashier_reserve/data_model/reserve/table_area_model.dart';
|
|
import 'package:cashier_reserve/data_model/reserve/table_model.dart';
|
|
import 'package:cashier_reserve/model/reserve_model.dart';
|
|
import 'package:flutter/cupertino.dart';
|
|
import 'package:url_launcher/url_launcher.dart';
|
|
|
|
class ReserveViewModel extends BaseUIModel {
|
|
Map<int, String> weekdayMap = {
|
|
1: "星期一",
|
|
2: "星期二",
|
|
3: "星期三",
|
|
4: "星期四",
|
|
5: "星期五",
|
|
6: "星期六",
|
|
7: "星期日",
|
|
};
|
|
|
|
Map<int, String> dayInfoMap = {
|
|
0: "今",
|
|
1: "明",
|
|
2: "后",
|
|
};
|
|
|
|
PageController pageController = PageController();
|
|
AnimationController? _animationController;
|
|
Animation<double>? _animationSizeFactor;
|
|
|
|
Animation<double>? get animationSizeFactor => _animationSizeFactor;
|
|
|
|
DateTime now = DateTime.now();
|
|
|
|
int selectedDateIndex = 0;
|
|
String selectedDate = "";
|
|
String bookingType = "lunch";
|
|
|
|
List<TableAreaModel?>? _tableAreaList;
|
|
|
|
List<TableAreaModel?>? get tableAreaList => _tableAreaList;
|
|
Map<num, TableAreaModel?> _tableAreaMap = {};
|
|
|
|
List<TableModel?>? _tableList;
|
|
|
|
List<TableModel?>? get tableList => _tableList;
|
|
Map<String, List<TableModel?>> tableMap = {};
|
|
|
|
List<CallLogModel?>? callLogs = [];
|
|
|
|
Map<String, ReserveLogModel?>? _reserveLogMap;
|
|
|
|
bool _isShowReserveInfoView = false;
|
|
|
|
/// bookingGender 预订人性别 1: 男 2: 女
|
|
int bookingGender = 1;
|
|
|
|
/// bookingNumController 就餐人数
|
|
TextEditingController bookingNumController = TextEditingController();
|
|
|
|
/// bookingPhoneController 联系电话
|
|
TextEditingController bookingPhoneController = TextEditingController();
|
|
|
|
/// bookingNameController 预订人姓名
|
|
TextEditingController bookingNameController = TextEditingController();
|
|
|
|
/// bookingTypeController 预订类型
|
|
TextEditingController bookingTypeController = TextEditingController();
|
|
|
|
/// bookingTableNumController 预订台桌数量
|
|
TextEditingController bookingTableNumController = TextEditingController();
|
|
|
|
/// bookingStandardController 预定餐标
|
|
TextEditingController bookingStandardController = TextEditingController();
|
|
|
|
/// bookingRemarkController 备注
|
|
TextEditingController bookingRemarkController = TextEditingController();
|
|
|
|
/// bookingSelectedTime 预订时间
|
|
String bookingSelectedTime = "";
|
|
|
|
/// bookingFocus 重点关注
|
|
bool bookingFocus = false;
|
|
|
|
/// bookingSms 短信通知
|
|
bool bookingSms = false;
|
|
|
|
/// bookingStandardType 餐标类型
|
|
String bookingStandardType = "table";
|
|
|
|
String showTableName = "";
|
|
|
|
TableModel? selectedTable;
|
|
|
|
Timer? periodicTimer;
|
|
|
|
ReserveViewModel() {
|
|
selectedDate = "${now.year}-${now.month}-${now.day}";
|
|
|
|
EventManager.addListener<GetCallLogEvent>(this, (event) {
|
|
if (event.isSuccess) {
|
|
if (!event.isSuccess) {
|
|
return;
|
|
}
|
|
|
|
callLogs = event.callLogs;
|
|
notifyListeners();
|
|
|
|
loadUserReserveLog();
|
|
}
|
|
});
|
|
|
|
loadCallLog();
|
|
loadTableAreaList();
|
|
loadAreaTableList(0);
|
|
|
|
periodicTimer = Timer.periodic(const Duration(seconds: 30), (timer) {
|
|
loadAreaTableList(0);
|
|
});
|
|
}
|
|
|
|
@override
|
|
void dispose() {
|
|
pageController.dispose();
|
|
bookingNumController.dispose();
|
|
bookingPhoneController.dispose();
|
|
bookingNameController.dispose();
|
|
bookingTypeController.dispose();
|
|
bookingTableNumController.dispose();
|
|
bookingStandardController.dispose();
|
|
bookingRemarkController.dispose();
|
|
periodicTimer?.cancel();
|
|
super.dispose();
|
|
}
|
|
|
|
reloadPageData() {
|
|
loadCallLog();
|
|
loadTableAreaList();
|
|
loadAreaTableList(0);
|
|
loadReserveSms();
|
|
}
|
|
|
|
void testCallIncoming() {
|
|
CallStatusChangeModel model = CallStatusChangeModel(
|
|
state: "Incoming",
|
|
number: "123456789",
|
|
name: "测试",
|
|
region: "陕西省 西安市",
|
|
);
|
|
|
|
EventManager.postEvent(CallStatusChangeEvent(model: model));
|
|
}
|
|
|
|
void loadCallLog() {
|
|
ChannelManager.getCallLog("getCallLog");
|
|
}
|
|
|
|
void loadUserReserveLog() async {
|
|
List<String> phoneNos = [];
|
|
for (var item in callLogs!) {
|
|
phoneNos.add(item!.number ?? '');
|
|
}
|
|
_reserveLogMap = await ReserveModel.getUserReserveLog(phoneNos);
|
|
|
|
notifyListeners();
|
|
}
|
|
|
|
void loadTableAreaList() async {
|
|
final r = await ReserveModel.getShopTableAreaList();
|
|
|
|
_tableAreaList = r;
|
|
|
|
_tableAreaList ??= [];
|
|
|
|
_tableAreaMap = {};
|
|
for (var item in _tableAreaList!) {
|
|
_tableAreaMap[item!.id!] = item;
|
|
}
|
|
|
|
_tableAreaList!.insert(0, TableAreaModel(id: 0, name: "全部"));
|
|
|
|
notifyListeners();
|
|
}
|
|
|
|
void loadAreaTableList(int areaId) async {
|
|
final r =
|
|
await ReserveModel.getAreaTableList(areaId, selectedDate, bookingType);
|
|
|
|
_tableList = r;
|
|
|
|
_tableList ??= [];
|
|
|
|
tableMap = {};
|
|
tableMap["0"] = _tableList!;
|
|
for (var item in _tableList!) {
|
|
String areaId = item!.areaId.toString();
|
|
if (tableMap[areaId] == null) {
|
|
tableMap[areaId] = [];
|
|
}
|
|
tableMap[areaId]!.add(item);
|
|
}
|
|
|
|
notifyListeners();
|
|
}
|
|
|
|
loadReserveSms() async {
|
|
AppManager.loadReserveSms();
|
|
}
|
|
|
|
void commitReserveInfo({bool sendSms = false}) async {
|
|
if (!_checkReserveInfo()) {
|
|
return;
|
|
}
|
|
|
|
Map<String, dynamic> params = {
|
|
"shopTableId": selectedTable!.id,
|
|
"bookingDate": selectedDate,
|
|
"bookingType": bookingType,
|
|
"dinerNum": bookingNumController.text,
|
|
"phoneNumber": bookingPhoneController.text,
|
|
"bookingPerson": bookingNameController.text,
|
|
"gender": bookingGender,
|
|
"bookingTime": '$selectedDate $bookingSelectedTime:00',
|
|
"diningType": bookingTypeController.text,
|
|
"focus": bookingFocus ? 1 : 0,
|
|
"receiveMarketingSms": bookingSms ? 1 : 0,
|
|
"bookingTableNum": bookingTableNumController.text,
|
|
"diningStandardPrice": bookingStandardController.text,
|
|
"diningStandardUnit": bookingStandardType,
|
|
"remark": bookingRemarkController.text,
|
|
};
|
|
|
|
await ReserveModel.commitReserveInfo(params);
|
|
|
|
Utils.toast("预定成功", context);
|
|
hideReserveInfoView();
|
|
loadAreaTableList(0);
|
|
|
|
if (sendSms) {
|
|
String smsContent = await AppManager.loadReserveSms();
|
|
if (smsContent.isNotEmpty) {
|
|
yjPrint("send sms: $smsContent, phone: ${bookingPhoneController.text}");
|
|
|
|
goSendSms(phone: bookingPhoneController.text, message: smsContent);
|
|
}
|
|
}
|
|
}
|
|
|
|
goSendSms({required String phone, required String message}) async {
|
|
final Uri smsUri = Uri(
|
|
scheme: 'sms',
|
|
path: phone,
|
|
queryParameters: {
|
|
'body': message,
|
|
},
|
|
);
|
|
if (await canLaunchUrl(smsUri)) {
|
|
await launchUrl(smsUri);
|
|
} else {
|
|
// 如果无法启动短信发送,可在此处添加相应的提示逻辑,比如打印错误信息等
|
|
yjPrint('Could not launch SMS');
|
|
}
|
|
}
|
|
|
|
void setSelectedDateIndex(int index) {
|
|
selectedDateIndex = index;
|
|
|
|
DateTime offsetDay = now.add(Duration(days: index ~/ 2));
|
|
selectedDate = "${offsetDay.year}-${offsetDay.month}-${offsetDay.day}";
|
|
bookingType = index % 2 == 0 ? "lunch" : "dinner";
|
|
|
|
notifyListeners();
|
|
|
|
loadAreaTableList(0);
|
|
}
|
|
|
|
void setAnimationController(
|
|
AnimationController controller, Animation<double> sizeFactor) {
|
|
_animationController = controller;
|
|
_animationSizeFactor = sizeFactor;
|
|
}
|
|
|
|
ReserveLogModel? getReserveLogModel(String phone) {
|
|
return _reserveLogMap?[phone];
|
|
}
|
|
|
|
showReserveInfoView() {
|
|
_resetReserveData();
|
|
_isShowReserveInfoView = true;
|
|
_animationController?.forward();
|
|
notifyListeners();
|
|
}
|
|
|
|
hideReserveInfoView() {
|
|
_isShowReserveInfoView = false;
|
|
_animationController?.reverse();
|
|
}
|
|
|
|
execCallLog(CallLogModel? callLog) {
|
|
showReserveInfoView();
|
|
bookingPhoneController.text = callLog?.number ?? "";
|
|
bookingNameController.text = callLog?.name ?? "";
|
|
notifyListeners();
|
|
}
|
|
|
|
updateBookingTime(int hour, int minute) {
|
|
bookingSelectedTime =
|
|
"${hour.toString().padLeft(2, '0')}:${minute.toString().padLeft(2, '0')}";
|
|
notifyListeners();
|
|
}
|
|
|
|
updateBookingGender(int gender) {
|
|
if (bookingGender == gender) {
|
|
return;
|
|
}
|
|
bookingGender = gender;
|
|
notifyListeners();
|
|
}
|
|
|
|
updateBookingAttr(String key, bool val) {
|
|
if (key == "focus") {
|
|
bookingFocus = val;
|
|
} else if (key == "sms") {
|
|
bookingSms = val;
|
|
}
|
|
notifyListeners();
|
|
}
|
|
|
|
updateBookingStandard(String standard) {
|
|
bookingStandardType = standard;
|
|
notifyListeners();
|
|
}
|
|
|
|
clickTable(TableModel table) {
|
|
if (_isShowReserveInfoView) {
|
|
if (table.bookingInfo != null) {
|
|
Utils.toast("当前台桌已预定", context);
|
|
return;
|
|
}
|
|
selectedTable = table;
|
|
TableAreaModel? area = _tableAreaMap[table.areaId!];
|
|
showTableName = "${area?.name ?? ""} - ${table.name}";
|
|
notifyListeners();
|
|
|
|
return;
|
|
}
|
|
|
|
if (table.bookingInfo == null) {
|
|
return;
|
|
}
|
|
|
|
_changeReserveStatus(table);
|
|
}
|
|
|
|
_resetReserveData() {
|
|
bookingGender = 1;
|
|
bookingNumController.text = "";
|
|
bookingPhoneController.text = "";
|
|
bookingNameController.text = "";
|
|
bookingTypeController.text = "";
|
|
bookingTableNumController.text = "";
|
|
bookingStandardController.text = "";
|
|
bookingRemarkController.text = "";
|
|
bookingSelectedTime = "";
|
|
bookingFocus = false;
|
|
bookingSms = false;
|
|
bookingStandardType = "table";
|
|
selectedTable = null;
|
|
showTableName = "";
|
|
}
|
|
|
|
_changeReserveStatus(TableModel table) async {
|
|
var result = await showCupertinoModalPopup(
|
|
context: context!,
|
|
builder: (context) {
|
|
return CupertinoActionSheet(
|
|
title: const Text('预定信息'),
|
|
actions: <Widget>[
|
|
CupertinoActionSheetAction(
|
|
onPressed: () {
|
|
Navigator.of(context).pop('arrive');
|
|
},
|
|
isDefaultAction: true,
|
|
child: const Text('到店'),
|
|
),
|
|
CupertinoActionSheetAction(
|
|
child: const Text('取消预定'),
|
|
onPressed: () {
|
|
Navigator.of(context).pop('cancelBooking');
|
|
},
|
|
// isDestructiveAction: true,
|
|
),
|
|
],
|
|
cancelButton: CupertinoActionSheetAction(
|
|
child: const Text('取消'),
|
|
onPressed: () {
|
|
Navigator.of(context).pop('cancel');
|
|
},
|
|
),
|
|
);
|
|
});
|
|
yjPrint('$result');
|
|
|
|
if (result == 'arrive') {
|
|
await ReserveModel.updateReserveStatus(table.bookingInfo?.id ?? 0, 10);
|
|
Utils.toast("到店成功", context);
|
|
loadAreaTableList(0);
|
|
} else if (result == 'cancelBooking') {
|
|
ReserveModel.updateReserveStatus(table.bookingInfo?.id ?? 0, -1);
|
|
Utils.toast("取消成功", context);
|
|
loadAreaTableList(0);
|
|
}
|
|
}
|
|
|
|
bool _checkReserveInfo() {
|
|
if (selectedTable == null) {
|
|
Utils.toast("请选择台桌", context);
|
|
return false;
|
|
}
|
|
|
|
if (bookingNumController.text.isEmpty) {
|
|
Utils.toast("请输入就餐人数", context);
|
|
return false;
|
|
}
|
|
|
|
if (bookingPhoneController.text.isEmpty) {
|
|
Utils.toast("请输入联系电话", context);
|
|
return false;
|
|
}
|
|
|
|
if (bookingNameController.text.isEmpty) {
|
|
Utils.toast("请输入预订人姓名", context);
|
|
return false;
|
|
}
|
|
|
|
if (bookingSelectedTime.isEmpty) {
|
|
Utils.toast("请选择预订时间", context);
|
|
return false;
|
|
}
|
|
|
|
if (bookingTypeController.text.isEmpty) {
|
|
Utils.toast("请输入预订类型", context);
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
String getCurrentDate() {
|
|
return "${now.year}/${now.month}/${now.day}";
|
|
}
|
|
|
|
String getOffsetDay(int offset) {
|
|
DateTime offsetDay = now.add(Duration(days: offset));
|
|
return "${dayInfoMap[offset]}/${offsetDay.day}";
|
|
}
|
|
|
|
String getOffsetWeekday(int offset) {
|
|
DateTime offsetDay = now.add(Duration(days: offset));
|
|
return weekdayMap[offsetDay.weekday] ?? "";
|
|
}
|
|
}
|