台桌列表页面

This commit is contained in:
GYJ
2024-11-26 13:44:06 +08:00
parent c93cc46da1
commit 04720c2ef1
12 changed files with 921 additions and 43 deletions

View File

@@ -1,7 +1,10 @@
import 'package:cashier_reserve/common/base/ui.dart';
import 'package:cashier_reserve/common/print/print.dart';
import 'package:cashier_reserve/data_model/reserve/table_area_model.dart';
import 'package:cashier_reserve/home/reserve_view_model.dart';
import 'reserve_right_table_list.dart';
class ReserveRightContentView extends StatelessWidget {
final ReserveViewModel provider;
final TabController? tabController;
@@ -18,6 +21,7 @@ class ReserveRightContentView extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.start,
children: [
_buildTabBar(context),
_buildTableListWidget(context),
],
),
);
@@ -40,8 +44,54 @@ class ReserveRightContentView extends StatelessWidget {
indicatorWeight: 2,
labelPadding: const EdgeInsets.only(left: 10, right: 10),
onTap: (index) {
yjPrint("tab index: $index");
provider.pageController.jumpToPage(index);
},
);
}
Widget _buildTableListWidget(BuildContext context) {
if ((provider.tableAreaList?.length ?? 0) == 0) {
return Container();
}
return Expanded(
child: Container(
padding: const EdgeInsets.only(left: 15, right: 15),
color: const Color(0xFFF5F5F5),
child: PageView(
controller: provider.pageController,
physics: const NeverScrollableScrollPhysics(),
children: _buildTableList(context),
),
),
);
}
List<Widget> _buildTableList(BuildContext context) {
List<Widget> list = [];
for (int i = 0; i < provider.tableAreaList!.length; i++) {
List<TableAreaModel?> areas = [];
if (i == 0) {
/// 排除第一个全部
areas.addAll(provider.tableAreaList!.sublist(1));
} else {
areas.add(provider.tableAreaList![i]);
}
list.add(
ReserveRightTableList(
areas: areas,
getAreaTableListFunc: (areaId) {
return provider.tableMap[areaId] ?? [];
},
tableClickFunc: (table) {
yjPrint("table: ${table.name}");
},
),
);
}
return list;
}
}

View File

