123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472 |
- 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
- })
|