Skip to content

Commit d5fead2

Browse files
committed
[feat]: 创建和加入组织
1 parent a92b7e3 commit d5fead2

File tree

6 files changed

+130
-12
lines changed

6 files changed

+130
-12
lines changed

app/api/v1/endpoints/article.py

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -40,19 +40,16 @@ async def get_self_folders(page_number: Optional[int] = Query(None, ge=1), page_
4040
# 获取用户id
4141
user_id = user.get("id")
4242

43-
# 数据库查询
44-
folders = await crud_get_self_folders(user_id, page_number, page_size, db)
45-
46-
# 返回结果
43+
total_num, folders = await crud_get_self_folders(user_id, page_number, page_size, db)
4744
result = [{"folder_id": folder.id, "folder_name": folder.name} for folder in folders]
48-
return {"result": result}
45+
return {"total_num": total_num, "result": result}
4946

5047
@router.get("/getArticlesInFolder", response_model="dict")
5148
async def get_articles_in_folder(folder_id: int = Query(...), page_number: Optional[int] = Query(None, ge=1), page_size: Optional[int] = Query(None, ge=1),
5249
db: AsyncSession = Depends(get_db)):
53-
articles = await crud_get_articles_in_folder(folder_id, page_number, page_size, db)
50+
total_num, articles = await crud_get_articles_in_folder(folder_id, page_number, page_size, db)
5451
result = [{"article_id": article.id, "article_name": article.name} for article in articles]
55-
return {"result": result}
52+
return {"total_num": total_num, "result": result}
5653

5754
@router.post("/selfCreateFolder", response_model="dict")
5855
async def self_create_folder(model: SelfCreateFolder, db: AsyncSession = Depends(get_db), user: dict = Depends(get_current_user)):

app/api/v1/endpoints/group.py

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
from fastapi import APIRouter, Query, Body, UploadFile, File, Depends, HTTPException
2+
from sqlalchemy.ext.asyncio import AsyncSession
3+
import os
4+
5+
from app.utils.get_db import get_db
6+
from app.utils.auth import get_current_user
7+
from app.curd.group import crud_create, crud_apply_to_enter, crud_get_applications, crud_reply_to_enter
8+
from app.schemas.group import ApplyToEnter
9+
10+
router = APIRouter()
11+
12+
@router.post("/create", response_model=dict)
13+
async def create(group_name: str = Query(...), group_desc: str = Query(...), group_avatar: UploadFile | None = File(None)
14+
, db: AsyncSession = Depends(get_db), user: dict = Depends(get_current_user)):
15+
if len(group_name) > 30:
16+
raise HTTPException(status_code=405, detail="Invalid group name, longer than 30")
17+
if len(group_desc) > 200:
18+
raise HTTPException(status_code=405, detail="Invalid group description, longer than 200")
19+
group_id = await crud_create(user.get("id"), group_name, group_desc, db)
20+
if group_avatar:
21+
os.makedirs("/lhcos-data/group-avatar", exist_ok=True)
22+
ext = os.path.splitext(group_avatar.filename)[1]
23+
path = os.path.join("/lhcos-data/group-avatar", f"{group_id}{ext}")
24+
with open(path, "wb") as f:
25+
content = await group_avatar.read()
26+
f.write(content)
27+
return {"msg": "Group created successfully"}
28+
29+
@router.post("/applyToEnter", response_model=dict)
30+
async def apply_to_enter(model: ApplyToEnter, db: AsyncSession = Depends(get_db), user: dict = Depends(get_current_user)):
31+
group_id = model.group_id
32+
user_id = user.get("id")
33+
await crud_apply_to_enter(user_id, group_id, db)
34+
return {"msg": "Application sent successfully"}
35+
36+
@router.get("/getApplications", response_model=dict)
37+
async def get_applications(group_id: int = Query(...), db: AsyncSession = Depends(get_db)):
38+
users = await crud_get_applications(group_id, db)
39+
return {"users": users}
40+
41+
@router.post("/replyToEnter", response_model=dict)
42+
async def reply_to_enter(user_id: int = Body(...), group_id: int = Body(...), reply: int = Body(...), db: AsyncSession = Depends(get_db)):
43+
if reply != 0 and reply != 1:
44+
raise HTTPException(status_code=405, detail="Wrong parameter, reply should be either 0 or 1")
45+
msg = await crud_reply_to_enter(user_id, group_id, reply, db)
46+
return {"msg": msg}

app/curd/article.py

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,23 +13,31 @@ async def crud_upload_to_self_folder(name: str, folder_id: int, db: AsyncSession
1313

1414
async def crud_get_self_folders(user_id: int, page_number: int, page_size: int, db: AsyncSession):
1515
query = select(Folder).where(Folder.user_id == user_id, Folder.visible == True).order_by(Folder.id.desc())
16+
count_query = select(func.count()).select_from(query.subquery())
17+
count_result = await db.execute(count_query)
18+
total_num = count_result.scalar()
19+
1620
if page_number and page_size:
1721
offset = (page_number - 1) * page_size
1822
query = query.offset(offset).limit(page_size)
19-
2023
result = await db.execute(query)
2124
folders = result.scalars().all()
22-
return folders
25+
26+
return total_num, folders
2327

2428
async def crud_get_articles_in_folder(folder_id: int, page_number: int, page_size: int, db: AsyncSession):
2529
query = select(Article).where(Article.folder_id == folder_id, Article.visible == True).order_by(Article.id.desc())
30+
count_query = select(func.count()).select_from(query.subquery())
31+
count_result = await db.execute(count_query)
32+
total_num = count_result.scalar()
33+
2634
if page_number and page_size:
2735
offset = (page_number - 1) * page_size
2836
query = query.offset(offset).limit(page_size)
29-
3037
result = await db.execute(query)
3138
articles = result.scalars().all()
32-
return articles
39+
40+
return total_num, articles
3341

3442
async def crud_self_create_folder(name: str, user_id: int, db: AsyncSession):
3543
new_folder = Folder(name=name, user_id=user_id)

app/curd/group.py

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
from fastapi import HTTPException
2+
from sqlalchemy.ext.asyncio import AsyncSession
3+
from sqlalchemy.exc import IntegrityError
4+
from sqlalchemy import select, insert, delete
5+
from app.models.model import User, Group, Folder, Article, Note, Tag, user_group, enter_application
6+
7+
async def crud_create(leader: int, name: str, description: str, db: AsyncSession):
8+
new_group = Group(leader=leader, name=name, description=description)
9+
db.add(new_group)
10+
await db.commit()
11+
await db.refresh(new_group)
12+
return new_group.id
13+
14+
async def crud_apply_to_enter(user_id: int, group_id: int, db: AsyncSession):
15+
# 是否已经在组织中
16+
query = select(user_group).where(user_group.c.user_id == user_id, user_group.c.group_id == group_id)
17+
result = await db.execute(query)
18+
existing = result.first()
19+
if existing:
20+
raise HTTPException(status_code=405, detail="Already in the group")
21+
query = select(Group).where(Group.id == group_id)
22+
result = await db.execute(query)
23+
group = result.scalar_one_or_none()
24+
if group.leader == user_id:
25+
raise HTTPException(status_code=405, detail="Already in the group")
26+
27+
# 插入申请表,若已存在申请则抛出异常
28+
query = insert(enter_application).values(user_id=user_id, group_id=group_id)
29+
try:
30+
await db.execute(query)
31+
await db.commit()
32+
except IntegrityError:
33+
await db.rollback()
34+
raise HTTPException(status_code=405, detail="Don't apply repeatedly")
35+
36+
async def crud_get_applications(group_id: int, db: AsyncSession):
37+
query = select(User.id, User.username).where(User.id.in_(
38+
select(enter_application.c.user_id).where(enter_application.c.group_id == group_id)
39+
))
40+
result = await db.execute(query)
41+
users = result.all()
42+
return [{"user_id": user.id, "user_name": user.username} for user in users]
43+
44+
async def crud_reply_to_enter(user_id: int, group_id: int, reply: int, db: AsyncSession):
45+
# 答复后,需要从待处理申请的表中删除表项
46+
query = delete(enter_application).where(enter_application.c.user_id == user_id, enter_application.c.group_id == group_id)
47+
result = await db.execute(query)
48+
if result.rowcount == 0: # 如果没有删除任何行,说明不存在该项
49+
raise HTTPException(status_code=405, detail="Application is not existed or already handled")
50+
await db.commit()
51+
52+
if reply == 1:
53+
new_relation = insert(user_group).values(user_id=user_id, group_id=group_id)
54+
await db.execute(new_relation)
55+
await db.commit()
56+
return "Add new member successfully"
57+
58+
return "Refuse the application successfully"

app/routers/router.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
from app.api.v1.endpoints.aichat import router as aichat_router
77
from app.api.v1.endpoints.article import router as article_router
88
from app.api.v1.endpoints.articleDB import router as articleDB_router
9+
from app.api.v1.endpoints.group import router as group_router
910

1011
def include_auth_router(app):
1112
app.include_router(auth_router, prefix="/public", tags=["auth"])
@@ -25,10 +26,14 @@ def include_article_router(app):
2526
def include_articleDB_router(app):
2627
app.include_router(articleDB_router, prefix="/database", tags=["articleDB"], dependencies=[Depends(get_current_user)])
2728

29+
def include_group_router(app):
30+
app.include_router(group_router, prefix="/group", tags=["group"], dependencies=[Depends(get_current_user)])
31+
2832
def include_routers(app):
2933
include_auth_router(app)
3034
include_note_router(app)
3135
include_user_router(app)
3236
include_aichat_router(app)
3337
include_article_router(app)
34-
include_articleDB_router(app)
38+
include_articleDB_router(app)
39+
include_group_router(app)

app/schemas/group.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
from pydantic import BaseModel
2+
3+
class ApplyToEnter(BaseModel):
4+
group_id: int

0 commit comments

Comments
 (0)