11from sqlalchemy .ext .asyncio import AsyncSession
2- from sqlalchemy import select , delete
2+ from sqlalchemy import select , delete , insert , desc
33from sqlalchemy import func , cast , Date
44from datetime import datetime , timedelta
5- from app .models .model import User , Group , Folder , Article , Note , Tag , user_group
5+ from app .models .model import User , Group , Folder , Article , Note , Tag , user_group , self_recycle_bin
66
77async def crud_upload_to_self_folder (name : str , folder_id : int , db : AsyncSession ):
88 new_article = Article (name = name , folder_id = folder_id )
@@ -46,25 +46,31 @@ async def crud_self_create_folder(name: str, user_id: int, db: AsyncSession):
4646 await db .refresh (new_folder )
4747 return new_folder .id
4848
49- async def crud_self_article_to_recycle_bin (article_id : int , db : AsyncSession ):
50- # 查询 article
49+ async def crud_self_article_to_recycle_bin (article_id : int , user_id : int , db : AsyncSession ):
50+ # 维护 article 表
5151 query = select (Article ).where (Article .id == article_id )
5252 result = await db .execute (query )
5353 article = result .scalar_one_or_none ()
54-
55- # 修改 visible 字段
5654 article .visible = False
55+
56+ # 维护 self_recycle_bin 表
57+ recycle = insert (self_recycle_bin ).values (user_id = user_id , type = 2 , id = article_id , name = article .name , folder_id = article .folder_id )
58+ await db .execute (recycle )
59+
5760 await db .commit ()
5861 await db .refresh (article )
5962
60- async def crud_self_folder_to_recycle_bin (folder_id : int , db : AsyncSession ):
61- # 查询 folder
63+ async def crud_self_folder_to_recycle_bin (folder_id : int , user_id : int , db : AsyncSession ):
64+ # 维护 folder 表
6265 query = select (Folder ).where (Folder .id == folder_id )
6366 result = await db .execute (query )
6467 folder = result .scalar_one_or_none ()
65-
66- # 修改 visible 字段
6768 folder .visible = False
69+
70+ # 维护 self_recycle_bin 表
71+ recycle = insert (self_recycle_bin ).values (user_id = user_id , type = 1 , id = folder_id , name = folder .name )
72+ await db .execute (recycle )
73+
6874 await db .commit ()
6975 await db .refresh (folder )
7076
@@ -166,11 +172,11 @@ async def crud_article_statistic(db: AsyncSession):
166172 tomorrow = datetime .now ().date () + timedelta (days = 1 )
167173 seven_days_ago = datetime .now ().date () - timedelta (days = 6 )
168174
169- # 查询近7天内的笔记数目 ,按日期分组
175+ # 查询近7天内的文献数目 ,按日期分组
170176 query = (
171177 select (
172178 cast (Article .create_time , Date ).label ("date" ), # 按日期分组
173- func .count (Article .id ).label ("count" ) # 统计每日期的笔记数
179+ func .count (Article .id ).label ("count" ) # 统计每日期的文献数
174180 )
175181 .where (
176182 Article .create_time >= seven_days_ago , # 大于等于7天前的0点
@@ -243,11 +249,11 @@ async def crud_self_article_statistic(user_id: int, db: AsyncSession):
243249 tomorrow = datetime .now ().date () + timedelta (days = 1 )
244250 seven_days_ago = datetime .now ().date () - timedelta (days = 6 )
245251
246- # 查询近7天内的笔记数目 ,按日期分组
252+ # 查询近7天内的文献数目 ,按日期分组
247253 query = (
248254 select (
249255 cast (Article .create_time , Date ).label ("date" ), # 按日期分组
250- func .count (Article .id ).label ("count" ) # 统计每日期的笔记数
256+ func .count (Article .id ).label ("count" ) # 统计每日期的文献数
251257 )
252258 .join (Folder , Article .folder_id == Folder .id )
253259 .where (
@@ -273,4 +279,95 @@ async def crud_self_article_statistic(user_id: int, db: AsyncSession):
273279 if i == len (articles ) or articles [i ].get ("date" ) != seven_days_ago + timedelta (days = i ):
274280 articles .insert (i , {"date" : seven_days_ago + timedelta (days = i ), "count" : 0 })
275281
276- return article_total_num , articles
282+ return article_total_num , articles
283+
284+ async def crud_items_in_recycle_bin (user_id : int , page_number : int , page_size : int , db : AsyncSession ):
285+ query = select (
286+ self_recycle_bin .c .type ,
287+ self_recycle_bin .c .id ,
288+ self_recycle_bin .c .name ,
289+ self_recycle_bin .c .create_time
290+ ).where (self_recycle_bin .c .user_id == user_id ).order_by (desc (self_recycle_bin .c .create_time ))
291+
292+ if page_number and page_size :
293+ offset = (page_number - 1 ) * page_size
294+ query = query .offset (offset ).limit (page_size )
295+
296+ result = await db .execute (query )
297+ items = result .fetchall ()
298+
299+ return [{"type" : item .type , "id" : item .id , "name" : item .name , "time" : item .create_time .strftime ("%Y-%m-%d %H:%M:%S" )} for item in items ]
300+
301+ async def crud_delete_forever (type : int , id : int , db : AsyncSession ):
302+ query = delete (self_recycle_bin ).where (self_recycle_bin .c .type == type , self_recycle_bin .c .id == id )
303+ await db .execute (query )
304+ if type == 1 :
305+ query = delete (Folder ).where (Folder .id == id )
306+ elif type == 2 :
307+ query = delete (Article ).where (Article .id == id )
308+ else :
309+ query = delete (Note ).where (Note .id == id )
310+ await db .execute (query )
311+ await db .commit ()
312+
313+ async def crud_recover (type : int , id : int , db : AsyncSession ):
314+ query = select (self_recycle_bin ).where (self_recycle_bin .c .type == type , self_recycle_bin .c .id == id )
315+ result = await db .execute (query )
316+ item = result .first ()
317+ if type == 3 :
318+ # 检查上级文献存在性
319+ query = select (Article ).where (Article .id == item .article_id )
320+ result = await db .execute (query )
321+ article = result .scalar_one_or_none ()
322+ article_name = article .name
323+ article_visible = article .visible
324+ # 检查上级文件夹存在性
325+ query = select (Folder ).where (Folder .id == item .folder_id )
326+ result = await db .execute (query )
327+ folder = result .scalar_one_or_none ()
328+ folder_name = folder .name
329+ folder_visible = folder .visible
330+ # 若上级不存在,则给用户以提示信息,请用户先恢复相应的文件夹和文献
331+ if not article_visible or not folder_visible :
332+ return {"info" : "Note recovered failed, please check its upper-level node" , "folder_name" : folder_name , "article_name" : article_name }
333+ # 若上级存在,则正常恢复即可,在回收站表中删除该表项,并将Note表中visible改为True
334+ query = delete (self_recycle_bin ).where (self_recycle_bin .c .type == type , self_recycle_bin .c .id == id )
335+ await db .execute (query )
336+ query = select (Note ).where (Note .id == id )
337+ result = await db .execute (query )
338+ note = result .scalar_one_or_none ()
339+ note .visible = True
340+ await db .commit ()
341+ await db .refresh (note )
342+ return {"info" : "Note recovered successfully" }
343+ if type == 2 :
344+ # 检查上级文件夹存在性
345+ query = select (Folder ).where (Folder .id == item .folder_id )
346+ result = await db .execute (query )
347+ folder = result .scalar_one_or_none ()
348+ folder_name = folder .name
349+ folder_visible = folder .visible
350+ # 若上级不存在,则给用户以提示信息,请用户先恢复相应的文件夹
351+ if not folder_visible :
352+ return {"info" : "Article recovered failed, please check its upper-level node" , "folder_name" : folder_name }
353+ # 若上级存在,则正常恢复即可,在回收站表中删除该表项,并将Article表中visible改为True
354+ query = delete (self_recycle_bin ).where (self_recycle_bin .c .type == type , self_recycle_bin .c .id == id )
355+ await db .execute (query )
356+ query = select (Article ).where (Article .id == id )
357+ result = await db .execute (query )
358+ article = result .scalar_one_or_none ()
359+ article .visible = True
360+ await db .commit ()
361+ await db .refresh (article )
362+ return {"info" : "Article recovered successfully" }
363+ if type == 1 :
364+ # 正常恢复即可,在回收站表中删除该表项,并将Folder表中visible改为True
365+ query = delete (self_recycle_bin ).where (self_recycle_bin .c .type == type , self_recycle_bin .c .id == id )
366+ await db .execute (query )
367+ query = select (Folder ).where (Folder .id == id )
368+ result = await db .execute (query )
369+ folder = result .scalar_one_or_none ()
370+ folder .visible = True
371+ await db .commit ()
372+ await db .refresh (folder )
373+ return {"info" : "Folder recovered successfully" }
0 commit comments