# 核心功能1: 用户认证处理(登录或注册)def handle_user_auth(request): username = request.POST.get('username', '').strip() password = request.POST.get('password', '').strip() if not username or not password: return JsonResponse({'status': 'error', 'message': '用户名或密码不能为空'}) # 模拟数据库查询,检查用户是否存在 existing_user = User.objects.filter(username=username).first() if existing_user: # 用户存在,进行密码校验 if existing_user.check_password(password): # 密码正确,登录成功,更新最后登录时间 existing_user.last_login = timezone.now() existing_user.save(update_fields=['last_login']) # 生成或获取用户token token, _ = Token.objects.get_or_create(user=existing_user) return JsonResponse({'status': 'success', 'message': '登录成功', 'token': token.key, 'user_id': existing_user.id}) else: # 密码错误 return JsonResponse({'status': 'error', 'message': '密码错误'}) else: # 用户不存在,执行注册逻辑 try: new_user = User.objects.create_user(username=username, password=password) new_user.is_active = True new_user.save() # 为新用户生成token token = Token.objects.create(user=new_user) return JsonResponse({'status': 'success', 'message': '注册成功', 'token': token.key, 'user_id': new_user.id}) except Exception as e: return JsonResponse({'status': 'error', 'message': f'注册失败: {str(e)}'})# 核心功能2: 搜索音乐并添加到指定播放列表def search_and_add_to_playlist(request): user_id = request.POST.get('user_id') search_query = request.POST.get('query', '').strip() playlist_id = request.POST.get('playlist_id') song_id_to_add = request.POST.get('song_id') if not all([user_id, search_query, playlist_id, song_id_to_add]): return JsonResponse({'status': 'error', 'message': '参数不完整'}) # 验证播放列表是否属于当前用户 playlist = Playlist.objects.filter(id=playlist_id, user_id=user_id).first() if not playlist: return JsonResponse({'status': 'error', 'message': '播放列表不存在或无权限'}) # 验证歌曲是否存在 song = Music.objects.filter(id=song_id_to_add, title__icontains=search_query).first() if not song: return JsonResponse({'status': 'error', 'message': '未找到要添加的歌曲'}) # 检查歌曲是否已在播放列表中 if PlaylistSong.objects.filter(playlist_id=playlist, song_id=song).exists(): return JsonResponse({'status': 'warning', 'message': '歌曲已存在于播放列表中'}) # 添加歌曲到播放列表 try: PlaylistSong.objects.create(playlist_id=playlist, song_id=song) # 更新播放列表的修改时间和歌曲数量 playlist.song_count = F('song_count') + 1 playlist.updated_at = timezone.now() playlist.save(update_fields=['song_count', 'updated_at']) return JsonResponse({'status': 'success', 'message': f'成功将《{song.title}》添加到《{playlist.name}》'}) except Exception as e: return JsonResponse({'status': 'error', 'message': f'添加失败: {str(e)}'})# 核心功能3: 基于用户播放历史生成个性化音乐推荐def generate_recommendations(request): user_id = request.GET.get('user_id') if not user_id: return JsonResponse({'status': 'error', 'message': '用户ID缺失'}) # 初始化SparkSession,用于大数据分析 spark = SparkSession.builder \ .appName("MusicRecommendation") \ .config("spark.sql.warehouse.dir", "/user/hive/warehouse") \ .enableHiveSupport() \ .getOrCreate() try: # 模拟从MySQL加载用户播放历史到Spark DataFrame user_history_df = spark.read.format("jdbc").options( url="jdbc:mysql://localhost:3306/music_db", driver="com.mysql.jdbc.Driver", dbtable="user_play_history", user="root", password="password" ).load() # 模拟加载所有歌曲元数据 songs_df = spark.read.format("jdbc").options( url="jdbc:mysql://localhost:3306/music_db", driver="com.mysql.jdbc.Driver", dbtable="music", user="root", password="password" ).load() # 筛选出当前用户播放过的歌曲ID played_songs_df = user_history_df.filter(F.col("user_id") == user_id).select("song_id") # 找出播放过相同歌曲的其他用户 similar_users_df = user_history_df.join(played_songs_df, "song_id", "inner") \ .filter(F.col("user_id") != user_id) \ .select("user_id").distinct() # 找出这些相似用户播放过但当前用户未播放的歌曲 candidate_songs_df = user_history_df.join(similar_users_df, "user_id", "inner") \ .join(played_songs_df, "song_id", "leftanti") \ .groupBy("song_id").count() \ .orderBy(F.col("count").desc()) # 获取推荐歌曲的详细信息 recommendations_df = candidate_songs_df.limit(10).join(songs_df, "song_id", "inner") recommended_songs = [row['title'] for row in recommendations_df.select('title').collect()] spark.stop() return JsonResponse({'status': 'success', 'recommendations': recommended_songs}) except Exception as e: spark.stop() return JsonResponse({'status': 'error', 'message': f'推荐生成失败: {str(e)}'})