Avance del programa
This commit is contained in:
@@ -12,7 +12,8 @@ class DbHelper {
|
||||
|
||||
static Future<Database> _initDb() async {
|
||||
final path = join(await getDatabasesPath(), 'celaya_v3.db');
|
||||
return openDatabase(path, version: 1, onCreate: _onCreate);
|
||||
return openDatabase(path, version: 2,
|
||||
onCreate: _onCreate, onUpgrade: _onUpgrade);
|
||||
}
|
||||
|
||||
static Future<void> _onCreate(Database db, int v) async {
|
||||
@@ -76,6 +77,28 @@ class DbHelper {
|
||||
user_id INTEGER PRIMARY KEY, activo INTEGER DEFAULT 1,
|
||||
notas TEXT)''');
|
||||
|
||||
// NOTAS DE ADMIN SOBRE REPORTES
|
||||
await db.execute('''CREATE TABLE reporte_notas(
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
reporte_id INTEGER NOT NULL, admin_id INTEGER NOT NULL,
|
||||
admin_nombre TEXT NOT NULL, nota TEXT NOT NULL,
|
||||
fecha TEXT NOT NULL)''');
|
||||
|
||||
// EVIDENCIAS DEL ADMIN EN REPORTES
|
||||
await db.execute('''CREATE TABLE reporte_evidencias(
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
reporte_id INTEGER NOT NULL, admin_id INTEGER NOT NULL,
|
||||
pie_imagen TEXT NOT NULL, foto_path TEXT,
|
||||
fecha TEXT NOT NULL)''');
|
||||
|
||||
// CHAT POR REPORTE (admin <-> ciudadano)
|
||||
await db.execute('''CREATE TABLE reporte_chat(
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
reporte_id INTEGER NOT NULL, user_id INTEGER NOT NULL,
|
||||
rol TEXT NOT NULL,
|
||||
mensaje TEXT NOT NULL, fecha TEXT NOT NULL,
|
||||
leido INTEGER DEFAULT 0)''');
|
||||
|
||||
await db.insert('users', {'nombre':'Administrador','email':'admin@celaya.gob.mx',
|
||||
'password':'admin123','rol':'ADMINISTRADOR'});
|
||||
final conductorId = await db.insert('users', {'nombre':'Juan Conductor',
|
||||
@@ -83,6 +106,47 @@ class DbHelper {
|
||||
await db.insert('user_meta', {'user_id': conductorId, 'activo': 1});
|
||||
}
|
||||
|
||||
// Migración incremental — se ejecuta al actualizar la app
|
||||
static Future<void> _onUpgrade(Database db, int oldV, int newV) async {
|
||||
// Agregar columnas/tablas que pueden faltar en instalaciones anteriores
|
||||
final helpers = [
|
||||
// foto_path en reportes
|
||||
"ALTER TABLE reportes ADD COLUMN foto_path TEXT",
|
||||
// Tablas nuevas (IF NOT EXISTS para no fallar si ya existen)
|
||||
'''CREATE TABLE IF NOT EXISTS notification_history(
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
user_id INTEGER, route_id TEXT NOT NULL,
|
||||
event_type TEXT NOT NULL, title TEXT NOT NULL,
|
||||
body TEXT NOT NULL, fecha TEXT NOT NULL,
|
||||
leida INTEGER DEFAULT 0)''',
|
||||
'''CREATE TABLE IF NOT EXISTS user_meta(
|
||||
user_id INTEGER PRIMARY KEY, activo INTEGER DEFAULT 1, notas TEXT)''',
|
||||
'''CREATE TABLE IF NOT EXISTS reporte_notas(
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
reporte_id INTEGER NOT NULL, admin_id INTEGER NOT NULL,
|
||||
admin_nombre TEXT NOT NULL, nota TEXT NOT NULL, fecha TEXT NOT NULL)''',
|
||||
'''CREATE TABLE IF NOT EXISTS reporte_evidencias(
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
reporte_id INTEGER NOT NULL, admin_id INTEGER NOT NULL,
|
||||
pie_imagen TEXT NOT NULL, foto_path TEXT, fecha TEXT NOT NULL)''',
|
||||
'''CREATE TABLE IF NOT EXISTS reporte_chat(
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
reporte_id INTEGER NOT NULL, user_id INTEGER NOT NULL,
|
||||
rol TEXT NOT NULL, mensaje TEXT NOT NULL,
|
||||
fecha TEXT NOT NULL, leido INTEGER DEFAULT 0)''',
|
||||
'''CREATE TABLE IF NOT EXISTS route_definitions(
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
route_id TEXT UNIQUE NOT NULL, nombre TEXT NOT NULL,
|
||||
dias TEXT NOT NULL, hora_inicio TEXT NOT NULL,
|
||||
hora_fin TEXT NOT NULL, turno TEXT NOT NULL,
|
||||
colonias TEXT NOT NULL, activa INTEGER DEFAULT 1)''',
|
||||
];
|
||||
for (final sql in helpers) {
|
||||
try { await db.execute(sql); } catch (_) {}
|
||||
// Ignorar errores (ej. columna ya existe)
|
||||
}
|
||||
}
|
||||
|
||||
// ── USERS ────────────────────────────────────────────────────────────────
|
||||
static Future<int> insertUser(UserModel u) async =>
|
||||
(await database).insert('users', u.toMap(), conflictAlgorithm: ConflictAlgorithm.abort);
|
||||
@@ -385,4 +449,50 @@ class DbHelper {
|
||||
FROM reviews
|
||||
GROUP BY semana ORDER BY semana DESC LIMIT 8''');
|
||||
}
|
||||
|
||||
// ── NOTAS DE ADMIN ───────────────────────────────────────────────────────
|
||||
static Future<void> insertReporteNota(int reporteId, int adminId, String adminNombre, String nota) async =>
|
||||
(await database).insert('reporte_notas', {
|
||||
'reporte_id': reporteId, 'admin_id': adminId,
|
||||
'admin_nombre': adminNombre, 'nota': nota,
|
||||
'fecha': DateTime.now().toIso8601String(),
|
||||
});
|
||||
|
||||
static Future<List<Map<String, dynamic>>> getReporteNotas(int reporteId) async =>
|
||||
(await database).query('reporte_notas',
|
||||
where: 'reporte_id=?', whereArgs: [reporteId], orderBy: 'fecha ASC');
|
||||
|
||||
// ── EVIDENCIAS DEL ADMIN ─────────────────────────────────────────────────
|
||||
static Future<void> insertReporteEvidencia(int reporteId, int adminId, String pie, String? fotoPath) async =>
|
||||
(await database).insert('reporte_evidencias', {
|
||||
'reporte_id': reporteId, 'admin_id': adminId,
|
||||
'pie_imagen': pie, 'foto_path': fotoPath,
|
||||
'fecha': DateTime.now().toIso8601String(),
|
||||
});
|
||||
|
||||
static Future<List<Map<String, dynamic>>> getReporteEvidencias(int reporteId) async =>
|
||||
(await database).query('reporte_evidencias',
|
||||
where: 'reporte_id=?', whereArgs: [reporteId], orderBy: 'fecha ASC');
|
||||
|
||||
// ── CHAT POR REPORTE ─────────────────────────────────────────────────────
|
||||
static Future<void> insertChatMsg(int reporteId, int userId, String rol, String mensaje) async =>
|
||||
(await database).insert('reporte_chat', {
|
||||
'reporte_id': reporteId, 'user_id': userId, 'rol': rol,
|
||||
'mensaje': mensaje, 'fecha': DateTime.now().toIso8601String(), 'leido': 0,
|
||||
});
|
||||
|
||||
static Future<List<Map<String, dynamic>>> getChatMsgs(int reporteId) async =>
|
||||
(await database).query('reporte_chat',
|
||||
where: 'reporte_id=?', whereArgs: [reporteId], orderBy: 'fecha ASC');
|
||||
|
||||
static Future<int> getChatUnread(int reporteId, String rolLector) async {
|
||||
final res = await (await database).rawQuery(
|
||||
"SELECT COUNT(*) as c FROM reporte_chat WHERE reporte_id=? AND rol!=? AND leido=0",
|
||||
[reporteId, rolLector]);
|
||||
return (res.first['c'] as int? ?? 0);
|
||||
}
|
||||
|
||||
static Future<void> markChatRead(int reporteId, String rolLector) async =>
|
||||
(await database).update('reporte_chat', {'leido': 1},
|
||||
where: 'reporte_id=? AND rol!=?', whereArgs: [reporteId, rolLector]);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user