- 在AndroidManifest.xml中添加USB Host权限和设备过滤器配置 - 新增设备控制国际化词条包括速度档位、吹气时间等 - 重构数据库结构将速度相关字段统一为档位数值存储 - 添加通用KV存储方法用于settings表数据读写 - 优化首页导航实现tab间跳转和状态保持功能 - 更新程序详情页面布局和参数表单界面 - 移除模拟运行器相关测试代码 - 添加USB串口通信依赖包usb_serial
191 lines
5.6 KiB
Dart
191 lines
5.6 KiB
Dart
import 'package:sqflite/sqflite.dart';
|
||
import 'package:path/path.dart';
|
||
|
||
/// 数据库服务
|
||
class DatabaseService {
|
||
static final DatabaseService instance = DatabaseService._internal();
|
||
static Database? _database;
|
||
|
||
DatabaseService._internal();
|
||
|
||
Future<Database> get database async {
|
||
if (_database != null) return _database!;
|
||
_database = await _initDatabase();
|
||
return _database!;
|
||
}
|
||
|
||
Future<Database> _initDatabase() async {
|
||
final dbPath = await getDatabasesPath();
|
||
final path = join(dbPath, 'kuaishai.db');
|
||
|
||
return await openDatabase(
|
||
path,
|
||
version: 3,
|
||
onCreate: _onCreate,
|
||
onUpgrade: _onUpgrade,
|
||
);
|
||
}
|
||
|
||
Future<void> _onCreate(Database db, int version) async {
|
||
// 程序表
|
||
await db.execute('''
|
||
CREATE TABLE programs (
|
||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||
code TEXT NOT NULL UNIQUE,
|
||
name TEXT NOT NULL,
|
||
created_at TEXT NOT NULL,
|
||
status INTEGER DEFAULT 1,
|
||
temperature INTEGER DEFAULT 50,
|
||
airflow_time INTEGER DEFAULT 60
|
||
)
|
||
''');
|
||
|
||
// 步骤表
|
||
await db.execute('''
|
||
CREATE TABLE steps (
|
||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||
program_id INTEGER NOT NULL,
|
||
step_no INTEGER NOT NULL,
|
||
position TEXT NOT NULL,
|
||
name TEXT NOT NULL,
|
||
mix_time INTEGER DEFAULT 0,
|
||
magnet_time INTEGER DEFAULT 0,
|
||
volume INTEGER DEFAULT 0,
|
||
blow_time INTEGER DEFAULT 0,
|
||
speed INTEGER DEFAULT 5,
|
||
FOREIGN KEY (program_id) REFERENCES programs(id) ON DELETE CASCADE
|
||
)
|
||
''');
|
||
|
||
// 设置表(密码存储)
|
||
await db.execute('''
|
||
CREATE TABLE settings (
|
||
key TEXT PRIMARY KEY,
|
||
value TEXT NOT NULL
|
||
)
|
||
''');
|
||
|
||
// 初始化默认密码
|
||
await db.insert('settings', {'key': 'password', 'value': '123456'});
|
||
}
|
||
|
||
/// 数据库升级
|
||
Future<void> _onUpgrade(Database db, int oldVersion, int newVersion) async {
|
||
if (oldVersion < 2) {
|
||
// 添加 settings 表
|
||
await db.execute('''
|
||
CREATE TABLE settings (
|
||
key TEXT PRIMARY KEY,
|
||
value TEXT NOT NULL
|
||
)
|
||
''');
|
||
// 初始化默认密码
|
||
await db.insert('settings', {'key': 'password', 'value': '123456'});
|
||
}
|
||
if (oldVersion < 3) {
|
||
// v3: 重构字段
|
||
// programs 增加 temperature, airflow_time
|
||
await db.execute('ALTER TABLE programs ADD COLUMN temperature INTEGER DEFAULT 50');
|
||
await db.execute('ALTER TABLE programs ADD COLUMN airflow_time INTEGER DEFAULT 60');
|
||
// steps 删除 mix_speed, blow_speed, needle_speed;增加 speed
|
||
// sqflite 不支持 DROP COLUMN,旧字段保留但不再使用
|
||
await db.execute('ALTER TABLE steps ADD COLUMN speed INTEGER DEFAULT 5');
|
||
}
|
||
}
|
||
|
||
Future<void> close() async {
|
||
if (_database != null) {
|
||
await _database!.close();
|
||
_database = null;
|
||
}
|
||
}
|
||
|
||
/// 通用 KV 读:读取 settings 表中 [key] 对应的 value;不存在返回 null
|
||
Future<String?> readSetting(String key) async {
|
||
final db = await database;
|
||
final rows = await db.query(
|
||
'settings',
|
||
columns: ['value'],
|
||
where: 'key = ?',
|
||
whereArgs: [key],
|
||
limit: 1,
|
||
);
|
||
if (rows.isEmpty) return null;
|
||
return rows.first['value'] as String?;
|
||
}
|
||
|
||
/// 通用 KV 写:以 INSERT OR REPLACE 写入 settings 表
|
||
Future<void> writeSetting(String key, String value) async {
|
||
final db = await database;
|
||
await db.insert(
|
||
'settings',
|
||
{'key': key, 'value': value},
|
||
conflictAlgorithm: ConflictAlgorithm.replace,
|
||
);
|
||
}
|
||
|
||
/// 初始化测试数据(仅调试模式使用)
|
||
Future<void> initTestData() async {
|
||
final db = await database;
|
||
|
||
// 检查是否已有数据
|
||
final count = Sqflite.firstIntValue(
|
||
await db.rawQuery('SELECT COUNT(*) FROM programs'),
|
||
);
|
||
if (count != null && count > 0) return;
|
||
|
||
// 插入测试程序并添加步骤
|
||
final testPrograms = [
|
||
{'code': 'P001', 'name': '标准检测程序', 'created_at': '2026-05-19', 'status': 1, 'temperature': 50, 'airflow_time': 60},
|
||
{'code': 'P002', 'name': '快速检测程序', 'created_at': '2026-05-18', 'status': 1, 'temperature': 45, 'airflow_time': 30},
|
||
{'code': 'P003', 'name': '深度检测程序', 'created_at': '2026-05-17', 'status': 1, 'temperature': 60, 'airflow_time': 90},
|
||
{'code': 'P004', 'name': '样本预处理程序', 'created_at': '2026-05-16', 'status': 0, 'temperature': 50, 'airflow_time': 60},
|
||
{'code': 'P005', 'name': '磁珠分离程序', 'created_at': '2026-05-15', 'status': 1, 'temperature': 55, 'airflow_time': 60},
|
||
];
|
||
|
||
for (final program in testPrograms) {
|
||
final programId = await db.insert('programs', program);
|
||
|
||
// 为每个程序添加测试步骤
|
||
final testSteps = [
|
||
{
|
||
'program_id': programId,
|
||
'step_no': 1,
|
||
'position': 'A1',
|
||
'name': '混合',
|
||
'mix_time': 60,
|
||
'magnet_time': 0,
|
||
'volume': 100,
|
||
'blow_time': 0,
|
||
'speed': 5,
|
||
},
|
||
{
|
||
'program_id': programId,
|
||
'step_no': 2,
|
||
'position': 'A1',
|
||
'name': '吸磁',
|
||
'mix_time': 0,
|
||
'magnet_time': 30,
|
||
'volume': 0,
|
||
'blow_time': 0,
|
||
'speed': 5,
|
||
},
|
||
{
|
||
'program_id': programId,
|
||
'step_no': 3,
|
||
'position': 'A2',
|
||
'name': '吹气',
|
||
'mix_time': 0,
|
||
'magnet_time': 0,
|
||
'volume': 0,
|
||
'blow_time': 10,
|
||
'speed': 8,
|
||
},
|
||
];
|
||
|
||
for (final step in testSteps) {
|
||
await db.insert('steps', step);
|
||
}
|
||
}
|
||
}
|
||
} |