diff --git a/lib/common/services/database/dao/broadcast_dao.dart b/lib/common/services/database/dao/broadcast_dao.dart index e2fba6b..9fd122a 100644 --- a/lib/common/services/database/dao/broadcast_dao.dart +++ b/lib/common/services/database/dao/broadcast_dao.dart @@ -20,4 +20,27 @@ abstract class BroadcastDao { AND strftime('%Y-%m-%d', createTime) = strftime('%Y-%m-%d', 'now', 'localtime') """) Future> getAll(); + + @Query(""" + SELECT * FROM broadcast + WHERE + strftime('%Y-%m-%d', createTime) = strftime('%Y-%m-%d', 'now', 'localtime') + AND (:hourType = '-1' OR hourType = :hourType) + LIMIT :pageSize OFFSET :offset + """) + Future> findAllPage( + String hourType, + int pageSize, + int offset, + ); + + @Query(""" + SELECT COUNT(0) FROM broadcast + WHERE + strftime('%Y-%m-%d', createTime) = strftime('%Y-%m-%d', 'now', 'localtime') + AND (:hourType = '-1' OR hourType = :hourType) + """) + Future count( + String hourType, + ); } diff --git a/lib/common/services/database/database.g.dart b/lib/common/services/database/database.g.dart index f80be69..bf8fe95 100644 --- a/lib/common/services/database/database.g.dart +++ b/lib/common/services/database/database.g.dart @@ -118,7 +118,7 @@ class _$AppDatabase extends AppDatabase { }, onCreate: (database, version) async { await database.execute( - 'CREATE TABLE IF NOT EXISTS `broadcast` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `content` TEXT NOT NULL, `broadcastCount` INTEGER NOT NULL, `broadcastMaxCount` INTEGER NOT NULL, `isBroadcast` INTEGER NOT NULL, `isDone` INTEGER NOT NULL, `isDoneTime` TEXT, `serviceCode` TEXT NOT NULL, `userId` TEXT NOT NULL, `username` TEXT NOT NULL, `userMobile` TEXT NOT NULL, `productDesc` TEXT NOT NULL, `payPrice` INTEGER NOT NULL, `enable` INTEGER NOT NULL, `createTime` TEXT NOT NULL)'); + 'CREATE TABLE IF NOT EXISTS `broadcast` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `content` TEXT NOT NULL, `broadcastCount` INTEGER NOT NULL, `broadcastMaxCount` INTEGER NOT NULL, `isBroadcast` INTEGER NOT NULL, `isDone` INTEGER NOT NULL, `isDoneTime` TEXT, `serviceCode` TEXT NOT NULL, `userId` TEXT NOT NULL, `username` TEXT NOT NULL, `userMobile` TEXT NOT NULL, `productDesc` TEXT NOT NULL, `payPrice` INTEGER NOT NULL, `hourType` INTEGER, `enable` INTEGER NOT NULL, `createTime` TEXT NOT NULL)'); await database.execute( 'CREATE TABLE IF NOT EXISTS `order_record` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `uniqueCode` TEXT NOT NULL, `serviceUniqueCode` TEXT NOT NULL, `sysType` TEXT NOT NULL, `userCode` TEXT NOT NULL, `username` TEXT, `hourType` TEXT, `price` INTEGER NOT NULL, `extraPrice` INTEGER NOT NULL, `payPrice` INTEGER NOT NULL, `walletId` TEXT, `orderSourceTypeId` TEXT, `type` TEXT NOT NULL, `status` TEXT NOT NULL, `payType` TEXT NOT NULL, `productDesc` TEXT, `count` INTEGER NOT NULL, `weight` REAL NOT NULL, `payTime` TEXT, `createTime` TEXT NOT NULL)'); await database.execute( @@ -237,6 +237,7 @@ class _$BroadcastDao extends BroadcastDao { 'userMobile': item.userMobile, 'productDesc': item.productDesc, 'payPrice': item.payPrice, + 'hourType': item.hourType?.index, 'enable': _boolConverter.encode(item.enable), 'createTime': _dateTimeConverter.encode(item.createTime) }); @@ -267,6 +268,26 @@ class _$BroadcastDao extends BroadcastDao { payPrice: row['payPrice'] as int)); } + @override + Future> findAllPage( + String hourType, + int pageSize, + int offset, + ) async { + return _queryAdapter.queryList( + 'SELECT * FROM broadcast WHERE strftime(\'%Y-%m-%d\', createTime) = strftime(\'%Y-%m-%d\', \'now\', \'localtime\') AND (?1 = \'-1\' OR hourType = ?1) LIMIT ?2 OFFSET ?3', + mapper: (Map row) => BroadcastEntity(id: row['id'] as int?, content: row['content'] as String, broadcastMaxCount: row['broadcastMaxCount'] as int, isBroadcast: _boolConverter.decode(row['isBroadcast'] as int), createTime: _dateTimeConverter.decode(row['createTime'] as String), serviceCode: row['serviceCode'] as String, userId: row['userId'] as String, username: row['username'] as String, userMobile: row['userMobile'] as String, productDesc: row['productDesc'] as String, payPrice: row['payPrice'] as int), + arguments: [hourType, pageSize, offset]); + } + + @override + Future count(String hourType) async { + return _queryAdapter.query( + 'SELECT COUNT(0) FROM broadcast WHERE strftime(\'%Y-%m-%d\', createTime) = strftime(\'%Y-%m-%d\', \'now\', \'localtime\') AND (?1 = \'-1\' OR hourType = ?1)', + mapper: (Map row) => row.values.first as int, + arguments: [hourType]); + } + @override Future save(BroadcastEntity entity) async { await _broadcastEntityInsertionAdapter.insert( diff --git a/lib/common/services/database/entity/broadcast_entity.dart b/lib/common/services/database/entity/broadcast_entity.dart index 91c867b..8d35506 100644 --- a/lib/common/services/database/entity/broadcast_entity.dart +++ b/lib/common/services/database/entity/broadcast_entity.dart @@ -1,5 +1,6 @@ import 'package:floor/floor.dart'; import 'package:json_annotation/json_annotation.dart'; +import 'package:pj_supermarket_cloud/common/index.dart'; part 'broadcast_entity.g.dart'; @@ -46,6 +47,9 @@ class BroadcastEntity { /// 支付价格 int payPrice; + /// 菜品时间类型 + ProductHourType? hourType; + /// 手动开关 bool enable = true; diff --git a/lib/common/services/database/entity/broadcast_entity.g.dart b/lib/common/services/database/entity/broadcast_entity.g.dart index b6a4a0b..e0c65a0 100644 --- a/lib/common/services/database/entity/broadcast_entity.g.dart +++ b/lib/common/services/database/entity/broadcast_entity.g.dart @@ -25,6 +25,8 @@ BroadcastEntity _$BroadcastEntityFromJson(Map json) => ..isDoneTime = json['isDoneTime'] == null ? null : DateTime.parse(json['isDoneTime'] as String) + ..hourType = + $enumDecodeNullable(_$ProductHourTypeEnumMap, json['hourType']) ..enable = json['enable'] as bool; Map _$BroadcastEntityToJson(BroadcastEntity instance) => @@ -42,6 +44,14 @@ Map _$BroadcastEntityToJson(BroadcastEntity instance) => 'userMobile': instance.userMobile, 'productDesc': instance.productDesc, 'payPrice': instance.payPrice, + 'hourType': _$ProductHourTypeEnumMap[instance.hourType], 'enable': instance.enable, 'createTime': instance.createTime.toIso8601String(), }; + +const _$ProductHourTypeEnumMap = { + ProductHourType.TOTAL: 'TOTAL', + ProductHourType.MORNING: 'MORNING', + ProductHourType.NOON: 'NOON', + ProductHourType.NIGHT: 'NIGHT', +}; diff --git a/lib/pages/canteen_product/controller.dart b/lib/pages/canteen_product/controller.dart index 341e4b5..430223b 100644 --- a/lib/pages/canteen_product/controller.dart +++ b/lib/pages/canteen_product/controller.dart @@ -68,7 +68,13 @@ class CanteenProductController extends GetxController with OrderMixin { sysType = SysType.CANTEEN; _listenPayTypeSelectCallback(); // 更新分类和商品 - await SyncProductTool.updateDatabase(); + try { + await SyncProductTool.updateDatabase(); + } catch (e) { + Toast.error(msg: "初始化资源失败,请检查网络情况"); + EasyLoading.dismiss(); + Get.offAndToNamed(RouteNames.panel); + } // 获取分类和商品 await getClassify(); await getProduct(); diff --git a/lib/pages/canteen_reserve/controller.dart b/lib/pages/canteen_reserve/controller.dart index 14b1c0b..ac65869 100644 --- a/lib/pages/canteen_reserve/controller.dart +++ b/lib/pages/canteen_reserve/controller.dart @@ -1,17 +1,50 @@ +import 'package:flutter_easyloading/flutter_easyloading.dart'; +import 'package:forui/forui.dart'; import 'package:get/get.dart'; +import 'package:pj_supermarket_cloud/common/index.dart'; + class CanteenReserveController extends GetxController { CanteenReserveController(); + final appC = Get.find(); + + RxList reserveList = [].obs; + + Rx hourType = Rx(ProductHourType.MORNING); + + var hourTypeC = FRadioSelectGroupController( + value: ProductHourType.MORNING.code, + ); + + // table + RxInt currentPage = 1.obs; + + RxInt totalPage = 0.obs; + + RxInt pageSize = 10.obs; + _initData() { update(["canteen_reserve"]); } - void onTap() {} - @override void onInit() { super.onInit(); + hourTypeC.addValueListener((v) async { + final currentHourType = ProductHourType.values.fromCode( + v.first, + ); + if (currentHourType == null) return; + EasyLoading.show( + status: '切换中...', + maskType: EasyLoadingMaskType.black, + ); + hourType.value = currentHourType; + currentPage.value = 1; + await _getReservePage(); + EasyLoading.dismiss(); + }); } @override @@ -24,4 +57,34 @@ class CanteenReserveController extends GetxController { void onClose() { super.onClose(); } + + Future doPage({int? page}) async { + if (page != null) { + currentPage.value = page; + } + await _getReservePage(); + } + + /// 获取预约列表 + Future _getReservePage() async { + final appSetting = await AppSettingTool.getSysSetting(); + final sysType = appSetting.sysType.name; + + final broadcastDao = appC.dataBase.getBroadcastDao; + + /// 处理查询参数 + String hourTypeCode = hourType.value.code; + if (sysType == SysType.SUPERMARKET.name) { + hourTypeCode = "-1"; + } + + final list = await broadcastDao.findAllPage( + hourTypeCode, + pageSize.value, + (currentPage.value - 1) * pageSize.value, + ); + final total = await broadcastDao.count(hourTypeCode); + totalPage.value = total ?? 0; + reserveList.value = list; + } } diff --git a/lib/pages/canteen_reserve/view.dart b/lib/pages/canteen_reserve/view.dart index c32a57f..b91dece 100644 --- a/lib/pages/canteen_reserve/view.dart +++ b/lib/pages/canteen_reserve/view.dart @@ -1,3 +1,5 @@ +import 'package:common_utils/common_utils.dart'; +import 'package:data_table_2/data_table_2.dart'; import 'package:ducafe_ui_core/ducafe_ui_core.dart'; import 'package:flutter/material.dart'; import 'package:forui/forui.dart'; @@ -12,8 +14,149 @@ class CanteenReservePage extends GetView { // 主视图 Widget _buildView(BuildContext context) { - return const Center( - child: Text("CanteenReservePage"), + final height = context.height; + final headerHeight = height * 0.08; + return [ + _buildCondition(context, headerHeight), + SizedBox(height: 20.h), + _buildTable(context).center().expanded(), + Obx( + () => appPage( + context, + pageNo: controller.currentPage.value, + pageSize: controller.pageSize.value, + total: controller.totalPage.value, + onPageChanged: (page) => controller.doPage(page: page), + ), + ) + ].toColumn(); + } + + /// 搜索条件 + Widget _buildCondition(BuildContext context, double headerHeight) { + final theme = FTheme.of(context); + return [ + const Spacer(), + appRadioHourTypeDialog(context, controller.hourTypeC) + .width(300.w) + .marginOnly(right: 15.w), + ].toRowSpace(space: 15.w, mainAxisAlignment: MainAxisAlignment.center); + } + + /// 表格 + Widget _buildTable(BuildContext context) { + final theme = FTheme.of(context); + return LayoutBuilder( + builder: (BuildContext context, BoxConstraints constraints) { + final height = constraints.maxHeight; + final hdHeight = (height - 50.h) / 10.5; + return Obx( + () => DataTable2( + columnSpacing: 12.w, + horizontalMargin: 12.w, + minWidth: 600.w, + showBottomBorder: true, + headingTextStyle: theme.typography.lg, + dataTextStyle: theme.typography.base, + dataRowHeight: hdHeight, + columns: [ + DataColumn2( + label: Text("用户", textAlign: TextAlign.center), + headingRowAlignment: MainAxisAlignment.center, + fixedWidth: 230.w, + ), + DataColumn2( + label: Text("商品", textAlign: TextAlign.center), + headingRowAlignment: MainAxisAlignment.center, + fixedWidth: 230.w, + ), + DataColumn2( + label: Text("价格", textAlign: TextAlign.center), + headingRowAlignment: MainAxisAlignment.center, + fixedWidth: 230.w, + ), + DataColumn2( + label: Text("当前广播次数", textAlign: TextAlign.center), + headingRowAlignment: MainAxisAlignment.center, + fixedWidth: 230.w, + ), + DataColumn2( + label: Text("最大广播次数", textAlign: TextAlign.center), + headingRowAlignment: MainAxisAlignment.center, + fixedWidth: 230.w, + ), + DataColumn2( + label: Text("是否开启广播", textAlign: TextAlign.center), + headingRowAlignment: MainAxisAlignment.center, + fixedWidth: 230.w, + ), + DataColumn2( + label: Text("下单时间", textAlign: TextAlign.center), + headingRowAlignment: MainAxisAlignment.center, + fixedWidth: 230.w, + ), + DataColumn2( + label: Text("操作", textAlign: TextAlign.center), + headingRowAlignment: MainAxisAlignment.center, + fixedWidth: 230.w, + ), + ], + rows: controller.reserveList + .map( + (v) => DataRow( + cells: [ + DataCell( + Text( + "${v.username}-${v.userMobile}", + textAlign: TextAlign.center, + ).center(), + ), + DataCell( + Text( + v.productDesc, + textAlign: TextAlign.center, + ).center(), + ), + DataCell( + appPrice(context, v.payPrice).center(), + ), + DataCell( + Text( + "${v.broadcastCount}", + textAlign: TextAlign.center, + ).center(), + ), + DataCell( + Text( + "${v.broadcastMaxCount}", + textAlign: TextAlign.center, + ).center(), + ), + DataCell( + Text( + v.enable ? "是" : "否", + textAlign: TextAlign.center, + ).center(), + ), + DataCell( + Text( + DateUtil.formatDate(v.createTime), + textAlign: TextAlign.center, + ).center(), + ), + DataCell( + Text( + DateUtil.formatDate(v.createTime), + textAlign: TextAlign.center, + ).center(), + ), + ], + ), + ) + .toList(), + ), + ); + }, ); } @@ -25,7 +168,7 @@ class CanteenReservePage extends GetView { builder: (_) { return FScaffold( header: appDefaultNav(context, title: "预定"), - content: _buildView(context).marginOnly(top: 20.h), + content: _buildView(context), resizeToAvoidBottomInset: false, ); }, diff --git a/lib/pages/setting/widgets/setting_baseInfo.dart b/lib/pages/setting/widgets/setting_baseInfo.dart index e8c9d90..d545b7f 100644 --- a/lib/pages/setting/widgets/setting_baseInfo.dart +++ b/lib/pages/setting/widgets/setting_baseInfo.dart @@ -21,9 +21,9 @@ Future _bindServiceDialog(BuildContext context, SysSetting sys) async { // 正式环境-测试 // uniqueCodeC.text = "1896157295523049473"; // 测试环境-测试设备 - // uniqueCodeC.text = "1877592554489143298"; + uniqueCodeC.text = "1877592554489143298"; // 测试环境-食堂-浦阳 - uniqueCodeC.text = "1914567628657778690"; + // uniqueCodeC.text = "1914567628657778690"; } await showAdaptiveDialog( context: context,