You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

147 lines
4.2 KiB

// 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<void> _initDatabase() async {
final databasePath = await getDatabasesPath();
final path = join(databasePath, _dbName);
_database = await openDatabase(path, version: 1, onCreate: _onCreate);
}
/// 数据库创建时的回调函数,用于定义表结构。
Future<void> _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<int> 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<int> deleteProblem(String id) async {
return await _database.delete(_tableName, where: 'id = ?', whereArgs: [id]);
}
/// 更新数据库中已存在的问题。
/// 返回被更新的行数。
Future<int> updateProblem(Problem problem) async {
return await _database.update(
_tableName,
problem.toMap(),
where: 'id = ?',
whereArgs: [problem.id],
);
}
/// 根据 ID 获取单个问题。
/// 如果找到则返回 `Problem` 对象,否则返回 `null`。
Future<Problem?> getProblemById(String id) async {
final List<Map<String, dynamic>> maps = await _database.query(
_tableName,
where: 'id = ?',
whereArgs: [id],
limit: 1,
);
if (maps.isNotEmpty) {
return Problem.fromMap(maps.first);
}
return null;
}
/// 获取所有问题,支持按筛选条件查询。
/// 可选参数用于筛选创建时间范围和同步状态。
Future<List<Problem>> getProblems({
DateTime? startDate,
DateTime? endDate,
SyncStatus? syncStatus,
}) async {
final List<String> whereClauses = [];
final List<dynamic> 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<Map<String, dynamic>> 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();
}
}