Spaces:
Sleeping
Sleeping
| """ | |
| AI 垃圾分类助手 - 数据库模块 | |
| 使用 SQLite 记录用户分类历史和环保积分 | |
| """ | |
| import sqlite3 | |
| from datetime import date | |
| class Database: | |
| def __init__(self, db_path="garbage_assistant.db"): | |
| self.db_path = db_path | |
| self.init_database() | |
| def _get_conn(self): | |
| conn = sqlite3.connect(self.db_path) | |
| conn.row_factory = sqlite3.Row | |
| conn.execute("PRAGMA journal_mode=WAL") | |
| return conn | |
| def init_database(self): | |
| conn = self._get_conn() | |
| conn.executescript(""" | |
| CREATE TABLE IF NOT EXISTS users ( | |
| id INTEGER PRIMARY KEY AUTOINCREMENT, | |
| username TEXT UNIQUE NOT NULL, | |
| total_points INTEGER DEFAULT 0, | |
| total_classifications INTEGER DEFAULT 0, | |
| created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP | |
| ); | |
| CREATE TABLE IF NOT EXISTS records ( | |
| id INTEGER PRIMARY KEY AUTOINCREMENT, | |
| user_id INTEGER NOT NULL, | |
| image_path TEXT, | |
| predicted_class TEXT NOT NULL, | |
| confidence REAL, | |
| points INTEGER DEFAULT 10, | |
| created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, | |
| FOREIGN KEY (user_id) REFERENCES users(id) | |
| ); | |
| CREATE TABLE IF NOT EXISTS daily_stats ( | |
| id INTEGER PRIMARY KEY AUTOINCREMENT, | |
| user_id INTEGER NOT NULL, | |
| date TEXT NOT NULL, | |
| count INTEGER DEFAULT 0, | |
| points INTEGER DEFAULT 0, | |
| FOREIGN KEY (user_id) REFERENCES users(id), | |
| UNIQUE(user_id, date) | |
| ); | |
| """) | |
| conn.commit() | |
| conn.close() | |
| def register_user(self, username): | |
| conn = self._get_conn() | |
| try: | |
| cursor = conn.cursor() | |
| cursor.execute("INSERT INTO users (username) VALUES (?)", (username,)) | |
| conn.commit() | |
| user_id = cursor.lastrowid | |
| print(f"✓ 用户 '{username}' 注册成功 (ID: {user_id})") | |
| return user_id | |
| except sqlite3.IntegrityError: | |
| user_id = conn.execute( | |
| "SELECT id FROM users WHERE username = ?", (username,) | |
| ).fetchone()["id"] | |
| print(f"ℹ 用户 '{username}' 已存在 (ID: {user_id})") | |
| return user_id | |
| finally: | |
| conn.close() | |
| def get_user(self, username): | |
| conn = self._get_conn() | |
| user = conn.execute( | |
| "SELECT * FROM users WHERE username = ?", (username,) | |
| ).fetchone() | |
| conn.close() | |
| return dict(user) if user else None | |
| def add_record(self, user_id, predicted_class, confidence, image_path=None): | |
| today = date.today().isoformat() | |
| points = max(5, min(20, int(confidence * 20))) | |
| conn = self._get_conn() | |
| conn.execute( | |
| "INSERT INTO records (user_id, image_path, predicted_class, confidence, points) VALUES (?, ?, ?, ?, ?)", | |
| (user_id, image_path, predicted_class, confidence, points), | |
| ) | |
| conn.execute( | |
| "UPDATE users SET total_points = total_points + ?, total_classifications = total_classifications + 1 WHERE id = ?", | |
| (points, user_id), | |
| ) | |
| conn.execute( | |
| "INSERT INTO daily_stats (user_id, date, count, points) VALUES (?, ?, 1, ?) " | |
| "ON CONFLICT(user_id, date) DO UPDATE SET count = count + 1, points = points + ?", | |
| (user_id, today, points, points), | |
| ) | |
| conn.commit() | |
| conn.close() | |
| return points | |
| def get_user_stats(self, user_id): | |
| conn = self._get_conn() | |
| user = conn.execute("SELECT * FROM users WHERE id = ?", (user_id,)).fetchone() | |
| if not user: | |
| conn.close() | |
| return None | |
| stats = dict(user) | |
| stats["recent_records"] = [ | |
| dict(r) for r in conn.execute( | |
| "SELECT predicted_class, confidence, points, created_at FROM records WHERE user_id = ? ORDER BY created_at DESC LIMIT 10", | |
| (user_id,), | |
| ).fetchall() | |
| ] | |
| stats["class_distribution"] = [ | |
| dict(r) for r in conn.execute( | |
| "SELECT predicted_class, COUNT(*) as count FROM records WHERE user_id = ? GROUP BY predicted_class ORDER BY count DESC", | |
| (user_id,), | |
| ).fetchall() | |
| ] | |
| today = date.today().isoformat() | |
| today_row = conn.execute( | |
| "SELECT * FROM daily_stats WHERE user_id = ? AND date = ?", (user_id, today) | |
| ).fetchone() | |
| stats["today"] = dict(today_row) if today_row else {"count": 0, "points": 0} | |
| stats["weekly"] = [ | |
| dict(r) for r in conn.execute( | |
| "SELECT date, count, points FROM daily_stats WHERE user_id = ? AND date >= date('now', '-7 days') ORDER BY date DESC", | |
| (user_id,), | |
| ).fetchall() | |
| ] | |
| conn.close() | |
| return stats | |
| def get_leaderboard(self, limit=10): | |
| conn = self._get_conn() | |
| leaders = conn.execute( | |
| "SELECT username, total_points, total_classifications FROM users ORDER BY total_points DESC LIMIT ?", | |
| (limit,), | |
| ).fetchall() | |
| conn.close() | |
| return [dict(r) for r in leaders] | |