from math import floor from django.db import models from django.db.models import Sum from django.http import HttpResponse,JsonResponse from django.views.decorators.csrf import csrf_exempt from datetime import datetime, timedelta from django.core import serializers import time import json import os import jwt from .models import DogTrainingNew, WalkDogsScore os.environ.setdefault("DJANGO_SETTINGS_MODULE", "aiDogProject.settings") import django django.setup() from aiDogApp.models import * from . import aidog_tools,aidog_request_tools #遛狗结果提交接口:客户端上传user_id、access_token,score,maxCombo,perfect,good,poor,miss,coin,date_time # POST /api/walkdogs/score/ # 2025/6/6 # 这个接口返回的是重置结果。{ # "status": "string", # "message": "string", # "user_info": {}, # "dogs": {} # } @csrf_exempt def walk_dogs_score(request): # 记录请求时间 current_time = datetime.now().strftime('%Y-%m-%d %H:%M:%S') # 清理30天前的WalkDogsScore记录 thirty_days_ago = datetime.now().date() - timedelta(days=30) try: deleted_count, _ = WalkDogsScore.objects.filter(walk_time__lt=thirty_days_ago).delete() if deleted_count > 0: print(f"Cleaned up {deleted_count} WalkDogsScore records older than 30 days") except Exception as cleanup_error: print(f"Error during WalkDogsScore cleanup: {str(cleanup_error)}") # 清理失败不影响主要功能,继续执行 try: # 获取请求参数 params = aidog_request_tools.handle_post_request_parameters( request, ["access_token", "user_id", "score", "maxCombo", "perfect", "good", "poor", "miss","coin"] ) date_time = request.POST.get("date_time", '') access_token = params["access_token"] user_id = params["user_id"] score = int(params["score"]) maxCombo = int(params["maxCombo"]) perfect = int(params["perfect"]) good = int(params["good"]) poor = int(params["poor"]) miss = int(params["miss"]) coin = int(params["coin"]) print(f"Error during WalkDogsScore access_token: {access_token}") # 验证访问令牌 token_validation = aidog_tools.validate_access_token(access_token) if isinstance(token_validation, JsonResponse): return token_validation user_id = token_validation['user_id'] try: #计算总分=perfect次数*100+good次数*30+poor次数*10是否与score一致,不一致报错, # 奖励计算方式:用户金币+=floor(总分/1000) # 每次请求接口,所有的狗:快乐 + 20,体力 - 10,口渴 - 15,健康 + 10,好奇心 + 10,活泼度 + 5,敏捷度 + 5,如果maxCombo >= 15,跑步速度 + 5,如果maxCombo >= 30,跑步速度 + 15,肥胖程度 - 10 #一天最多奖励2次 # 计算总分验证 calculated_score = int(perfect) * 100 + int(good) * 30 + int(poor) * 10 if score != calculated_score: return JsonResponse({ "status": "error", "date": current_time, "message": f"Score calculation mismatch! Expected: {calculated_score}, Got: {score}", "end_time": current_time }) # 计算奖励金币 reward_coins = floor(calculated_score / 1000) if reward_coins != coin: return JsonResponse({ "status": "error", "date": current_time, "message": f"Coin calculation mismatch! Expected: {reward_coins}, Got: {coin}", "end_time": current_time }) # 获取今天的日期(年-月-日) today = datetime.now().date() # 检查今天已经获得奖励的次数 today_rewards = WalkDogsScore.objects.filter( uid=user_id, walk_time=today ).aggregate(total_count=Sum('walk_count'))['total_count'] or 0 # 检查是否达到每日上限 if today_rewards< 2: # 创建新的遛狗记录 walk_dog_record = WalkDogsScore.objects.create( uid=user_id, score=score, maxcombo=maxCombo, perfect=perfect, good=good, poor=poor, miss=miss, walk_time=today, walk_count=1 # 每次记录计数为1 ) # 更新用户金币 try: user = User.objects.get(uid=user_id) user.coin = (user.coin or 0) + reward_coins user.save() except User.DoesNotExist: return JsonResponse({ "status": "error", "date": current_time, "message": "User not found" }) # 获取用户的所有狗列表 dog_info = Doginfo.objects.filter(owner_id=user_id) for dog in dog_info: # dog_id=dog.dog_id dog_serialized = serializers.serialize('json', [dog]) dog_data = json.loads(dog_serialized)[0]['fields'] dog_id = dog_data['d_id'] print(f"dog_id for ------------- {dog_id}") # 更新狗的状态 try: dog_status = DogStatus.objects.get(d_id=dog_id) dog_status.happiness = min((dog_status.happiness or 0) + 20, 100) # 最大值100 dog_status.stamina = max((dog_status.stamina or 0) - 10, 0) # 最小值0 dog_status.thirsty = max((dog_status.thirsty or 0) - 15, 0) # 最小值0 dog_status.healthy = min((dog_status.healthy or 0) + 10, 100) # 最大值100 dog_status.clean = max((dog_status.clean or 0) - 10, 0) # 最小值0 dog_status.satiety = max((dog_status.satiety or 0) - 10, 0) # 最小值0 print(f"happiness for ------------- {dog_status.happiness}") dog_status.save() except DogStatus.DoesNotExist: continue # 如果状态不存在,跳过这只狗 # 更新狗的身体属性 try: dog_body_attr = DogBodyAttributes.objects.get(d_id=dog_id) dog_body_attr.curiosity = min((dog_body_attr.curiosity or 0) + 10, 100) dog_body_attr.liveliness = min((dog_body_attr.liveliness or 0) + 5, 100) dog_body_attr.agility = min((dog_body_attr.agility or 0) + 5, 100) dog_body_attr.obesity = max((dog_body_attr.obesity or 0) - 10, 0) # 根据maxCombo调整跑步速度 speed_bonus = 0 if maxCombo >= 30: speed_bonus = 20 # 15 + 5 elif maxCombo >= 15: speed_bonus = 5 if speed_bonus > 0: dog_body_attr.runSpeed = min((dog_body_attr.runSpeed or 0) + speed_bonus, 100) print(f"dog_body_attr.curiosity for ------------- {dog_body_attr.curiosity }") dog_body_attr.save() except DogBodyAttributes.DoesNotExist: continue # 如果属性不存在,跳过这只狗 except Exception as e: # 全局异常处理 import traceback traceback.print_exc() return JsonResponse({ "status": "error", "message": f"Server processing exception: {str(e)}", "date": current_time }) # 获取用户信息 try: user = User.objects.get(uid=user_id) user_info = aidog_tools._build_user_info(user) except User.DoesNotExist: user_info = {} # 获取用户的所有狗列表 try: dog_info = Doginfo.objects.filter(owner_id=user_id) dog_list = [] for dog in dog_info: dog_serialized = serializers.serialize('json', [dog]) dog_data = json.loads(dog_serialized)[0]['fields'] dog_id = dog_data['d_id'] # 获取狗的信息并转换为字典 new_dog_status = aidog_tools.model_to_dict_without_id(DogStatus.objects.filter(d_id=dog_id).first()) new_dog_training = aidog_tools.model_to_dict_without_id( DogTrainingNew.objects.filter(d_id=dog_id).first()) new_dog_body_attributes = aidog_tools.model_to_dict_without_id( DogBodyAttributes.objects.filter(d_id=dog_id).first()) new_dog_personality_relationship = aidog_tools.model_to_dict_without_id( DogPersonalityRelationship.objects.filter(d_id=dog_id).first()) # 合并所有相关信息 dog_info_combined = { **dog_data, **new_dog_status, **new_dog_training, **new_dog_body_attributes, **new_dog_personality_relationship, } # 只保留字段而不是数据库内部的元数据(如 '_state') dog_info_clean = {key: value for key, value in dog_info_combined.items() if not key.startswith('_')} dog_list.append(dog_info_clean) except Exception as e: dog_list = [] # 返回包含所有voice得分的结果 return JsonResponse({ "status": "success", "code":200, "date": current_time, "message": 'Walk dog score uploaded successfully', "reward_coins": reward_coins, "today_rewards": today_rewards + 1, "user_info":user_info, "dogs": dog_list, }) except Exception as e: # 全局异常处理 import traceback traceback.print_exc() return JsonResponse({ "status": "error", "message": f"Server processing exception: {str(e)}", "date": current_time }) #遛狗结果提交接口:客户端上传user_id、access_token,item_id,dog_id,catch,distance,date_time # 考虑到未来有多个飞盘的设定 示例值:toy_00001 # catch true接到飞盘,false没有接到 # POST /api/frisbee/score/ # 2025/6/13 # 这个接口返回的是重置结果。{ # "status": "string", # "message": "string", # "user_info": {}, # "dogs": {} # } @csrf_exempt def frisbee_dogs_score(request): # 记录请求时间 current_time = datetime.now().strftime('%Y-%m-%d %H:%M:%S') # 清理30天前的WalkDogsScore记录 thirty_days_ago = datetime.now().date() - timedelta(days=30) try: deleted_count, _ = FrisbeeDogsScore.objects.filter(frisbee_time__lt=thirty_days_ago).delete() if deleted_count > 0: print(f"Cleaned up {deleted_count} WalkDogsScore records older than 30 days") except Exception as cleanup_error: print(f"Error during WalkDogsScore cleanup: {str(cleanup_error)}") # 清理失败不影响主要功能,继续执行 try: # 获取请求参数 params = aidog_request_tools.handle_post_request_parameters( request, ["access_token", "user_id", "item_id", "dog_id", "catch", "distance"] ) date_time = request.POST.get("date_time", '') access_token = params["access_token"] user_id = params["user_id"] item_id = params["item_id"] dog_id = params["dog_id"] distance = float(params["distance"]) # 转换 catch 参数 catch_str = params["catch"] if isinstance(catch_str, str): catch = 1 if catch_str.lower() == 'true' else 0 else: catch = int(bool(catch_str)) # 验证访问令牌 token_validation = aidog_tools.validate_access_token(access_token) if isinstance(token_validation, JsonResponse): return token_validation user_id = token_validation['user_id'] try: #计算总分=飞行距离是否与score一致,不一致报错, # 奖励计算方式:用户金币+=floor(总分/1000) # 每次请求接口,单一狗:无论成功是否:快乐 + 2,体力 - 6,口渴 - 5,健康 + 3,活泼度 + 2,敏捷度 + 2,肥胖程度 - 2,干净 - 3,饱腹度 - 5 # 如果成功跑步速度 + 2,跳跃高度 + 2,叼飞盘熟练度 + 2 #一天最多奖励5次 # 计算奖励金币 reward_coins = floor(distance) # 获取今天的日期(年-月-日) today = datetime.now().date() # 检查今天已经获得奖励的次数 today_rewards = FrisbeeDogsScore.objects.filter( uid=user_id, frisbee_time=today ).aggregate(total_count=Sum('frisbee_count'))['total_count'] or 0 # 检查是否达到每日上限 if today_rewards< 5: # 创建新的丢飞盘记录 frisbee_dog_record = FrisbeeDogsScore.objects.create( uid=user_id, d_id=dog_id, item_id=item_id, catch=catch, distance=distance, frisbee_time=today, frisbee_count=1 # 每次记录计数为1 ) # 更新用户金币 try: user = User.objects.get(uid=user_id) user.coin = (user.coin or 0) + reward_coins user.save() except User.DoesNotExist: return JsonResponse({ "status": "error", "date": current_time, "message": "User not found" }) # 更新该狗状态 try: dog_status = DogStatus.objects.get(d_id=dog_id) dog_status.happiness = min((dog_status.happiness or 0) + 2, 100) # 最大值100 dog_status.stamina = max((dog_status.stamina or 0) - 6, 0) # 最小值0 dog_status.thirsty = max((dog_status.thirsty or 0) - 5, 0) # 最小值0 dog_status.healthy = min((dog_status.healthy or 0) + 3, 100) # 最大值100 dog_status.clean = max((dog_status.clean or 0) - 3, 0) # 最小值0 dog_status.satiety = max((dog_status.satiety or 0) - 5, 0) # 最小值0 print(f"happiness for ------------- {dog_status.happiness}") dog_status.save() except DogStatus.DoesNotExist: return JsonResponse({ "status": "error", "message": f"Server processing exception: {str(e)}", "date": current_time }) # 更新狗的身体属性 try: dog_body_attr = DogBodyAttributes.objects.get(d_id=dog_id) dog_body_attr.liveliness = min((dog_body_attr.liveliness or 0) + 2, 100) dog_body_attr.agility = min((dog_body_attr.agility or 0) + 2, 100) dog_body_attr.obesity = max((dog_body_attr.obesity or 0) - 2, 0) if catch: dog_body_attr.runSpeed = min((dog_body_attr.runSpeed or 0) + 2, 100) dog_body_attr.jumpHeight = min((dog_body_attr.jumpHeight or 0) + 2, 100) dog_body_attr.frisbeeSkill = min((dog_body_attr.frisbeeSkill or 0) + 2, 100) dog_body_attr.save() except DogBodyAttributes.DoesNotExist: return JsonResponse({ "status": "error", "message": f"Server processing exception: {str(e)}", "date": current_time }) except Exception as e: # 全局异常处理 import traceback traceback.print_exc() return JsonResponse({ "status": "error", "message": f"Server processing exception: {str(e)}", "date": current_time }) # 获取用户信息 try: user = User.objects.get(uid=user_id) user_info = aidog_tools._build_user_info(user) except User.DoesNotExist: user_info = {} # 获取用户的所有狗列表 try: dog_info = Doginfo.objects.filter(owner_id=user_id) dog_list = [] for dog in dog_info: dog_serialized = serializers.serialize('json', [dog]) dog_data = json.loads(dog_serialized)[0]['fields'] dog_id = dog_data['d_id'] # 获取狗的信息并转换为字典 new_dog_status = aidog_tools.model_to_dict_without_id(DogStatus.objects.filter(d_id=dog_id).first()) new_dog_training = aidog_tools.model_to_dict_without_id( DogTrainingNew.objects.filter(d_id=dog_id).first()) new_dog_body_attributes = aidog_tools.model_to_dict_without_id( DogBodyAttributes.objects.filter(d_id=dog_id).first()) new_dog_personality_relationship = aidog_tools.model_to_dict_without_id( DogPersonalityRelationship.objects.filter(d_id=dog_id).first()) # 合并所有相关信息 dog_info_combined = { **dog_data, **new_dog_status, **new_dog_training, **new_dog_body_attributes, **new_dog_personality_relationship, } # 只保留字段而不是数据库内部的元数据(如 '_state') dog_info_clean = {key: value for key, value in dog_info_combined.items() if not key.startswith('_')} dog_list.append(dog_info_clean) except Exception as e: dog_list = [] # 返回包含所有voice得分的结果 return JsonResponse({ "status": "success", "code":200, "date": current_time, "message": 'Frisbee score uploaded successfully', "reward_coins": reward_coins, "today_total_count": today_rewards + 1, "user_info":user_info, "dogs": dog_list, }) except Exception as e: # 全局异常处理 import traceback traceback.print_exc() return JsonResponse({ "status": "error", "message": f"Server processing exception: {str(e)}", "date": current_time })