diff --git a/api/controllers/service_api_with_auth/user/profile.py b/api/controllers/service_api_with_auth/user/profile.py index fed35c5827..0c51fc7bbd 100644 --- a/api/controllers/service_api_with_auth/user/profile.py +++ b/api/controllers/service_api_with_auth/user/profile.py @@ -1,10 +1,16 @@ -from flask import Blueprint -from flask_restful import Api, Resource # type: ignore +import re from controllers.service_api_with_auth import api +from controllers.service_api_with_auth.wraps import validate_user_token_and_extract_info +from flask import Blueprint, request +from flask_restful import Api, Resource # type: ignore +from models.model import EndUser +from services.end_user_service import EndUserService + class UserProfile(Resource): - def get(self): + @validate_user_token_and_extract_info + def get(self, end_user: EndUser): """Get user profile. --- tags: @@ -32,9 +38,12 @@ class UserProfile(Resource): 401: description: Invalid or missing token """ - pass + # Use the service to get user profile + profile = EndUserService.get_user_profile(end_user.id) + return profile - def put(self): + @validate_user_token_and_extract_info + def put(self, end_user: EndUser): """Update user profile. --- tags: @@ -75,6 +84,38 @@ class UserProfile(Resource): 401: description: Invalid or missing token """ - pass + data = request.get_json() + validated_data = {} + + # Validate username if provided + if 'username' in data: + username = data['username'] + # Validate username (Chinese or English only, max 10 chars) + if not re.match(r'^[a-zA-Z\u4e00-\u9fa5]+$', username) or len(username) > 10: + return {"success": False, "message": "Invalid username format"}, 400 + validated_data['username'] = username + + # Validate gender if provided + if 'gender' in data: + gender_str = data['gender'] + if gender_str not in ["unknown", "male", "female"]: + return {"success": False, "message": "Invalid gender value"}, 400 + validated_data['gender'] = gender_str + + # Validate major if provided + if 'major' in data: + major = data['major'] + if len(major) > 20: + return {"success": False, "message": "Major exceeds maximum length"}, 400 + validated_data['major'] = major + + # Use the service to update user profile + success, error = EndUserService.update_user_profile(end_user, validated_data) + + if not success: + return {"success": False, "message": error or "Failed to update profile"}, 500 + + return {"success": True} + -api.add_resource(UserProfile, '/user/profile') \ No newline at end of file +api.add_resource(UserProfile, '/user/profile') diff --git a/api/pyproject.toml b/api/pyproject.toml index e633aa90da..f125517267 100644 --- a/api/pyproject.toml +++ b/api/pyproject.toml @@ -8,10 +8,7 @@ requires = ["poetry-core>=2.0.0"] build-backend = "poetry.core.masonry.api" [tool.poetry] -name = "jim-api" -version = "0.1.0" -description = "Jim API - LLM application development platform" -authors = ["Jim Team "] +package-mode = false ############################################################ # [ Main ] Dependency group diff --git a/api/services/end_user_service.py b/api/services/end_user_service.py new file mode 100644 index 0000000000..08f7d19c60 --- /dev/null +++ b/api/services/end_user_service.py @@ -0,0 +1,85 @@ +from typing import Any, Dict, Optional, Tuple + +from extensions.ext_database import db +from models.account import Account +from models.model import EndUser + + +class EndUserService: + @staticmethod + def get_user_profile(end_user_id: str) -> Dict[str, Any]: + """ + Get user profile information + + Args: + end_user_id: The ID of the end user + + Returns: + Dict containing user profile information + """ + # Get EndUser information + end_user = db.session.query(EndUser).filter(EndUser.id == end_user_id).first() + + if not end_user: + return {"username": None, "gender": "unknown", "major": None, "email": None} + + # Map numeric gender to string representation + gender_map = {0: "unknown", 1: "male", 2: "female"} + + # Get major from extra_profile if it exists + major = None + if end_user.extra_profile and 'major' in end_user.extra_profile: + major = end_user.extra_profile.get('major') + + # Get email from Account table + account = db.session.query(Account).filter(Account.id == end_user_id).first() + email = account.email if account else None + + return { + "username": end_user.name, + "gender": gender_map.get(end_user.gender, "unknown"), + "major": major, + "email": email, + } + + @staticmethod + def update_user_profile(end_user: EndUser, profile_data: Dict[str, Any]) -> Tuple[bool, Optional[str]]: + """ + Update user profile information + + Args: + end_user: The EndUser object to update + profile_data: Dictionary containing profile data to update + + Returns: + Tuple of (success, error_message) + """ + try: + # Update username if provided + if 'username' in profile_data: + end_user.name = profile_data['username'] + + # Update gender if provided + if 'gender' in profile_data: + gender_str = profile_data['gender'] + gender_map = {"unknown": 0, "male": 1, "female": 2} + end_user.gender = gender_map[gender_str] + + # Update major if provided + if 'major' in profile_data: + major = profile_data['major'] + + # Initialize extra_profile if it doesn't exist + if not end_user.extra_profile: + end_user.extra_profile = {} + + # Update major in extra_profile + end_user.extra_profile['major'] = major + + # Save changes to database + db.session.commit() + return True, None + + except Exception as e: + db.session.rollback() + return False, str(e)