@@ -0,0 +1,162 @@
import 'package:cashier_reserve/common/base/ui.dart';
import 'package:cashier_reserve/common/print/print.dart';
import 'package:cashier_reserve/data_model/reserve/table_area_model.dart';
import 'package:cashier_reserve/data_model/reserve/table_model.dart';
typedef GetAreaTableListFunc = List<TableModel?> Function(String areaId);
typedef TableClickFunc = void Function(TableModel table);
class ReserveRightTableList extends StatelessWidget {
final List<TableAreaModel?> areas;
final GetAreaTableListFunc getAreaTableListFunc;
final TableClickFunc? tableClickFunc;
const ReserveRightTableList({
super.key,
required this.areas,
required this.getAreaTableListFunc,
this.tableClickFunc,
});
@override
Widget build(BuildContext context) {
return ListView.builder(
itemBuilder: _buildTableAreaItem, itemCount: areas.length);
}
Widget _buildTableAreaItem(BuildContext context, int index) {
TableAreaModel? area = areas[index];
List<TableModel?> tables = getAreaTableListFunc(area?.id.toString() ?? "");
return Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
_buildTableAreaTitle(context, area, tables),
const SizedBox(height: 5),
_buildTableList(context, tables),
const SizedBox(height: 10),
],
);
}
Widget _buildTableAreaTitle(
BuildContext context, TableAreaModel? area, List<TableModel?> tables) {
return Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Container(
width: 2,
height: 15,
color: Colors.blue,
),
const SizedBox(width: 10),
Text(
"${area?.name ?? ""}${tables.length}",
style: const TextStyle(
fontSize: 15,
fontWeight: FontWeight.bold,
),
),
],
);
}
Widget _buildTableList(BuildContext context, List<TableModel?> tables) {
return Wrap(
children: tables.map((e) => _buildTableItem(context, e)).toList(),
);
}
Widget _buildTableItem(BuildContext context, TableModel? table) {
bool isBooking = table?.bookingInfo != null;
const itemNormalTextStyle = TextStyle(
color: Color(0xff333333),
fontSize: 12,
);
return GestureDetector(
onTap: () {
if (tableClickFunc != null) {
tableClickFunc!(table!);
}
},
child: Container(
width: 103,
height: 129,
margin: const EdgeInsets.fromLTRB(0, 0, 10, 0),
decoration: BoxDecoration(
color: isBooking ? const Color(0xffFFF4DF) : Colors.white,
borderRadius: BorderRadius.circular(5),
),
child: Column(
children: [
Container(
padding: const EdgeInsets.all(10),
child: Column(
children: [
Text(
table?.name ?? "",
style: const TextStyle(
color: Color(0xff333333),
fontSize: 16,
),
),
const SizedBox(height: 3),
if (!isBooking)
Text(
"${table?.maxCapacity ?? ""}",
style: itemNormalTextStyle,
),
if (isBooking)
Text(
"${(table?.bookingInfo?.createUserName?.length ?? 0) > 3 ? '${table?.bookingInfo?.createUserName?.substring(0, 3)}...' : table?.bookingInfo?.createUserName} 订",
style: itemNormalTextStyle,
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
if (isBooking) const SizedBox(height: 3),
if (isBooking)
Text(
"${table?.bookingInfo?.bookingPerson ?? ""}(${table?.bookingInfo?.gender == 1 ? '先生' : '女士'})",
style: itemNormalTextStyle,
),
if (isBooking) const SizedBox(height: 3),
if (isBooking)
Text(
"${table?.bookingInfo?.dinerNum ?? ""}人/(${table?.bookingInfo?.phoneNumber?.substring(7) ?? ""})",
style: itemNormalTextStyle,
),
],
),
),
Expanded(child: Container()),
if (isBooking)
Container(
width: double.infinity,
alignment: Alignment.center,
decoration: const BoxDecoration(
color: Color(0xffF8AD13),
borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(5),
bottomRight: Radius.circular(5),
),
),
child: const Row(
children: [
SizedBox(width: 5),
Text(
"",
style: TextStyle(
color: Colors.white,
fontSize: 11,
),
),
],
),
),
],
),
),
);
}
}

View File

