Files
biz_xfj_cloud/lib/pages/setting/widgets/setting_sync.dart
T

195 lines
6.2 KiB
Dart

import 'package:common_utils/common_utils.dart';
import 'package:ducafe_ui_core/ducafe_ui_core.dart';
import 'package:flutter/material.dart';
import 'package:forui/forui.dart';
import 'package:get/get.dart';
import 'package:pj_supermarket_cloud/common/index.dart';
import '../controller.dart';
import 'setting_components.dart';
Widget settingSync(BuildContext context) {
final controller = Get.find<SettingController>();
return Obx(() {
final sys = controller.sysSetting.value;
if (sys == null) return const SettingEmpty(message: '暂无同步信息');
final items = <_SyncItem>[
_SyncItem('config', '同步设备信息', sys.syncTime, controller.syncConfig),
_SyncItem('mq', '同步长链接', sys.mqSyncTime, controller.syncMq),
_SyncItem(
'classify',
'同步分类',
sys.sysType == SysType.CANTEEN
? sys.canteenClassifySyncTime
: sys.supermarketClassifySyncTime,
controller.syncClassify,
),
_SyncItem(
'product',
'同步商品',
sys.sysType == SysType.CANTEEN
? sys.canteenProductSyncTime
: sys.supermarketProductSyncTime,
controller.syncProduct,
),
_SyncItem(
'offlineOrder',
'同步离线订单',
sys.offlineOrderSyncTime,
controller.syncOfflineOrder,
icon: FAssets.icons.cloudDownload,
),
];
return Column(
children: [
Expanded(
child: GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
crossAxisSpacing: XfjDesignTokens.cardGap.w,
mainAxisSpacing: XfjDesignTokens.cardGap.h,
childAspectRatio: 3.25,
),
itemCount: items.length,
itemBuilder: (context, index) {
final item = items[index];
return _SyncCard(
item: item,
syncing: controller.syncingKey.value == item.key,
failed: controller.syncFailedKeys.contains(item.key),
enabled: controller.syncingKey.isEmpty,
);
},
),
),
SizedBox(height: XfjDesignTokens.cardGap.h),
const SettingNotice(
text: '网络接口可用不等于业务服务可用。同步失败时会保留本地数据,可在网络恢复后重新执行。',
),
],
);
});
}
class _SyncItem {
const _SyncItem(this.key, this.title, this.time, this.action, {this.icon});
final String key;
final String title;
final DateTime? time;
final Future<void> Function() action;
final SvgAsset? icon;
}
class _SyncCard extends StatelessWidget {
const _SyncCard({
required this.item,
required this.syncing,
required this.failed,
required this.enabled,
});
final _SyncItem item;
final bool syncing;
final bool failed;
final bool enabled;
@override
Widget build(BuildContext context) {
final theme = FTheme.of(context);
final statusColor = failed
? XfjDesignTokens.danger
: syncing
? XfjDesignTokens.primary
: XfjDesignTokens.success;
return Opacity(
opacity: enabled || syncing ? 1 : 0.55,
child: InkWell(
onTap: enabled ? item.action : null,
borderRadius: BorderRadius.circular(XfjDesignTokens.cardRadius),
child: Container(
padding: EdgeInsets.all(20.w),
decoration: BoxDecoration(
color: XfjDesignTokens.surface,
border: Border.all(color: XfjDesignTokens.line),
borderRadius: BorderRadius.circular(XfjDesignTokens.cardRadius),
boxShadow: XfjDesignTokens.surfaceShadow,
),
child: Row(
children: [
Container(
width: 56.w,
height: 56.w,
alignment: Alignment.center,
decoration: BoxDecoration(
color: XfjDesignTokens.primarySoft,
borderRadius: BorderRadius.circular(
XfjDesignTokens.cardRadius,
),
),
child: syncing
? SizedBox(
width: 28.w,
height: 28.w,
child: const CircularProgressIndicator(strokeWidth: 3),
)
: FIcon(
item.icon ?? FAssets.icons.refreshCw,
color: XfjDesignTokens.primary,
size: 30.sp,
),
),
SizedBox(width: 16.w),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
item.title,
style: theme.typography.lg.copyWith(
color: XfjDesignTokens.ink,
fontWeight: FontWeight.w800,
),
),
SizedBox(height: 8.h),
Text(
'最后同步时间:${_formatTime(item.time)}',
style: theme.typography.sm.copyWith(
color: XfjDesignTokens.muted,
),
),
SizedBox(height: 8.h),
Text(
failed
? '同步失败,点击重试'
: syncing
? '同步中...'
: '状态正常',
style: theme.typography.sm.copyWith(
color: statusColor,
fontWeight: FontWeight.w600,
),
),
],
),
),
FIcon(
FAssets.icons.chevronRight,
color: XfjDesignTokens.muted,
size: 22.sp,
),
],
),
),
),
);
}
}
String _formatTime(DateTime? time) {
if (time == null) return '未同步';
return DateUtil.formatDate(time, format: DateFormats.full);
}