chore(project): 初始化项目基础配置文件
- 添加 CodeGraph、Android 和通用 gitignore 配置 - 创建项目元数据文件跟踪 Flutter 项目属性 - 添加 Codex AI 指导文档 AGENTS.md 说明项目架构 - 配置代码分析选项 analysis_options.yaml - 设置 Android 应用清单权限和 Kiosk 模式配置 - 实现中英文国际化支持 AppLocalizations - 配置 GoRouter 应用路由导航 - 创建明亮工业控制风格的主题配置 AppTheme
This commit is contained in:
126
lib/features/programs/services/program_import_service.dart
Normal file
126
lib/features/programs/services/program_import_service.dart
Normal file
@@ -0,0 +1,126 @@
|
||||
import 'dart:convert';
|
||||
import '../../programs/models/program.dart';
|
||||
import '../../programs/models/step.dart';
|
||||
import '../../programs/services/program_service.dart';
|
||||
|
||||
/// 程序导入服务
|
||||
class ProgramImportService {
|
||||
static final ProgramImportService instance = ProgramImportService._internal();
|
||||
final ProgramService _programService = ProgramService.instance;
|
||||
|
||||
ProgramImportService._internal();
|
||||
|
||||
/// 从 JSON 字符串导入程序
|
||||
/// 返回导入的程序数量
|
||||
Future<int> importFromJson(String jsonContent) async {
|
||||
final data = jsonDecode(jsonContent);
|
||||
|
||||
// 支持单个程序或程序数组
|
||||
final List<dynamic> programsData;
|
||||
if (data is List) {
|
||||
programsData = data;
|
||||
} else if (data is Map && data.containsKey('programs')) {
|
||||
programsData = data['programs'] as List;
|
||||
} else {
|
||||
programsData = [data];
|
||||
}
|
||||
|
||||
int importedCount = 0;
|
||||
|
||||
for (final programData in programsData) {
|
||||
try {
|
||||
// 验证必填字段
|
||||
if (!_validateProgramData(programData)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// 检查编号是否已存在
|
||||
final existingPrograms = await _programService.getAllPrograms();
|
||||
final code = programData['code'] as String;
|
||||
if (existingPrograms.any((p) => p.code == code)) {
|
||||
// 编号已存在,跳过或使用新编号
|
||||
continue;
|
||||
}
|
||||
|
||||
// 创建程序
|
||||
final program = Program(
|
||||
code: code,
|
||||
name: programData['name'] as String,
|
||||
createdAt: programData['createdAt'] ?? DateTime.now().toString().split('.')[0],
|
||||
status: programData['status'] ?? 1,
|
||||
);
|
||||
|
||||
final programId = await _programService.addProgram(program);
|
||||
|
||||
// 导入步骤
|
||||
final stepsData = programData['steps'] as List?;
|
||||
if (stepsData != null) {
|
||||
for (int i = 0; i < stepsData.length; i++) {
|
||||
final stepData = stepsData[i];
|
||||
final step = Step(
|
||||
programId: programId,
|
||||
stepNo: i + 1,
|
||||
position: stepData['position'] as String? ?? 'A1',
|
||||
name: stepData['name'] as String? ?? '步骤${i + 1}',
|
||||
mixTime: stepData['mixTime'] as int? ?? 0,
|
||||
magnetTime: stepData['magnetTime'] as int? ?? 0,
|
||||
volume: stepData['volume'] as int? ?? 0,
|
||||
mixSpeed: stepData['mixSpeed'] as String? ?? '中速',
|
||||
blowSpeed: stepData['blowSpeed'] as String? ?? '中速',
|
||||
blowTime: stepData['blowTime'] as int? ?? 0,
|
||||
needleSpeed: stepData['needleSpeed'] as int? ?? 5,
|
||||
);
|
||||
await _programService.addStep(step);
|
||||
}
|
||||
}
|
||||
|
||||
importedCount++;
|
||||
} catch (e) {
|
||||
// 忽略单个程序导入错误
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
return importedCount;
|
||||
}
|
||||
|
||||
/// 验证程序数据
|
||||
bool _validateProgramData(Map<String, dynamic> data) {
|
||||
return data.containsKey('code') &&
|
||||
data.containsKey('name') &&
|
||||
data['code'] is String &&
|
||||
data['name'] is String;
|
||||
}
|
||||
|
||||
/// 导出程序为 JSON
|
||||
Future<String> exportToJson(List<int> programIds) async {
|
||||
final programs = [];
|
||||
|
||||
for (final id in programIds) {
|
||||
final program = await _programService.getProgramById(id);
|
||||
if (program == null) continue;
|
||||
|
||||
final steps = await _programService.getStepsByProgramId(id);
|
||||
|
||||
programs.add({
|
||||
'code': program.code,
|
||||
'name': program.name,
|
||||
'createdAt': program.createdAt,
|
||||
'status': program.status,
|
||||
'steps': steps.map((s) => {
|
||||
'position': s.position,
|
||||
'name': s.name,
|
||||
'mixTime': s.mixTime,
|
||||
'magnetTime': s.magnetTime,
|
||||
'volume': s.volume,
|
||||
'mixSpeed': s.mixSpeed,
|
||||
'blowSpeed': s.blowSpeed,
|
||||
'blowTime': s.blowTime,
|
||||
'needleSpeed': s.needleSpeed,
|
||||
}).toList(),
|
||||
});
|
||||
}
|
||||
|
||||
return jsonEncode({'programs': programs});
|
||||
}
|
||||
}
|
||||
156
lib/features/programs/services/program_service.dart
Normal file
156
lib/features/programs/services/program_service.dart
Normal file
@@ -0,0 +1,156 @@
|
||||
import '../../../core/database/database_service.dart';
|
||||
import '../models/program.dart';
|
||||
import '../models/step.dart';
|
||||
|
||||
/// 程序服务
|
||||
/// 封装程序和步骤的数据库操作
|
||||
class ProgramService {
|
||||
static final ProgramService instance = ProgramService._internal();
|
||||
final DatabaseService _db = DatabaseService.instance;
|
||||
|
||||
ProgramService._internal();
|
||||
|
||||
/// 获取所有程序
|
||||
Future<List<Program>> getAllPrograms() async {
|
||||
final database = await _db.database;
|
||||
final maps = await database.query('programs', orderBy: 'created_at DESC');
|
||||
return maps.map((m) => Program.fromMap(m)).toList();
|
||||
}
|
||||
|
||||
/// 根据ID获取程序
|
||||
Future<Program?> getProgramById(int id) async {
|
||||
final database = await _db.database;
|
||||
final maps = await database.query(
|
||||
'programs',
|
||||
where: 'id = ?',
|
||||
whereArgs: [id],
|
||||
);
|
||||
if (maps.isEmpty) return null;
|
||||
return Program.fromMap(maps.first);
|
||||
}
|
||||
|
||||
/// 新增程序
|
||||
Future<int> addProgram(Program program) async {
|
||||
final database = await _db.database;
|
||||
return await database.insert('programs', program.toMap());
|
||||
}
|
||||
|
||||
/// 更新程序
|
||||
Future<bool> updateProgram(Program program) async {
|
||||
if (program.id == null) return false;
|
||||
final database = await _db.database;
|
||||
final count = await database.update(
|
||||
'programs',
|
||||
program.toMap(),
|
||||
where: 'id = ?',
|
||||
whereArgs: [program.id],
|
||||
);
|
||||
return count > 0;
|
||||
}
|
||||
|
||||
/// 删除程序(含步骤)
|
||||
Future<bool> deleteProgram(int id) async {
|
||||
final database = await _db.database;
|
||||
// 先删除关联的步骤
|
||||
await database.delete('steps', where: 'program_id = ?', whereArgs: [id]);
|
||||
// 再删除程序
|
||||
final count = await database.delete('programs', where: 'id = ?', whereArgs: [id]);
|
||||
return count > 0;
|
||||
}
|
||||
|
||||
/// 批量删除程序
|
||||
Future<bool> deletePrograms(List<int> ids) async {
|
||||
if (ids.isEmpty) return true;
|
||||
final database = await _db.database;
|
||||
// 先删除关联的步骤
|
||||
await database.delete(
|
||||
'steps',
|
||||
where: 'program_id IN (${ids.map((_) => '?').join(',')})',
|
||||
whereArgs: ids,
|
||||
);
|
||||
// 再删除程序
|
||||
final count = await database.delete(
|
||||
'programs',
|
||||
where: 'id IN (${ids.map((_) => '?').join(',')})',
|
||||
whereArgs: ids,
|
||||
);
|
||||
return count > 0;
|
||||
}
|
||||
|
||||
/// 切换程序状态
|
||||
Future<bool> toggleProgramStatus(int id) async {
|
||||
final database = await _db.database;
|
||||
final program = await getProgramById(id);
|
||||
if (program == null) return false;
|
||||
final count = await database.update(
|
||||
'programs',
|
||||
{'status': program.status == 1 ? 0 : 1},
|
||||
where: 'id = ?',
|
||||
whereArgs: [id],
|
||||
);
|
||||
return count > 0;
|
||||
}
|
||||
|
||||
/// 获取程序的步骤列表
|
||||
Future<List<Step>> getStepsByProgramId(int programId) async {
|
||||
final database = await _db.database;
|
||||
final maps = await database.query(
|
||||
'steps',
|
||||
where: 'program_id = ?',
|
||||
whereArgs: [programId],
|
||||
orderBy: 'step_no ASC',
|
||||
);
|
||||
return maps.map((m) => Step.fromMap(m)).toList();
|
||||
}
|
||||
|
||||
/// 新增步骤
|
||||
Future<int> addStep(Step step) async {
|
||||
final database = await _db.database;
|
||||
return await database.insert('steps', step.toMap());
|
||||
}
|
||||
|
||||
/// 更新步骤
|
||||
Future<bool> updateStep(Step step) async {
|
||||
if (step.id == null) return false;
|
||||
final database = await _db.database;
|
||||
final count = await database.update(
|
||||
'steps',
|
||||
step.toMap(),
|
||||
where: 'id = ?',
|
||||
whereArgs: [step.id],
|
||||
);
|
||||
return count > 0;
|
||||
}
|
||||
|
||||
/// 删除步骤
|
||||
Future<bool> deleteStep(int id) async {
|
||||
final database = await _db.database;
|
||||
final count = await database.delete('steps', where: 'id = ?', whereArgs: [id]);
|
||||
return count > 0;
|
||||
}
|
||||
|
||||
/// 批量删除步骤
|
||||
Future<bool> deleteSteps(List<int> ids) async {
|
||||
if (ids.isEmpty) return true;
|
||||
final database = await _db.database;
|
||||
final count = await database.delete(
|
||||
'steps',
|
||||
where: 'id IN (${ids.map((_) => '?').join(',')})',
|
||||
whereArgs: ids,
|
||||
);
|
||||
return count > 0;
|
||||
}
|
||||
|
||||
/// 更新步骤排序
|
||||
Future<void> reorderSteps(int programId, List<int> stepIds) async {
|
||||
final database = await _db.database;
|
||||
for (int i = 0; i < stepIds.length; i++) {
|
||||
await database.update(
|
||||
'steps',
|
||||
{'step_no': i + 1},
|
||||
where: 'id = ? AND program_id = ?',
|
||||
whereArgs: [stepIds[i], programId],
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user