v1.0.3 上线第一版

main
mula.liu 2025-09-15 11:52:00 +08:00
parent aad59dd5df
commit 689300044c
16 changed files with 40 additions and 1713 deletions

BIN
.DS_Store vendored

Binary file not shown.

BIN
app.zip 100644

Binary file not shown.

View File

@ -1,6 +1,6 @@
from fastapi import APIRouter, HTTPException, Depends from fastapi import APIRouter, HTTPException, Depends
from app.models.models import UserInfo, PasswordChangeRequest, UserListResponse, CreateUserRequest, UpdateUserRequest from app.models.models import UserInfo, PasswordChangeRequest, UserListResponse, CreateUserRequest, UpdateUserRequest, RoleInfo
from app.core.database import get_db_connection from app.core.database import get_db_connection
from app.core.auth import get_current_user from app.core.auth import get_current_user
from app.core.config import DEFAULT_RESET_PASSWORD from app.core.config import DEFAULT_RESET_PASSWORD
@ -18,6 +18,18 @@ def validate_email(email: str) -> bool:
def hash_password(password: str) -> str: def hash_password(password: str) -> str:
return hashlib.sha256(password.encode()).hexdigest() return hashlib.sha256(password.encode()).hexdigest()
@router.get("/roles")
def get_all_roles(current_user: dict = Depends(get_current_user)):
"""获取所有角色列表"""
if current_user['role_id'] != 1: # 1 is admin
raise HTTPException(status_code=403, detail="仅管理员有权限查看角色列表")
with get_db_connection() as connection:
cursor = connection.cursor(dictionary=True)
cursor.execute("SELECT role_id, role_name FROM roles ORDER BY role_id")
roles = cursor.fetchall()
return [RoleInfo(**role) for role in roles]
@router.post("/users", status_code=201) @router.post("/users", status_code=201)
def create_user(request: CreateUserRequest, current_user: dict = Depends(get_current_user)): def create_user(request: CreateUserRequest, current_user: dict = Depends(get_current_user)):
if current_user['role_id'] != 1: # 1 is admin if current_user['role_id'] != 1: # 1 is admin
@ -85,7 +97,12 @@ def update_user(user_id: int, request: UpdateUserRequest, current_user: dict = D
connection.commit() connection.commit()
# Return updated user info # Return updated user info
cursor.execute("SELECT user_id, username, caption, email, created_at FROM users WHERE user_id = %s", (user_id,)) cursor.execute('''
SELECT u.user_id, u.username, u.caption, u.email, u.created_at, u.role_id, r.role_name
FROM users u
LEFT JOIN roles r ON u.role_id = r.role_id
WHERE u.user_id = %s
''', (user_id,))
updated_user = cursor.fetchone() updated_user = cursor.fetchone()
return UserInfo( return UserInfo(
@ -94,6 +111,8 @@ def update_user(user_id: int, request: UpdateUserRequest, current_user: dict = D
caption=updated_user['caption'], caption=updated_user['caption'],
email=updated_user['email'], email=updated_user['email'],
created_at=updated_user['created_at'], created_at=updated_user['created_at'],
role_id=updated_user['role_id'],
role_name=updated_user['role_name'],
meetings_created=0, # This is not accurate, but it is not displayed in the list meetings_created=0, # This is not accurate, but it is not displayed in the list
meetings_attended=0 meetings_attended=0
) )
@ -149,15 +168,17 @@ def get_all_users(page: int = 1, size: int = 10, current_user: dict = Depends(ge
cursor.execute("SELECT COUNT(*) as total FROM users") cursor.execute("SELECT COUNT(*) as total FROM users")
total = cursor.fetchone()['total'] total = cursor.fetchone()['total']
# Get paginated users # Get paginated users with role names
offset = (page - 1) * size offset = (page - 1) * size
query = ''' query = '''
SELECT SELECT
user_id, username, caption, email, created_at, u.user_id, u.username, u.caption, u.email, u.created_at, u.role_id,
r.role_name,
(SELECT COUNT(*) FROM meetings WHERE user_id = u.user_id) as meetings_created, (SELECT COUNT(*) FROM meetings WHERE user_id = u.user_id) as meetings_created,
(SELECT COUNT(*) FROM attendees WHERE user_id = u.user_id) as meetings_attended (SELECT COUNT(*) FROM attendees WHERE user_id = u.user_id) as meetings_attended
FROM users u FROM users u
ORDER BY user_id ASC LEFT JOIN roles r ON u.role_id = r.role_id
ORDER BY u.user_id ASC
LIMIT %s OFFSET %s LIMIT %s OFFSET %s
''' '''
cursor.execute(query, (size, offset)) cursor.execute(query, (size, offset))
@ -172,7 +193,12 @@ def get_user_info(user_id: int, current_user: dict = Depends(get_current_user)):
with get_db_connection() as connection: with get_db_connection() as connection:
cursor = connection.cursor(dictionary=True) cursor = connection.cursor(dictionary=True)
user_query = "SELECT user_id, username, caption, email, created_at FROM users WHERE user_id = %s" user_query = '''
SELECT u.user_id, u.username, u.caption, u.email, u.created_at, u.role_id, r.role_name
FROM users u
LEFT JOIN roles r ON u.role_id = r.role_id
WHERE u.user_id = %s
'''
cursor.execute(user_query, (user_id,)) cursor.execute(user_query, (user_id,))
user = cursor.fetchone() user = cursor.fetchone()
@ -193,6 +219,8 @@ def get_user_info(user_id: int, current_user: dict = Depends(get_current_user)):
caption=user['caption'], caption=user['caption'],
email=user['email'], email=user['email'],
created_at=user['created_at'], created_at=user['created_at'],
role_id=user['role_id'],
role_name=user['role_name'],
meetings_created=meetings_created, meetings_created=meetings_created,
meetings_attended=meetings_attended meetings_attended=meetings_attended
) )

View File

@ -15,6 +15,10 @@ class LoginResponse(BaseModel):
token: str token: str
role_id: int role_id: int
class RoleInfo(BaseModel):
role_id: int
role_name: str
class UserInfo(BaseModel): class UserInfo(BaseModel):
user_id: int user_id: int
username: str username: str
@ -23,6 +27,8 @@ class UserInfo(BaseModel):
created_at: datetime.datetime created_at: datetime.datetime
meetings_created: int meetings_created: int
meetings_attended: int meetings_attended: int
role_id: int
role_name: str
class UserListResponse(BaseModel): class UserListResponse(BaseModel):
users: list[UserInfo] users: list[UserInfo]

BIN
uploads/.DS_Store vendored

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 251 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 211 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 221 KiB

File diff suppressed because it is too large Load Diff