11
This commit is contained in:
1 parent
60d9380a65
commit
fe6d988fa3
46 files changed
+5738
-1013
No files matched your search
@@ -195,35 +195,22 @@ abstract class SyncProductTool {
|
||||
}
|
||||
}
|
||||
|
||||
/// 同步商品
|
||||
/// 按终端业态执行常规商品同步。
|
||||
///
|
||||
/// 食堂常规同步保留今天起连续七天的缓存范围,一次范围请求完成。
|
||||
/// 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 String day = DateUtil.formatDate(
|
||||
date,
|
||||
format: DateFormats.y_mo_d,
|
||||
);
|
||||
final dayDatetime = DateUtil.getDateTime(day);
|
||||
final pa = {
|
||||
"day": day,
|
||||
"hourType": null,
|
||||
"categoryId": null,
|
||||
"merchantId": sysSetting.serviceMerchantId,
|
||||
};
|
||||
final canteenList = await ProductApi.canteenProduct(pa);
|
||||
if (canteenList == null) return;
|
||||
for (var v in canteenList) {
|
||||
v.saleDate = dayDatetime;
|
||||
}
|
||||
// 更新数据
|
||||
await _batchUpdateCaneenProduct(list: canteenList, dayStr: day);
|
||||
}
|
||||
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>();
|
||||
@@ -273,6 +260,128 @@ abstract class SyncProductTool {
|
||||
// 同步食堂商品 spu start
|
||||
// **************************************************************************
|
||||
|
||||
/// 仅同步终端本地时区的当天食堂菜品,并在成功后记录食堂商品同步时间。
|
||||
///
|
||||
/// MQTT 菜品变更和进入点餐页使用此入口,避免刷新当天时额外拉取未来六天。
|
||||
static Future<bool> syncTodayCanteenProduct() async {
|
||||
final today = DateTime.now();
|
||||
final sysSetting = await AppSettingTool.getSysSetting();
|
||||
if (sysSetting.sysType != SysType.CANTEEN) return false;
|
||||
try {
|
||||
final success = await _syncCanteenProductForDay(
|
||||
date: today,
|
||||
merchantId: sysSetting.serviceMerchantId,
|
||||
);
|
||||
if (!success) return false;
|
||||
sysSetting.canteenProductSyncTime = DateTime.now();
|
||||
await AppSettingTool.setSysSetting(sysSetting);
|
||||
return true;
|
||||
} catch (e, stack) {
|
||||
logger.e("|$_tag|同步当天食堂商品信息意外的错误error:|$e|,stack:|$stack|");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// 请求并替换指定自然日的食堂菜品快照。
|
||||
///
|
||||
/// 返回 `false` 表示接口没有有效响应,本地当天旧快照会保留;
|
||||
/// 空数组属于有效响应,会清空当天快照。
|
||||
static Future<bool> _syncCanteenProductForDay({
|
||||
required DateTime date,
|
||||
required String? merchantId,
|
||||
}) async {
|
||||
final day = DateUtil.formatDate(date, format: DateFormats.y_mo_d);
|
||||
final dayDatetime = DateUtil.getDateTime(day);
|
||||
final canteenList = await ProductApi.canteenProduct({
|
||||
"day": day,
|
||||
"hourType": null,
|
||||
"categoryId": null,
|
||||
"merchantId": merchantId,
|
||||
});
|
||||
if (canteenList == null) return false;
|
||||
if (ObjectUtil.isEmptyList(canteenList)) {
|
||||
// 空数组只代表指定日期没有可售菜品,清空当天快照,不影响其他日期。
|
||||
await _batchUpdateCaneenProduct(list: const [], dayStr: day);
|
||||
return true;
|
||||
}
|
||||
for (final product in canteenList) {
|
||||
// 接口按 day 查询,统一覆盖供应日期可防止异常响应把其他日期写进当天同步结果。
|
||||
product.saleDate = dayDatetime;
|
||||
}
|
||||
await _batchUpdateCaneenProduct(list: canteenList, dayStr: day);
|
||||
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;
|
||||
}
|
||||
|
||||
static Future<void> _batchUpdateCaneenProduct({
|
||||
required List<ServiceProduct> list,
|
||||
required String dayStr,
|
||||
|
||||
Reference in new issue
Block a user