Skip to content

Commit 7c8a3b4

Browse files
committed
[feat]: 组织管理基本功能
1 parent 70ee850 commit 7c8a3b4

File tree

3 files changed

+89
-9
lines changed

3 files changed

+89
-9
lines changed

app/api/v1/endpoints/group.py

Lines changed: 46 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
from fastapi import APIRouter, Query, Body, UploadFile, File, Depends, HTTPException
22
from sqlalchemy.ext.asyncio import AsyncSession
33
import os
4+
import glob
45

56
from app.utils.get_db import get_db
67
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
8+
from app.curd.group import crud_create, crud_apply_to_enter, crud_get_applications, crud_reply_to_enter, crud_modify_basic_info, crud_modify_admin_list, crud_remove_member, crud_leave_group
9+
from app.schemas.group import ApplyToEnter, LeaveGroup
910

1011
router = APIRouter()
1112

@@ -17,6 +18,7 @@ async def create(group_name: str = Query(...), group_desc: str = Query(...), gro
1718
if len(group_desc) > 200:
1819
raise HTTPException(status_code=405, detail="Invalid group description, longer than 200")
1920
group_id = await crud_create(user.get("id"), group_name, group_desc, db)
21+
# 存储头像,文件名为 {group_id}.上传文件的扩展名
2022
if group_avatar:
2123
os.makedirs("/lhcos-data/group-avatar", exist_ok=True)
2224
ext = os.path.splitext(group_avatar.filename)[1]
@@ -39,8 +41,46 @@ async def get_applications(group_id: int = Query(...), db: AsyncSession = Depend
3941
return {"users": users}
4042

4143
@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")
44+
async def reply_to_enter(user_id: int = Body(...), group_id: int = Body(...), reply: bool = Body(...), db: AsyncSession = Depends(get_db)):
4545
msg = await crud_reply_to_enter(user_id, group_id, reply, db)
46-
return {"msg": msg}
46+
return {"msg": msg}
47+
48+
@router.post("/modifyBasicInfo", response_model=dict)
49+
async def modify_basic_info(group_id: int = Query(...), group_name: str | None = Query(None), group_desc: str | None = Query(None), group_avatar: UploadFile | None = File(None), db: AsyncSession = Depends(get_db)):
50+
if group_name and len(group_name) > 30:
51+
raise HTTPException(status_code=405, detail="Invalid group name, longer than 30")
52+
if group_desc and len(group_desc) > 200:
53+
raise HTTPException(status_code=405, detail="Invalid group description, longer than 200")
54+
await crud_modify_basic_info(db=db, id=group_id, name=group_name, desc=group_desc)
55+
if group_avatar:
56+
os.makedirs("/lhcos-data/group-avatar", exist_ok=True)
57+
# 若之前存储了旧头像,则将其删除;若之前就没头像,则不做处理
58+
old_avatar = glob.glob(os.path.join("/lhcos-data/group-avatar", group_id + ".*")) # 基本名为group_id的文件列表,最多有一个元素
59+
if old_avatar:
60+
os.remove(old_avatar[0])
61+
# 存储新头像,文件名为 {group_id}.上传文件的扩展名
62+
ext = os.path.splitext(group_avatar.filename)[1]
63+
path = os.path.join("/lhcos-data/group-avatar", f"{group_id}{ext}")
64+
with open(path, "wb") as f:
65+
content = await group_avatar.read()
66+
f.write(content)
67+
return {"msg": "Basic info modified successfully"}
68+
69+
@router.post("/modifyAdminList", response_model=dict)
70+
async def modify_admin_list(group_id: int = Body(...), user_id: int = Body(...), add_admin: bool = Body(...), db: AsyncSession = Depends(get_db)):
71+
msg = await crud_modify_admin_list(group_id, user_id, add_admin, db)
72+
return {"msg": msg}
73+
74+
@router.post("/removeMember", response_model=dict)
75+
async def remove_member(group_id: int = Body(...), user_id: int = Body(...), db: AsyncSession = Depends(get_db)):
76+
await crud_remove_member(group_id, user_id, db)
77+
return {"msg": "Member removed successfully"}
78+
79+
@router.post("/leaveGroup", response_model=dict)
80+
async def leave_group(model: LeaveGroup, db: AsyncSession = Depends(get_db), user: dict = Depends(get_current_user)):
81+
group_id = model.group_id
82+
user_id = user.get("id")
83+
await crud_leave_group(group_id, user_id, db)
84+
return {"msg": "You successfully left the group"}
85+
86+
# 写返回个人文件树的后端时记得加 visible = True

app/curd/group.py

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from fastapi import HTTPException
22
from sqlalchemy.ext.asyncio import AsyncSession
33
from sqlalchemy.exc import IntegrityError
4-
from sqlalchemy import select, insert, delete
4+
from sqlalchemy import select, insert, delete, update
55
from app.models.model import User, Group, Folder, Article, Note, Tag, user_group, enter_application
66

77
async def crud_create(leader: int, name: str, description: str, db: AsyncSession):
@@ -41,18 +41,55 @@ async def crud_get_applications(group_id: int, db: AsyncSession):
4141
users = result.all()
4242
return [{"user_id": user.id, "user_name": user.username} for user in users]
4343

44-
async def crud_reply_to_enter(user_id: int, group_id: int, reply: int, db: AsyncSession):
44+
async def crud_reply_to_enter(user_id: int, group_id: int, reply: bool, db: AsyncSession):
4545
# 答复后,需要从待处理申请的表中删除表项
4646
query = delete(enter_application).where(enter_application.c.user_id == user_id, enter_application.c.group_id == group_id)
4747
result = await db.execute(query)
4848
if result.rowcount == 0: # 如果没有删除任何行,说明不存在该项
4949
raise HTTPException(status_code=405, detail="Application is not existed or already handled")
5050
await db.commit()
5151

52-
if reply == 1:
52+
if reply:
5353
new_relation = insert(user_group).values(user_id=user_id, group_id=group_id)
5454
await db.execute(new_relation)
5555
await db.commit()
5656
return "Add new member successfully"
5757

5858
return "Refuse the application successfully"
59+
60+
async def crud_modify_basic_info(db: AsyncSession, id: int, name: str | None = None, desc: str | None = None):
61+
update_data = {}
62+
if name:
63+
update_data["name"] = name
64+
if desc:
65+
update_data["description"] = desc
66+
query = update(Group).where(Group.id == id).values(**update_data)
67+
await db.execute(query)
68+
await db.commit()
69+
70+
async def crud_modify_admin_list(group_id: int, user_id: int, add_admin: bool, db: AsyncSession):
71+
# 检查组织中是否有该成员
72+
query = select(user_group).where(user_group.c.user_id == user_id, user_group.c.group_id == group_id)
73+
result = await db.execute(query)
74+
relation = result.first()
75+
if not relation:
76+
raise HTTPException(status_code=405, detail="User currently not in the group")
77+
78+
# 将该成员设为或取消管理员
79+
query = update(user_group).where(user_group.c.group_id == group_id, user_group.c.user_id == user_id).values(is_admin=add_admin)
80+
await db.execute(query)
81+
await db.commit()
82+
83+
return "The user is an admin now" if add_admin else "The user is not an admin now"
84+
85+
async def crud_remove_member(group_id: int, user_id: int, db: AsyncSession):
86+
# 不必先检查组织中是否有该成员,若没有则再执行一次delete也不会报错
87+
query = delete(user_group).where(user_group.c.group_id == group_id, user_group.c.user_id == user_id)
88+
await db.execute(query)
89+
await db.commit()
90+
91+
async def crud_leave_group(group_id: int, user_id: int, db: AsyncSession):
92+
# 不必先检查组织中是否有该成员,若没有则再执行一次delete也不会报错
93+
query = delete(user_group).where(user_group.c.group_id == group_id, user_group.c.user_id == user_id)
94+
await db.execute(query)
95+
await db.commit()

app/schemas/group.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
from pydantic import BaseModel
22

33
class ApplyToEnter(BaseModel):
4+
group_id: int
5+
6+
class LeaveGroup(BaseModel):
47
group_id: int

0 commit comments

Comments
 (0)