feat(programs): Excel 模板下载 + .xlsx 解析导入
- 新增 excel 4.0.6 / path_provider 2.1.5 依赖 - ExcelTemplateService:生成 Programs + Steps 双表模板(保存到应用文档目录) - ExcelImportService:解析 .xlsx 并写入数据库,跳过已存在 code、按 program_code 关联步骤 - programs_page 顶部新增「下载模板」按钮,导入按钮改用 Excel 解析 - 移除被取代的 program_import_service.dart - AppLocalizations 新增 downloadTemplate 键 - 验证:flutter analyze 无新增 issue;flutter build apk --debug 通过
This commit is contained in:
@@ -5,11 +5,13 @@ import 'package:file_picker/file_picker.dart';
|
||||
import 'dart:io';
|
||||
import '../../../core/localization/app_localizations.dart';
|
||||
import '../../../core/theme/app_theme.dart';
|
||||
import '../../../shared/services/toast_service.dart';
|
||||
import '../../../shared/widgets/common_button.dart';
|
||||
import '../models/program.dart';
|
||||
import '../providers/programs_provider.dart';
|
||||
import '../widgets/program_form_dialog.dart';
|
||||
import '../services/program_import_service.dart';
|
||||
import '../services/excel_import_service.dart';
|
||||
import '../services/excel_template_service.dart';
|
||||
|
||||
/// 程序管理页面
|
||||
class ProgramsPage extends ConsumerStatefulWidget {
|
||||
@@ -64,6 +66,14 @@ class _ProgramsPageState extends ConsumerState<ProgramsPage> {
|
||||
onPressed: () => _showAddDialog(context, ref),
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
// 下载模板按钮
|
||||
CommonButton(
|
||||
text: l10n?.downloadTemplate ?? '下载模板',
|
||||
icon: Icons.file_download,
|
||||
type: ButtonType.secondary,
|
||||
onPressed: () => _downloadTemplate(context),
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
// 导入按钮
|
||||
CommonButton(
|
||||
text: l10n?.importProgram ?? '导入',
|
||||
@@ -407,7 +417,7 @@ class _ProgramsPageState extends ConsumerState<ProgramsPage> {
|
||||
// 选择文件
|
||||
final result = await FilePicker.platform.pickFiles(
|
||||
type: FileType.custom,
|
||||
allowedExtensions: ['json'],
|
||||
allowedExtensions: ['xlsx'],
|
||||
allowMultiple: false,
|
||||
);
|
||||
|
||||
@@ -417,38 +427,39 @@ class _ProgramsPageState extends ConsumerState<ProgramsPage> {
|
||||
|
||||
final file = result.files.first;
|
||||
if (file.path == null) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text('无法读取文件'),
|
||||
backgroundColor: AppTheme.errorColor,
|
||||
),
|
||||
);
|
||||
if (!context.mounted) return;
|
||||
ToastService.showError(context, '无法读取文件');
|
||||
return;
|
||||
}
|
||||
|
||||
// 读取文件内容
|
||||
final jsonContent = await File(file.path!).readAsString();
|
||||
|
||||
// 导入程序
|
||||
final importedCount = await ProgramImportService.instance.importFromJson(jsonContent);
|
||||
// 解析并写入数据库
|
||||
final importedCount =
|
||||
await ExcelImportService.instance.importFromExcel(File(file.path!));
|
||||
|
||||
// 刷新程序列表
|
||||
ref.read(programsProvider.notifier).loadPrograms();
|
||||
|
||||
// 显示结果
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text('成功导入 $importedCount 个程序'),
|
||||
backgroundColor: importedCount > 0 ? AppTheme.successColor : AppTheme.warningColor,
|
||||
),
|
||||
);
|
||||
if (!context.mounted) return;
|
||||
if (importedCount > 0) {
|
||||
ToastService.showSuccess(context, '成功导入 $importedCount 个程序');
|
||||
} else {
|
||||
ToastService.showWarning(context, '未导入新程序(编号可能已存在)');
|
||||
}
|
||||
} catch (e) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text('导入失败: ${e.toString()}'),
|
||||
backgroundColor: AppTheme.errorColor,
|
||||
),
|
||||
);
|
||||
if (!context.mounted) return;
|
||||
ToastService.showError(context, '导入失败: ${e.toString()}');
|
||||
}
|
||||
}
|
||||
|
||||
/// 下载 Excel 模板
|
||||
Future<void> _downloadTemplate(BuildContext context) async {
|
||||
try {
|
||||
final file = await ExcelTemplateService.instance.generateTemplate();
|
||||
if (!context.mounted) return;
|
||||
ToastService.showSuccess(context, '模板已保存: ${file.path}');
|
||||
} catch (e) {
|
||||
if (!context.mounted) return;
|
||||
ToastService.showError(context, '生成模板失败: ${e.toString()}');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user