From 04720c2ef1152aad7a84bdb670392cafe8224623 Mon Sep 17 00:00:00 2001 From: GYJ <1157756119@qq.com> Date: Tue, 26 Nov 2024 13:44:06 +0800 Subject: [PATCH] =?UTF-8?q?=E5=8F=B0=E6=A1=8C=E5=88=97=E8=A1=A8=E9=A1=B5?= =?UTF-8?q?=E9=9D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- devtools_options.yaml | 4 + lib/common/manager/app_manager.dart | 2 +- lib/common/request/request_manager.dart | 30 +- .../login/login_result.dart | 0 .../reserve/table_area_model.dart | 0 lib/data_model/reserve/table_model.dart | 547 ++++++++++++++++++ lib/home/reserve_right_content_view.dart | 52 +- lib/home/reserve_right_table_list.dart | 162 ++++++ lib/home/reserve_view.dart | 78 ++- lib/home/reserve_view_model.dart | 64 +- lib/model/login_model.dart | 2 +- lib/model/reserve_model.dart | 23 +- 12 files changed, 921 insertions(+), 43 deletions(-) create mode 100644 devtools_options.yaml rename lib/{datas => data_model}/login/login_result.dart (100%) rename lib/{datas => data_model}/reserve/table_area_model.dart (100%) create mode 100644 lib/data_model/reserve/table_model.dart create mode 100644 lib/home/reserve_right_table_list.dart diff --git a/devtools_options.yaml b/devtools_options.yaml new file mode 100644 index 0000000..2bc8e05 --- /dev/null +++ b/devtools_options.yaml @@ -0,0 +1,4 @@ +description: This file stores settings for Dart & Flutter DevTools. +documentation: https://docs.flutter.dev/tools/devtools/extensions#configure-extension-enablement-states +extensions: + - provider: true \ No newline at end of file diff --git a/lib/common/manager/app_manager.dart b/lib/common/manager/app_manager.dart index 377186d..f65a4b1 100644 --- a/lib/common/manager/app_manager.dart +++ b/lib/common/manager/app_manager.dart @@ -1,5 +1,5 @@ import 'package:cashier_reserve/common/push/push.dart'; -import 'package:cashier_reserve/datas/login/login_result.dart'; +import 'package:cashier_reserve/data_model/login/login_result.dart'; import 'package:cashier_reserve/login/login_view.dart'; import '../base/ui.dart'; diff --git a/lib/common/request/request_manager.dart b/lib/common/request/request_manager.dart index 2ed63b7..76cbe6b 100644 --- a/lib/common/request/request_manager.dart +++ b/lib/common/request/request_manager.dart @@ -1,3 +1,5 @@ +import 'dart:convert'; + import 'package:cashier_reserve/common/manager/app_manager.dart'; import 'package:cashier_reserve/common/manager/hive_manager.dart'; import 'package:cashier_reserve/common/print/print.dart'; @@ -10,22 +12,30 @@ const String kBaseUrl = 'https://admintestpapi.sxczgkj.cn'; const kSuccessCode = 200; const kNeedLoginCode = 401; -class RequestManager { +const Map _emptyMap = {}; +class RequestManager { /// HttpClient static final Dio _c = Dio(BaseOptions( - baseUrl: kBaseUrl, + baseUrl: kBaseUrl, connectTimeout: const Duration(milliseconds: 5000), - receiveTimeout: const Duration(milliseconds: 5000) - )); + receiveTimeout: const Duration(milliseconds: 5000))); /// GET - static Future get(String url, {bool catchError = true}) { + static Future get(String url, + {Map params = _emptyMap, bool catchError = true}) { if (url.contains("?")) { url += "&shopId=${HiveManager.getShopId()}"; } else { url += "?shopId=${HiveManager.getShopId()}"; } + + // 处理传入的其他参数 + if (params.isNotEmpty) { + String paramString = Uri(queryParameters: params).query; + url += "&$paramString"; + } + return _doRequest("GET", url, catchError: catchError); } @@ -63,11 +73,11 @@ class RequestManager { try { final resp = await _c.request(url, data: body, - options: Options( - method: method, - headers: {"authorization": "Bearer ${AppManager.getUserToken()}"} - )); + options: Options(method: method, headers: { + "authorization": "Bearer ${AppManager.getUserToken()}" + })); yjPrint("[RequestManager resp]: $method 【$url】body === $resp"); + if (catchError) { if (resp.statusCode == kNeedLoginCode) { AppManager.gotoLogin(); @@ -100,4 +110,4 @@ class RequestManager { static _alertError(String title, String errorText) { Utils.alert(AppManager.globalContext!, errorText, title: title); } -} \ No newline at end of file +} diff --git a/lib/datas/login/login_result.dart b/lib/data_model/login/login_result.dart similarity index 100% rename from lib/datas/login/login_result.dart rename to lib/data_model/login/login_result.dart diff --git a/lib/datas/reserve/table_area_model.dart b/lib/data_model/reserve/table_area_model.dart similarity index 100% rename from lib/datas/reserve/table_area_model.dart rename to lib/data_model/reserve/table_area_model.dart diff --git a/lib/data_model/reserve/table_model.dart b/lib/data_model/reserve/table_model.dart new file mode 100644 index 0000000..17015f9 --- /dev/null +++ b/lib/data_model/reserve/table_model.dart @@ -0,0 +1,547 @@ +import 'dart:convert'; + +/// amount : 0.00 +/// areaId : 20 +/// autoClear : 0 +/// bookingInfo : {"arrivedTime":null,"bookingDate":"2024-11-22","bookingPerson":"王","bookingTableNum":0,"bookingTime":"2024-11-22 18:30:00","bookingType":"dinner","createTime":"2024-11-22 16:16:17","createUserName":"双屿pirse(测77)","delFlag":0,"dinerNum":6,"diningStandardPrice":0.00,"diningStandardUnit":"table","diningType":"普通用餐","focus":1,"gender":1,"id":1,"orderNo":"BK241122161617-cwba","phoneNumber":"13011223344","receiveMarketingSms":1,"remark":"今个高兴,和哥几个一醉方休","shopId":11,"shopTableId":151,"status":20,"timeoutMinute":60,"updateTime":"2024-11-22 16:27:47"} +/// createdAt : 1726283309239 +/// endTime : "2024-11-06 18:03:33" +/// id : 151 +/// isPredate : 1 +/// maxCapacity : 4 +/// name : "A1" +/// perhour : null +/// predateAmount : 0.00 +/// productNum : 6 +/// qrcode : "3000101848" +/// realAmount : 33.70 +/// shopId : 11 +/// sort : 0 +/// status : "using" +/// totalAmount : 33.70 +/// type : 0 +/// updatedAt : 1728720069117 +/// useNum : 1 +/// useTime : "2024-11-22 16:28:59" +/// view : null + +TableModel tableModelFromJson(String str) => + TableModel.fromJson(json.decode(str)); + +String tableModelToJson(TableModel data) => json.encode(data.toJson()); + +class TableModel { + TableModel({ + num? amount, + num? areaId, + num? autoClear, + BookingInfo? bookingInfo, + num? createdAt, + String? endTime, + num? id, + num? isPredate, + num? maxCapacity, + String? name, + dynamic perhour, + num? predateAmount, + num? productNum, + String? qrcode, + num? realAmount, + num? shopId, + num? sort, + String? status, + num? totalAmount, + num? type, + num? updatedAt, + num? useNum, + String? useTime, + dynamic view, + }) { + _amount = amount; + _areaId = areaId; + _autoClear = autoClear; + _bookingInfo = bookingInfo; + _createdAt = createdAt; + _endTime = endTime; + _id = id; + _isPredate = isPredate; + _maxCapacity = maxCapacity; + _name = name; + _perhour = perhour; + _predateAmount = predateAmount; + _productNum = productNum; + _qrcode = qrcode; + _realAmount = realAmount; + _shopId = shopId; + _sort = sort; + _status = status; + _totalAmount = totalAmount; + _type = type; + _updatedAt = updatedAt; + _useNum = useNum; + _useTime = useTime; + _view = view; + } + + TableModel.fromJson(dynamic json) { + _amount = json['amount']; + _areaId = json['areaId']; + _autoClear = json['autoClear']; + _bookingInfo = json['bookingInfo'] != null + ? BookingInfo.fromJson(json['bookingInfo']) + : null; + _createdAt = json['createdAt']; + _endTime = json['endTime']; + _id = json['id']; + _isPredate = json['isPredate']; + _maxCapacity = json['maxCapacity']; + _name = json['name']; + _perhour = json['perhour']; + _predateAmount = json['predateAmount']; + _productNum = json['productNum']; + _qrcode = json['qrcode']; + _realAmount = json['realAmount']; + _shopId = json['shopId']; + _sort = json['sort']; + _status = json['status']; + _totalAmount = json['totalAmount']; + _type = json['type']; + _updatedAt = json['updatedAt']; + _useNum = json['useNum']; + _useTime = json['useTime']; + _view = json['view']; + } + + num? _amount; + num? _areaId; + num? _autoClear; + BookingInfo? _bookingInfo; + num? _createdAt; + String? _endTime; + num? _id; + num? _isPredate; + num? _maxCapacity; + String? _name; + dynamic _perhour; + num? _predateAmount; + num? _productNum; + String? _qrcode; + num? _realAmount; + num? _shopId; + num? _sort; + String? _status; + num? _totalAmount; + num? _type; + num? _updatedAt; + num? _useNum; + String? _useTime; + dynamic _view; + + TableModel copyWith({ + num? amount, + num? areaId, + num? autoClear, + BookingInfo? bookingInfo, + num? createdAt, + String? endTime, + num? id, + num? isPredate, + num? maxCapacity, + String? name, + dynamic perhour, + num? predateAmount, + num? productNum, + String? qrcode, + num? realAmount, + num? shopId, + num? sort, + String? status, + num? totalAmount, + num? type, + num? updatedAt, + num? useNum, + String? useTime, + dynamic view, + }) => + TableModel( + amount: amount ?? _amount, + areaId: areaId ?? _areaId, + autoClear: autoClear ?? _autoClear, + bookingInfo: bookingInfo ?? _bookingInfo, + createdAt: createdAt ?? _createdAt, + endTime: endTime ?? _endTime, + id: id ?? _id, + isPredate: isPredate ?? _isPredate, + maxCapacity: maxCapacity ?? _maxCapacity, + name: name ?? _name, + perhour: perhour ?? _perhour, + predateAmount: predateAmount ?? _predateAmount, + productNum: productNum ?? _productNum, + qrcode: qrcode ?? _qrcode, + realAmount: realAmount ?? _realAmount, + shopId: shopId ?? _shopId, + sort: sort ?? _sort, + status: status ?? _status, + totalAmount: totalAmount ?? _totalAmount, + type: type ?? _type, + updatedAt: updatedAt ?? _updatedAt, + useNum: useNum ?? _useNum, + useTime: useTime ?? _useTime, + view: view ?? _view, + ); + + num? get amount => _amount; + + num? get areaId => _areaId; + + num? get autoClear => _autoClear; + + BookingInfo? get bookingInfo => _bookingInfo; + + num? get createdAt => _createdAt; + + String? get endTime => _endTime; + + num? get id => _id; + + num? get isPredate => _isPredate; + + num? get maxCapacity => _maxCapacity; + + String? get name => _name; + + dynamic get perhour => _perhour; + + num? get predateAmount => _predateAmount; + + num? get productNum => _productNum; + + String? get qrcode => _qrcode; + + num? get realAmount => _realAmount; + + num? get shopId => _shopId; + + num? get sort => _sort; + + String? get status => _status; + + num? get totalAmount => _totalAmount; + + num? get type => _type; + + num? get updatedAt => _updatedAt; + + num? get useNum => _useNum; + + String? get useTime => _useTime; + + dynamic get view => _view; + + Map toJson() { + final map = {}; + map['amount'] = _amount; + map['areaId'] = _areaId; + map['autoClear'] = _autoClear; + if (_bookingInfo != null) { + map['bookingInfo'] = _bookingInfo?.toJson(); + } + map['createdAt'] = _createdAt; + map['endTime'] = _endTime; + map['id'] = _id; + map['isPredate'] = _isPredate; + map['maxCapacity'] = _maxCapacity; + map['name'] = _name; + map['perhour'] = _perhour; + map['predateAmount'] = _predateAmount; + map['productNum'] = _productNum; + map['qrcode'] = _qrcode; + map['realAmount'] = _realAmount; + map['shopId'] = _shopId; + map['sort'] = _sort; + map['status'] = _status; + map['totalAmount'] = _totalAmount; + map['type'] = _type; + map['updatedAt'] = _updatedAt; + map['useNum'] = _useNum; + map['useTime'] = _useTime; + map['view'] = _view; + return map; + } +} + +/// arrivedTime : null +/// bookingDate : "2024-11-22" +/// bookingPerson : "王" +/// bookingTableNum : 0 +/// bookingTime : "2024-11-22 18:30:00" +/// bookingType : "dinner" +/// createTime : "2024-11-22 16:16:17" +/// createUserName : "双屿pirse(测77)" +/// delFlag : 0 +/// dinerNum : 6 +/// diningStandardPrice : 0.00 +/// diningStandardUnit : "table" +/// diningType : "普通用餐" +/// focus : 1 +/// gender : 1 +/// id : 1 +/// orderNo : "BK241122161617-cwba" +/// phoneNumber : "13011223344" +/// receiveMarketingSms : 1 +/// remark : "今个高兴,和哥几个一醉方休" +/// shopId : 11 +/// shopTableId : 151 +/// status : 20 +/// timeoutMinute : 60 +/// updateTime : "2024-11-22 16:27:47" + +BookingInfo bookingInfoFromJson(String str) => + BookingInfo.fromJson(json.decode(str)); + +String bookingInfoToJson(BookingInfo data) => json.encode(data.toJson()); + +class BookingInfo { + BookingInfo({ + dynamic arrivedTime, + String? bookingDate, + String? bookingPerson, + num? bookingTableNum, + String? bookingTime, + String? bookingType, + String? createTime, + String? createUserName, + num? delFlag, + num? dinerNum, + num? diningStandardPrice, + String? diningStandardUnit, + String? diningType, + num? focus, + num? gender, + num? id, + String? orderNo, + String? phoneNumber, + num? receiveMarketingSms, + String? remark, + num? shopId, + num? shopTableId, + num? status, + num? timeoutMinute, + String? updateTime, + }) { + _arrivedTime = arrivedTime; + _bookingDate = bookingDate; + _bookingPerson = bookingPerson; + _bookingTableNum = bookingTableNum; + _bookingTime = bookingTime; + _bookingType = bookingType; + _createTime = createTime; + _createUserName = createUserName; + _delFlag = delFlag; + _dinerNum = dinerNum; + _diningStandardPrice = diningStandardPrice; + _diningStandardUnit = diningStandardUnit; + _diningType = diningType; + _focus = focus; + _gender = gender; + _id = id; + _orderNo = orderNo; + _phoneNumber = phoneNumber; + _receiveMarketingSms = receiveMarketingSms; + _remark = remark; + _shopId = shopId; + _shopTableId = shopTableId; + _status = status; + _timeoutMinute = timeoutMinute; + _updateTime = updateTime; + } + + BookingInfo.fromJson(dynamic json) { + _arrivedTime = json['arrivedTime']; + _bookingDate = json['bookingDate']; + _bookingPerson = json['bookingPerson']; + _bookingTableNum = json['bookingTableNum']; + _bookingTime = json['bookingTime']; + _bookingType = json['bookingType']; + _createTime = json['createTime']; + _createUserName = json['createUserName']; + _delFlag = json['delFlag']; + _dinerNum = json['dinerNum']; + _diningStandardPrice = json['diningStandardPrice']; + _diningStandardUnit = json['diningStandardUnit']; + _diningType = json['diningType']; + _focus = json['focus']; + _gender = json['gender']; + _id = json['id']; + _orderNo = json['orderNo']; + _phoneNumber = json['phoneNumber']; + _receiveMarketingSms = json['receiveMarketingSms']; + _remark = json['remark']; + _shopId = json['shopId']; + _shopTableId = json['shopTableId']; + _status = json['status']; + _timeoutMinute = json['timeoutMinute']; + _updateTime = json['updateTime']; + } + + dynamic _arrivedTime; + String? _bookingDate; + String? _bookingPerson; + num? _bookingTableNum; + String? _bookingTime; + String? _bookingType; + String? _createTime; + String? _createUserName; + num? _delFlag; + num? _dinerNum; + num? _diningStandardPrice; + String? _diningStandardUnit; + String? _diningType; + num? _focus; + num? _gender; + num? _id; + String? _orderNo; + String? _phoneNumber; + num? _receiveMarketingSms; + String? _remark; + num? _shopId; + num? _shopTableId; + num? _status; + num? _timeoutMinute; + String? _updateTime; + + BookingInfo copyWith({ + dynamic arrivedTime, + String? bookingDate, + String? bookingPerson, + num? bookingTableNum, + String? bookingTime, + String? bookingType, + String? createTime, + String? createUserName, + num? delFlag, + num? dinerNum, + num? diningStandardPrice, + String? diningStandardUnit, + String? diningType, + num? focus, + num? gender, + num? id, + String? orderNo, + String? phoneNumber, + num? receiveMarketingSms, + String? remark, + num? shopId, + num? shopTableId, + num? status, + num? timeoutMinute, + String? updateTime, + }) => + BookingInfo( + arrivedTime: arrivedTime ?? _arrivedTime, + bookingDate: bookingDate ?? _bookingDate, + bookingPerson: bookingPerson ?? _bookingPerson, + bookingTableNum: bookingTableNum ?? _bookingTableNum, + bookingTime: bookingTime ?? _bookingTime, + bookingType: bookingType ?? _bookingType, + createTime: createTime ?? _createTime, + createUserName: createUserName ?? _createUserName, + delFlag: delFlag ?? _delFlag, + dinerNum: dinerNum ?? _dinerNum, + diningStandardPrice: diningStandardPrice ?? _diningStandardPrice, + diningStandardUnit: diningStandardUnit ?? _diningStandardUnit, + diningType: diningType ?? _diningType, + focus: focus ?? _focus, + gender: gender ?? _gender, + id: id ?? _id, + orderNo: orderNo ?? _orderNo, + phoneNumber: phoneNumber ?? _phoneNumber, + receiveMarketingSms: receiveMarketingSms ?? _receiveMarketingSms, + remark: remark ?? _remark, + shopId: shopId ?? _shopId, + shopTableId: shopTableId ?? _shopTableId, + status: status ?? _status, + timeoutMinute: timeoutMinute ?? _timeoutMinute, + updateTime: updateTime ?? _updateTime, + ); + + dynamic get arrivedTime => _arrivedTime; + + String? get bookingDate => _bookingDate; + + String? get bookingPerson => _bookingPerson; + + num? get bookingTableNum => _bookingTableNum; + + String? get bookingTime => _bookingTime; + + String? get bookingType => _bookingType; + + String? get createTime => _createTime; + + String? get createUserName => _createUserName; + + num? get delFlag => _delFlag; + + num? get dinerNum => _dinerNum; + + num? get diningStandardPrice => _diningStandardPrice; + + String? get diningStandardUnit => _diningStandardUnit; + + String? get diningType => _diningType; + + num? get focus => _focus; + + num? get gender => _gender; + + num? get id => _id; + + String? get orderNo => _orderNo; + + String? get phoneNumber => _phoneNumber; + + num? get receiveMarketingSms => _receiveMarketingSms; + + String? get remark => _remark; + + num? get shopId => _shopId; + + num? get shopTableId => _shopTableId; + + num? get status => _status; + + num? get timeoutMinute => _timeoutMinute; + + String? get updateTime => _updateTime; + + Map toJson() { + final map = {}; + map['arrivedTime'] = _arrivedTime; + map['bookingDate'] = _bookingDate; + map['bookingPerson'] = _bookingPerson; + map['bookingTableNum'] = _bookingTableNum; + map['bookingTime'] = _bookingTime; + map['bookingType'] = _bookingType; + map['createTime'] = _createTime; + map['createUserName'] = _createUserName; + map['delFlag'] = _delFlag; + map['dinerNum'] = _dinerNum; + map['diningStandardPrice'] = _diningStandardPrice; + map['diningStandardUnit'] = _diningStandardUnit; + map['diningType'] = _diningType; + map['focus'] = _focus; + map['gender'] = _gender; + map['id'] = _id; + map['orderNo'] = _orderNo; + map['phoneNumber'] = _phoneNumber; + map['receiveMarketingSms'] = _receiveMarketingSms; + map['remark'] = _remark; + map['shopId'] = _shopId; + map['shopTableId'] = _shopTableId; + map['status'] = _status; + map['timeoutMinute'] = _timeoutMinute; + map['updateTime'] = _updateTime; + return map; + } +} diff --git a/lib/home/reserve_right_content_view.dart b/lib/home/reserve_right_content_view.dart index 500cc71..ba82a2d 100644 --- a/lib/home/reserve_right_content_view.dart +++ b/lib/home/reserve_right_content_view.dart @@ -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 _buildTableList(BuildContext context) { + List list = []; + + for (int i = 0; i < provider.tableAreaList!.length; i++) { + List 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; + } } diff --git a/lib/home/reserve_right_table_list.dart b/lib/home/reserve_right_table_list.dart new file mode 100644 index 0000000..c3038eb --- /dev/null +++ b/lib/home/reserve_right_table_list.dart @@ -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 Function(String areaId); +typedef TableClickFunc = void Function(TableModel table); + +class ReserveRightTableList extends StatelessWidget { + final List 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 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 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 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, + ), + ), + ], + ), + ), + ], + ), + ), + ); + } +} diff --git a/lib/home/reserve_view.dart b/lib/home/reserve_view.dart index d0db580..d859ce9 100644 --- a/lib/home/reserve_view.dart +++ b/lib/home/reserve_view.dart @@ -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)), ), ), ), diff --git a/lib/home/reserve_view_model.dart b/lib/home/reserve_view_model.dart index 13441d7..f306cf1 100644 --- a/lib/home/reserve_view_model.dart +++ b/lib/home/reserve_view_model.dart @@ -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? _tableAreaList; List? get tableAreaList => _tableAreaList; + List? _tableList; + List? get tableList => _tableList; + Map> tableMap = {}; + List? callLogs = []; ReserveViewModel() { + selectedDate = "${now.year}-${now.month}-${now.day}"; + EventManager.addListener(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] ?? ""; } diff --git a/lib/model/login_model.dart b/lib/model/login_model.dart index 93ceb41..5a0fee7 100644 --- a/lib/model/login_model.dart +++ b/lib/model/login_model.dart @@ -1,5 +1,5 @@ import 'package:cashier_reserve/common/request/request_manager.dart'; -import 'package:cashier_reserve/datas/login/login_result.dart'; +import 'package:cashier_reserve/data_model/login/login_result.dart'; /// LoginModel 登录相关请求 class LoginModel { diff --git a/lib/model/reserve_model.dart b/lib/model/reserve_model.dart index 0ffd19a..26024c7 100644 --- a/lib/model/reserve_model.dart +++ b/lib/model/reserve_model.dart @@ -1,5 +1,6 @@ import 'package:cashier_reserve/common/request/request_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'; /// ReserveModel 台桌预定相关请求 class ReserveModel { @@ -15,4 +16,24 @@ class ReserveModel { } return list; } + + /// getAreaTableList 获取区域桌台列表 + static Future> getAreaTableList(num areaId, String date, String type) async { + Map paramData = { + "bookingDate": date, + "bookingType": type, + }; + if (areaId > 0) { + paramData["areaId"] = areaId; + } + final r = await RequestManager.get("/api/booking/shop-table/list", params: paramData); + if (r == null) { + return []; + } + List list = []; + for (var item in r as List) { + list.add(TableModel.fromJson(item)); + } + return list; + } } \ No newline at end of file