@@ -1,6 +1,5 @@
import 'package:cashier_reserve/common/base/ui.dart';
import 'package:cashier_reserve/common/base/ui_model.dart';
import 'package:cashier_reserve/common/print/print.dart';
import 'package:cashier_reserve/home/reserve_left_content_view.dart';
import 'package:cashier_reserve/home/reserve_right_content_view.dart';
import 'package:cashier_reserve/home/reserve_view_model.dart';
@@ -177,35 +176,44 @@ class ReserveView extends BaseUI with TickerProviderStateMixin {
BuildContext context, ReserveViewModel provider) {
return Row(
children: [
_buildDateSelectItem(context,
day: provider.getOffsetDay(0),
week: provider.getOffsetWeekday(0),
isToday: true),
_buildDateSelectItem(context,
day: provider.getOffsetDay(1), week: provider.getOffsetWeekday(1)),
_buildDateSelectItem(context,
day: provider.getOffsetDay(2), week: provider.getOffsetWeekday(2)),
_buildDateSelectItem(
context,
provider,
),
_buildDateSelectItem(
context,
provider,
offset: 1,
),
_buildDateSelectItem(
context,
provider,
offset: 2,
),
],
);
}
Widget _buildDateSelectItem(
BuildContext context, {
String day = "",
String week = "",
isToday = false,
BuildContext context,
ReserveViewModel provider, {
int offset = 0,
}) {
bool isSelect = provider.selectedDateIndex ~/ 2 == offset;
bool firstBtnSelect = provider.selectedDateIndex == (offset * 2);
bool secondBtnSelect = provider.selectedDateIndex == (offset * 2 + 1);
const double itemHeight = 45;
const double btnWidth = 60;
return Container(
height: itemHeight,
margin: const EdgeInsets.only(left: 15),
padding: const EdgeInsets.fromLTRB(10, 0, 6, 0),
padding: const EdgeInsets.fromLTRB(10, 0, 0, 0),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(5),
border: Border.all(
color:
isToday ? const Color(0xff318AFE) : const Color(0xffafafaf),
isSelect ? const Color(0xff318AFE) : const Color(0xffafafaf),
width: 1),
),
child: Row(
@@ -214,18 +222,18 @@ class ReserveView extends BaseUI with TickerProviderStateMixin {
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
day,
provider.getOffsetDay(offset),
style: TextStyle(
color: isToday
color: isSelect
? const Color(0xff6A8DC6)
: const Color(0xff333333),
fontSize: 13,
),
),
Text(
week,
provider.getOffsetWeekday(offset),
style: TextStyle(
color: isToday
color: isSelect
? const Color(0xff6A8DC6)
: const Color(0xff333333),
fontSize: 13,
@@ -240,13 +248,23 @@ class ReserveView extends BaseUI with TickerProviderStateMixin {
color: const Color(0xffafafaf),
),
InkWell(
onTap: () {},
child: const SizedBox(
onTap: () {
provider.setSelectedDateIndex(offset * 2);
},
child: Container(
decoration: BoxDecoration(
color:
firstBtnSelect ? const Color(0xff318AFE) : Colors.white,
),
width: btnWidth,
child: Center(
child: Text(
"午餐",
style: TextStyle(fontSize: 16, color: Color(0xff333333)),
style: TextStyle(
fontSize: 16,
color: firstBtnSelect
? Colors.white
: const Color(0xff333333)),
),
),
),
@@ -257,13 +275,23 @@ class ReserveView extends BaseUI with TickerProviderStateMixin {
color: const Color(0xffafafaf),
),
InkWell(
onTap: () {},
child: const SizedBox(
onTap: () {
provider.setSelectedDateIndex(offset * 2 + 1);
},
child: Container(
decoration: BoxDecoration(
color:
secondBtnSelect ? const Color(0xff318AFE) : Colors.white,
),
width: btnWidth,
child: Center(
child: Text(
"晚餐",
style: TextStyle(fontSize: 16, color: Color(0xff333333)),
style: TextStyle(
fontSize: 16,
color: secondBtnSelect
? Colors.white
: const Color(0xff333333)),
),
),
),

View File

@@ -3,7 +3,8 @@ import 'package:cashier_reserve/common/base/ui_model.dart';
import 'package:cashier_reserve/common/channel/call_log_model.dart';
import 'package:cashier_reserve/common/channel/channel_manager.dart';
import 'package:cashier_reserve/common/manager/event_manager.dart';
import 'package:cashier_reserve/datas/reserve/table_area_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';
class ReserveViewModel extends BaseUIModel {
@@ -23,12 +24,26 @@ class ReserveViewModel extends BaseUIModel {
2: "",
};
PageController pageController = PageController();
DateTime now = DateTime.now();
int selectedDateIndex = 0;
String selectedDate = "";
String bookingType = "lunch";
List<TableAreaModel?>? _tableAreaList;
List<TableAreaModel?>? get tableAreaList => _tableAreaList;
List<TableModel?>? _tableList;
List<TableModel?>? get tableList => _tableList;
Map<String, List<TableModel?>> tableMap = {};
List<CallLogModel?>? callLogs = [];
ReserveViewModel() {
selectedDate = "${now.year}-${now.month}-${now.day}";
EventManager.addListener<GetCallLogEvent>(this, (event) {
if (event.isSuccess) {
if (!event.isSuccess) {
@@ -41,6 +56,13 @@ class ReserveViewModel extends BaseUIModel {
loadCallLog();
loadTableAreaList();
loadAreaTableList(0);
}
@override
void dispose() {
pageController.dispose();
super.dispose();
}
@@ -52,22 +74,56 @@ class ReserveViewModel extends BaseUIModel {
final r = await ReserveModel.getShopTableAreaList();
_tableAreaList = r;
_tableAreaList ??= [];
_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();
}
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);
}
String getCurrentDate() {
DateTime now = DateTime.now();
return "${now.year}/${now.month}/${now.day}";
}
String getOffsetDay(int offset) {
DateTime now = DateTime.now();
DateTime offsetDay = now.add(Duration(days: offset));
return "${dayInfoMap[offset]}/${offsetDay.day}";
}
String getOffsetWeekday(int offset) {
DateTime now = DateTime.now();
DateTime offsetDay = now.add(Duration(days: offset));
return weekdayMap[offsetDay.weekday] ?? "";
}