// sqlite_provider.dart import 'package:get/get.dart'; import 'package:problem_check_system/data/models/enum_model.dart'; import 'package:problem_check_system/data/models/problem_model.dart'; import 'package:sqflite/sqflite.dart'; import 'package:path/path.dart'; import 'package:uuid/uuid.dart'; /// `SQLiteProvider` 是一个 GetxService,负责管理本地 SQLite 数据库。 /// 作为一个单例服务,它在整个应用生命周期中只会被创建一次。 class SQLiteProvider extends GetxService { static const String _dbName = 'problems.db'; static const String _tableName = 'problems'; /// 私有数据库实例,仅在服务内部访问。 late Database _database; /// 在服务首次初始化时调用,用于执行异步设置。 @override void onInit() { super.onInit(); _initDatabase(); } /// 异步初始化数据库连接。如果数据库不存在,则会创建它。 Future _initDatabase() async { final databasePath = await getDatabasesPath(); final path = join(databasePath, _dbName); _database = await openDatabase(path, version: 1, onCreate: _onCreate); } /// 数据库创建时的回调函数,用于定义表结构。 Future _onCreate(Database db, int version) async { await db.execute(''' CREATE TABLE $_tableName( id TEXT PRIMARY KEY, description TEXT NOT NULL, location TEXT NOT NULL, imageUrls TEXT NOT NULL, creationTime INTEGER NOT NULL, syncStatus INTEGER NOT NULL, censorTaskId TEXT, bindData TEXT ) '''); } /// --- /// **数据操作 (CRUD) 方法** /// 向数据库中插入一个新问题。 /// 如果 `problem` 没有 `id`,会自动生成一个唯一的 UUID。 Future insertProblem(Problem problem) async { final problemToInsert = problem.copyWith( id: problem.id ?? const Uuid().v4(), ); return await _database.insert( _tableName, problemToInsert.toMap(), conflictAlgorithm: ConflictAlgorithm.replace, ); } /// 根据 ID 从数据库中删除一个问题。 /// 返回被删除的行数。 Future deleteProblem(String id) async { return await _database.delete(_tableName, where: 'id = ?', whereArgs: [id]); } /// 更新数据库中已存在的问题。 /// 返回被更新的行数。 Future updateProblem(Problem problem) async { return await _database.update( _tableName, problem.toMap(), where: 'id = ?', whereArgs: [problem.id], ); } /// 根据 ID 获取单个问题。 /// 如果找到则返回 `Problem` 对象,否则返回 `null`。 Future getProblemById(String id) async { final List> maps = await _database.query( _tableName, where: 'id = ?', whereArgs: [id], limit: 1, ); if (maps.isNotEmpty) { return Problem.fromMap(maps.first); } return null; } /// 获取所有问题,支持按筛选条件查询。 /// 可选参数用于筛选创建时间范围和同步状态。 Future> getProblems({ DateTime? startDate, DateTime? endDate, SyncStatus? syncStatus, }) async { final List whereClauses = []; final List whereArgs = []; if (startDate != null) { whereClauses.add('creationTime >= ?'); whereArgs.add(startDate.millisecondsSinceEpoch); } if (endDate != null) { whereClauses.add('creationTime <= ?'); whereArgs.add(endDate.millisecondsSinceEpoch); } if (syncStatus != null) { whereClauses.add('syncStatus = ?'); whereArgs.add(syncStatus.index); } final String? whereString = whereClauses.isNotEmpty ? whereClauses.join(' AND ') : null; final List> maps = await _database.query( _tableName, where: whereString, whereArgs: whereArgs.isEmpty ? null : whereArgs, orderBy: 'creationTime DESC', ); return maps.map((json) => Problem.fromMap(json)).toList(); } /// --- /// `GetxService` 生命周期方法,在服务被销毁前调用, /// 用于关闭数据库连接,防止资源泄漏。 @override void onClose() { _database.close(); super.onClose(); } }