fix:设备查询菜品频繁问题

fix:退看流水对账问题
This commit is contained in:
dzc committed 2026-09-02 12:52:54 +08:00
1 parent 917e7b4e83
commit 4d7bc5ed33
12 files changed
+137 -32

No files matched your search

@@ -4,8 +4,11 @@ import 'package:pj_supermarket_cloud/common/index.dart';
/// 定时任务结构化存储入口,隔离调度器与 Floor DAO 的实体转换细节。
abstract final class ScheduledTaskStorageTool {
/// 旧版本商品同步任务的默认 Cron,仅用于识别尚未升级的默认配置。
static const String _legacyProductSyncCron = '0 25 0 * * *';
/// 最早版本商品同步任务的默认 Cron,仅用于识别尚未升级的关闭配置。
static const String _legacyDisabledProductSyncCron = '0 25 0 * * *';
/// 上一版本商品同步任务的默认 Cron,仅用于把未自定义配置升级为每 3 小时。
static const String _legacyFiveMinuteProductSyncCron = '0 */5 * * * *';
/// 当前应用数据库中的任务配置 DAO;数据库由 AppControl 在调度器启动前完成初始化。
static ScheduledTaskDao get _taskDao =>
@@ -89,9 +92,9 @@ abstract final class ScheduledTaskStorageTool {
required bool idleOnly,
}) =>
type == ScheduledTaskType.productSync &&
!enabled &&
cron == _legacyProductSyncCron &&
idleOnly;
idleOnly &&
((!enabled && cron == _legacyDisabledProductSyncCron) ||
(enabled && cron == _legacyFiveMinuteProductSyncCron));
/// 从 scheduled_task 读取有效任务,并转换为调度器使用的配置和最近执行快照。
///
+1 -1
View File
@@ -304,7 +304,7 @@ class SyncCheckTool {
ScheduledTaskConfig(
type: ScheduledTaskType.productSync,
enabled: true,
cron: '0 */5 * * * *',
cron: '0 0 */3 * * *',
idleOnly: true,
),
ScheduledTaskConfig(
+79 -12
View File
@@ -209,22 +209,20 @@ abstract class SyncProductTool {
/// 按终端业态执行常规商品同步。
///
/// 食堂常规同步保留今天起连续七天的缓存范围;MQTT 食堂变更必须改用 [syncTodayCanteenProduct]。
/// 食堂常规同步保留今天起连续七天的缓存范围。
/// MQTT 食堂变更和进入食堂收银页只刷新当天,使用 [syncTodayCanteenProduct]。
static Future<void> syncProduct() async {
final sysSetting = await AppSettingTool.getSysSetting();
final sysType = sysSetting.sysType;
try {
if (sysType == SysType.CANTEEN) {
// 获取从今天开始的所有日期时间
final DateTime now = DateTime.now();
for (int i = 0; i < 7; i++) {
final DateTime date = now.add(Duration(days: i));
final success = await _syncCanteenProductForDay(
date: date,
merchantId: sysSetting.serviceMerchantId,
);
if (!success) return;
}
final startDate = DateTime.now();
final success = await _syncCanteenProductForDateRange(
startDate: startDate,
endDate: startDate.add(const Duration(days: 6)),
merchantId: sysSetting.serviceMerchantId,
);
if (!success) return;
} else if (sysType == SysType.SUPERMARKET) {
// 超市
final app = Get.find<AppControl>();
@@ -275,7 +273,7 @@ abstract class SyncProductTool {
/// 仅同步终端本地时区的当天食堂菜品,并在成功后记录食堂商品同步时间。
///
/// MQTT 菜品变更使用此入口,确保请求和本地替换都不会扩展到未来一周。
/// MQTT 菜品变更和进入食堂收银页使用此入口,避免刷新当天时额外拉取未来六天。
static Future<bool> syncTodayCanteenProduct() async {
final today = DateTime.now();
final sysSetting = await AppSettingTool.getSysSetting();
@@ -329,6 +327,75 @@ abstract class SyncProductTool {
return true;
}
/// 一次请求指定闭区间的食堂菜谱,并按接口返回的供应日期逐日原子替换本地快照。
///
/// 返回 `false` 表示接口无有效响应或任一记录缺少合法供应日期,此时不会修改任何日期的本地数据。
static Future<bool> _syncCanteenProductForDateRange({
required DateTime startDate,
required DateTime endDate,
required String? merchantId,
}) async {
final startDay = DateUtil.formatDate(
startDate,
format: DateFormats.y_mo_d,
);
final endDay = DateUtil.formatDate(
endDate,
format: DateFormats.y_mo_d,
);
final requestMerchantId = int.tryParse(merchantId ?? '');
if (requestMerchantId == null) {
logger.w('|$_tag|范围菜谱同步缺少有效商户 ID,保留本地旧快照');
return false;
}
final canteenList = await ProductApi.canteenProductsByDateRange({
"startDate": startDay,
"endDate": endDay,
"hourType": null,
"categoryId": null,
"merchantId": requestMerchantId,
});
if (canteenList == null) return false;
final productsByDay = <String, List<ServiceProduct>>{};
var currentDate = DateTime.parse(startDay);
final lastDate = DateTime.parse(endDay);
while (!currentDate.isAfter(lastDate)) {
productsByDay[DateUtil.formatDate(
currentDate,
format: DateFormats.y_mo_d,
)] = <ServiceProduct>[];
currentDate = currentDate.add(const Duration(days: 1));
}
for (final product in canteenList) {
final saleDate = product.saleDate;
if (saleDate == null) {
logger.w('|$_tag|范围菜谱响应缺少供应日期,保留本地旧快照:${product.toJson()}');
return false;
}
final saleDay = DateUtil.formatDate(
saleDate,
format: DateFormats.y_mo_d,
);
final dayProducts = productsByDay[saleDay];
if (dayProducts == null) {
logger
.w('|$_tag|范围菜谱响应日期超出请求区间,保留本地旧快照:请求$startDay至$endDay,响应$saleDay');
return false;
}
dayProducts.add(product);
}
for (final entry in productsByDay.entries) {
await _batchUpdateCaneenProduct(
list: entry.value,
dayStr: entry.key,
);
}
return true;
}
// **************************************************************************
// 同步食堂商品 spu start
// **************************************************************************