195 lines
6.2 KiB
Dart
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);
|
|
}
|