feat: 新增回收站功能
- 数据库添加 is_deleted 和 deleted_at 字段 - 删除数据改为移动到回收站(软删除) - 回收站支持查看、恢复、彻底删除 - 支持一键清空回收站 - 侧边栏添加回收站入口
This commit is contained in:
@@ -61,6 +61,8 @@ class Database:
|
||||
note TEXT,
|
||||
is_starred INTEGER DEFAULT 0,
|
||||
views INTEGER DEFAULT 0,
|
||||
is_deleted INTEGER DEFAULT 0,
|
||||
deleted_at TEXT,
|
||||
created_at TEXT NOT NULL,
|
||||
updated_at TEXT NOT NULL
|
||||
)
|
||||
@@ -131,6 +133,16 @@ class Database:
|
||||
except sqlite3.OperationalError:
|
||||
cursor.execute("ALTER TABLE items ADD COLUMN views INTEGER DEFAULT 0")
|
||||
|
||||
# 检查并添加 is_deleted 和 deleted_at 字段(兼容旧数据库)
|
||||
try:
|
||||
cursor.execute("SELECT is_deleted FROM items LIMIT 1")
|
||||
except sqlite3.OperationalError:
|
||||
cursor.execute("ALTER TABLE items ADD COLUMN is_deleted INTEGER DEFAULT 0")
|
||||
try:
|
||||
cursor.execute("SELECT deleted_at FROM items LIMIT 1")
|
||||
except sqlite3.OperationalError:
|
||||
cursor.execute("ALTER TABLE items ADD COLUMN deleted_at TEXT")
|
||||
|
||||
conn.commit()
|
||||
|
||||
# ============ Item 操作 ============
|
||||
@@ -192,6 +204,9 @@ class Database:
|
||||
params = []
|
||||
conditions = []
|
||||
|
||||
# 只显示未删除的数据
|
||||
conditions.append("i.is_deleted = 0")
|
||||
|
||||
# 标签过滤需要JOIN
|
||||
if tag:
|
||||
query += " JOIN item_tags it ON i.id = it.item_id JOIN tags t ON it.tag_id = t.id"
|
||||
@@ -329,13 +344,73 @@ class Database:
|
||||
return True
|
||||
|
||||
def delete_item(self, item_id: int) -> bool:
|
||||
"""删除条目"""
|
||||
"""删除条目(移动到回收站)"""
|
||||
with self.get_conn() as conn:
|
||||
cursor = conn.cursor()
|
||||
now = datetime.now().isoformat()
|
||||
cursor.execute("UPDATE items SET is_deleted = 1, deleted_at = ? WHERE id = ?", (now, item_id))
|
||||
conn.commit()
|
||||
return cursor.rowcount > 0
|
||||
|
||||
def list_trash(self, limit: int = 50, offset: int = 0) -> List[Dict[str, Any]]:
|
||||
"""列出回收站数据"""
|
||||
with self.get_conn() as conn:
|
||||
cursor = conn.cursor()
|
||||
cursor.execute("SELECT * FROM items WHERE is_deleted = 1 ORDER BY deleted_at DESC LIMIT ? OFFSET ?", (limit, offset))
|
||||
items = []
|
||||
for row in cursor.fetchall():
|
||||
item = dict(row)
|
||||
item['tags'] = self._get_item_tags(conn, item['id'])
|
||||
items.append(item)
|
||||
return items
|
||||
|
||||
def count_trash(self) -> int:
|
||||
"""计算回收站数据总数"""
|
||||
with self.get_conn() as conn:
|
||||
cursor = conn.cursor()
|
||||
cursor.execute("SELECT COUNT(*) as count FROM items WHERE is_deleted = 1")
|
||||
return cursor.fetchone()['count']
|
||||
|
||||
def restore_item(self, item_id: int) -> bool:
|
||||
"""从回收站恢复数据"""
|
||||
with self.get_conn() as conn:
|
||||
cursor = conn.cursor()
|
||||
cursor.execute("UPDATE items SET is_deleted = 0, deleted_at = NULL WHERE id = ?", (item_id,))
|
||||
conn.commit()
|
||||
return cursor.rowcount > 0
|
||||
|
||||
def delete_permanently(self, item_id: int) -> bool:
|
||||
"""彻底删除数据(从数据库中删除)"""
|
||||
with self.get_conn() as conn:
|
||||
cursor = conn.cursor()
|
||||
# 删除标签关联
|
||||
cursor.execute("DELETE FROM item_tags WHERE item_id = ?", (item_id,))
|
||||
# 删除邮件发送记录
|
||||
cursor.execute("DELETE FROM email_logs WHERE item_id = ?", (item_id,))
|
||||
# 删除数据
|
||||
cursor.execute("DELETE FROM items WHERE id = ?", (item_id,))
|
||||
conn.commit()
|
||||
return cursor.rowcount > 0
|
||||
|
||||
def empty_trash(self) -> int:
|
||||
"""清空回收站"""
|
||||
with self.get_conn() as conn:
|
||||
cursor = conn.cursor()
|
||||
# 获取所有回收站数据ID
|
||||
cursor.execute("SELECT id FROM items WHERE is_deleted = 1")
|
||||
ids = [row['id'] for row in cursor.fetchall()]
|
||||
|
||||
# 删除所有关联数据
|
||||
for item_id in ids:
|
||||
cursor.execute("DELETE FROM item_tags WHERE item_id = ?", (item_id,))
|
||||
cursor.execute("DELETE FROM email_logs WHERE item_id = ?", (item_id,))
|
||||
|
||||
# 删除所有回收站数据
|
||||
cursor.execute("DELETE FROM items WHERE is_deleted = 1")
|
||||
deleted_count = cursor.rowcount
|
||||
conn.commit()
|
||||
return deleted_count
|
||||
|
||||
def toggle_star(self, item_id: int) -> bool:
|
||||
"""切换重点关注状态"""
|
||||
with self.get_conn() as conn:
|
||||
|
||||
Reference in New Issue
Block a user