views.py 50 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295
  1. import string
  2. from django.http import HttpResponse,JsonResponse
  3. from django.shortcuts import render
  4. from django.views.decorators.csrf import csrf_exempt #在视图函数上添加@csrf_exempt装饰器来绕过CSRF保护。不引起csrf报错也可以在前端加上{%csrf_token%}
  5. from . import aidog_tools,aidog_request_tools,generalRequest,dbOperate_upload_Uvoice,login as login_func,register,puppyStateUpdate,initialPuppyState #引入请求声纹API方法
  6. from datetime import datetime, timedelta
  7. from django.utils import timezone
  8. import random
  9. import json
  10. import time
  11. import traceback
  12. import os
  13. import jwt
  14. os.environ.setdefault("DJANGO_SETTINGS_MODULE", "aiDogProject.settings")
  15. import django
  16. django.setup()
  17. from aiDogApp.models import *
  18. from django.views.decorators.csrf import csrf_exempt
  19. import hashlib
  20. from django.core import serializers
  21. from django.db import transaction
  22. # from aiDogApp.settings import SECRET_KEY
  23. # Create your views here.
  24. # from rest_framework.decorators import api_view
  25. # from rest_framework.response import Response
  26. # APPId = "4522d502"
  27. # APISecret = "Zjc5MjJhMzBmMDYxNTg4MTNlMTg1MmQw"
  28. # APIKey = "f7a9f0ceae3ff7ebfc0c89efeb18810d"
  29. # APPId = "527f831f"
  30. # APISecret = "YWE5MjI0MzA4NmM3MTNmNTNiMWJkYzE4"
  31. # APIKey = "be5c37f3db1569737934240a0e3ad02d"
  32. APPId = "ed8eb862"
  33. APISecret = "YzEyMDYyMzljMDViNWJlZDdlOWJhYjVi"
  34. APIKey = "b4c831160d8933221e95bda817547e99"
  35. # file_path = './media/讯飞开放平台.mp3'#读取数据库路径下音源@@@@@@@@@@@@
  36. file_path = './audio_cache/voice_JTYNZP9O_1729843681.mp3'#读取数据库路径下音源
  37. res_pub={
  38. "status":"",
  39. "date":"2024-5-6",
  40. "msg":""
  41. }
  42. SECRET_KEY='#tdfnrcn1s610h4*csa2-p+=lfqz-ol+=uo$+n2sa'
  43. # # 生成access_token
  44. def generate_access_token(user_id):
  45. expiration_time= timezone.now() + timedelta(days=1) # 1天有效
  46. payload = {
  47. 'user_id': user_id,
  48. 'exp': expiration_time
  49. }
  50. return jwt.encode(payload, SECRET_KEY, algorithm='HS256')
  51. # 生成login_token
  52. def generate_login_token(user_id):
  53. expiration_time = timezone.now() + timedelta(days=7) # 7天有效
  54. payload = {
  55. 'user_id': user_id,
  56. 'exp': expiration_time
  57. }
  58. return jwt.encode(payload, SECRET_KEY, algorithm='HS256')
  59. # 统一的错误响应处理
  60. def handle_error(error_message):
  61. # 打印错误堆栈信息到日志或控制台
  62. traceback.print_exc()
  63. return JsonResponse({"status": "error", "message": error_message}, status=500)
  64. # 验证 Token 的函数
  65. # def validate_token(token):
  66. # try:
  67. # decoded_token = jwt.decode(token, SECRET_KEY, algorithms=["HS256"])
  68. # return decoded_token["uid"]
  69. # except jwt.ExpiredSignatureError:
  70. # raise ValueError("Token has expired.")
  71. # except jwt.InvalidTokenError:
  72. # raise ValueError("Invalid token.")
  73. #校验声纹接口:客户端上传用户id、wav格式文件流,转换文件流为MP3缓存在本地固定路径下
  74. # 提交用户id到数据库遍历全部声纹id
  75. # 每个声纹id+用户id+mp3路径上传到科大校验接口,筛选出得分最高的声纹id,并返回其口令类型,删除此mp3文件
  76. # 2024/12/02 无token
  77. # author Feng
  78. @csrf_exempt
  79. def check_Uvoice(request):
  80. user_uid=request.POST.get("user_id",'')# 用户ID
  81. file_stream = request.FILES.get("file_stream") # Get the uploaded file
  82. best_res = None # 存储符合条件的最大 score 结果
  83. max_score = 0.3 # 初始为0.3, 只记录比0.3大的score
  84. # file_path = './audio_cache/voice_JTYNZP9O_1729843681.mp3'
  85. # 当前时间
  86. date_now=datetime.now()
  87. # 校验上传的文件流
  88. if not file_stream:
  89. return JsonResponse({
  90. "status": "Error",
  91. "message": "File not uploaded.",
  92. "date": datetime.now().strftime('%Y-%m-%d %H:%M:%S')
  93. })
  94. # 确保用户id不为空
  95. if not user_uid :
  96. return JsonResponse({
  97. "status": "Error",
  98. "date": datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
  99. "message": "Please ensure all required fields are provided!",
  100. "end_time": datetime.now().strftime('%Y-%m-%d %H:%M:%S')
  101. })
  102. # 定义本地缓存路径
  103. # TODO----------迁移到登录/注册逻辑内 确保缓存目录只在应用启动时创建
  104. cache_directory = "audio_cache"
  105. os.makedirs(cache_directory, exist_ok=True)
  106. # 创建一个唯一的文件名
  107. timestamp = int(time.time())
  108. mp3_path = os.path.join(cache_directory, f"voice_check_{user_uid}_{timestamp}.mp3")
  109. # 将上传的文件流转换为 MP3 并保存
  110. if not dbOperate_upload_Uvoice.process_audio_file(file_stream, mp3_path):
  111. return JsonResponse({
  112. "status": "Error",
  113. "message": "Failed to process the audio file.",
  114. "date": datetime.now().strftime('%Y-%m-%d %H:%M:%S')
  115. })
  116. voices = VoiceFeatureInfo.objects.filter(uid=user_uid)
  117. for voice in voices:
  118. message_response = generalRequest.req_url(
  119. api_name='searchScoreFea', APPId=APPId, APIKey=APIKey, APISecret=APISecret,
  120. file_path=mp3_path, featureId=voice.voice_feature_id, groupId=user_uid
  121. )
  122. if message_response.get('code') == 0:
  123. data_dict = json.loads(message_response.get('msg'))
  124. score = data_dict.get('score')
  125. # print(score)
  126. # 更新最大 score 和对应的结果
  127. if score and score > max_score:
  128. max_score = score
  129. best_res = {
  130. "status": "success",
  131. "date": date_now.strftime('%Y-%m-%d %H:%M:%S'),
  132. "message": message_response,
  133. "score": score,
  134. "command_type": voice.command_type,
  135. "end_time": datetime.now().strftime('%Y-%m-%d %H:%M:%S')
  136. }
  137. # 清理临时 mp3 文件
  138. os.remove(mp3_path)
  139. # 检查是否找到符合条件的结果
  140. if best_res:
  141. return JsonResponse(best_res)
  142. else:
  143. return JsonResponse({"message": "请重新发出口令."})
  144. #上传声纹接口:客户端上传用户id、command_type、文件流
  145. # 2024/12/02 无token
  146. # author Feng
  147. @csrf_exempt
  148. def upload_Uvoice(request):
  149. # if request.method != "POST":
  150. # return JsonResponse({
  151. # "status": "Error",
  152. # "message": "Only POST method is allowed.",
  153. # "date": datetime.strftime(datetime.today(), '%Y-%m-%d %H:%M:%S')
  154. # })
  155. user_uid = request.POST.get("user", '') # 用户ID
  156. command_type = request.POST.get("command_type", '')
  157. file_stream = request.FILES.get("file_stream") # Get the uploaded file
  158. feature_id = str(time.time())[:10] # 随机 voice feature ID
  159. res = None
  160. # user_uid = 'iFLYTEK_examples_groupId'
  161. # command_type = 3
  162. if not file_stream:
  163. return JsonResponse({
  164. "status": "Error",
  165. "message": "File not uploaded.",
  166. "date": datetime.now().strftime('%Y-%m-%d %H:%M:%S')
  167. })
  168. # 确保用户id和声纹id不为空
  169. if not user_uid or not command_type:
  170. return JsonResponse({
  171. "status": "Error",
  172. "date": datetime.strftime(datetime.today(), '%Y-%m-%d %H:%M:%S'),
  173. "message": "Please ensure all required fields are provided!",
  174. "end_time": datetime.now().strftime('%Y-%m-%d %H:%M:%S')
  175. })
  176. try:
  177. # 尝试将 command_type 转换为整数
  178. # 使用INT 类型 查询和索引也会更高效
  179. command_type = int(command_type)
  180. except ValueError:
  181. # 如果转换失败,返回错误信息
  182. return JsonResponse({
  183. "status": "Error",
  184. "message": "Invalid value for command_type. It must be an integer.",
  185. "date": datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
  186. "end_time": datetime.now().strftime('%Y-%m-%d %H:%M:%S')
  187. })
  188. # 成功的情况下处理请求
  189. res = {
  190. "status": "Success",
  191. "date": datetime.strftime(datetime.today(), '%Y-%m-%d %H:%M:%S'),
  192. "message": dbOperate_upload_Uvoice.process_voice_recording(user_uid, feature_id, command_type,file_stream),
  193. "end_time": datetime.now().strftime('%Y-%m-%d %H:%M:%S')
  194. }
  195. return JsonResponse(res)
  196. #上传声纹接口:客户端上传用户id、command_type、文件流
  197. # 2024/12/02 带token
  198. # author Feng
  199. @csrf_exempt
  200. def upload_Uvoice_token(request):
  201. try:
  202. # 验证请求方法
  203. if request.method != "POST":
  204. return JsonResponse({
  205. "status": "Error",
  206. "message": "Only POST method is allowed.",
  207. "date": datetime.now().strftime('%Y-%m-%d %H:%M:%S')
  208. })
  209. # 获取 Token 并验证
  210. # token = request.META.get("HTTP_AUTHORIZATION") # 从请求头获取 Token
  211. # if not token:
  212. # return JsonResponse({"status": "Error", "message": "Token is missing."}, status=401)
  213. # uid = validate_token(token)
  214. uid="11111"
  215. # 获取请求参数
  216. command_type = request.POST.get("command_type", '')
  217. file_stream = request.FILES.get("file_stream") # 上传的文件
  218. feature_id = str(time.time())[:10] # 生成 voice feature ID
  219. # 验证必要参数
  220. if not file_stream or not command_type:
  221. return JsonResponse({
  222. "status": "Error",
  223. "message": "Missing required fields: file_stream or command_type.",
  224. "date": datetime.now().strftime('%Y-%m-%d %H:%M:%S')
  225. })
  226. # 处理上传
  227. result = dbOperate_upload_Uvoice.process_voice_recording(uid, feature_id, command_type, file_stream)
  228. res = {
  229. "status": "Success",
  230. "date": datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
  231. "message": result,
  232. }
  233. return JsonResponse(res)
  234. except ValueError as ve:
  235. return JsonResponse({"status": "Error", "message": str(ve)}, status=401)
  236. except Exception as e:
  237. import traceback
  238. traceback.print_exc()
  239. return JsonResponse({"status": "Error", "message": str(e)}, status=500)
  240. # @csrf_exempt
  241. def toLogin(request):
  242. return render(request, "login.html")
  243. #刷新请求令牌access_token:客户端上传用户uid、login_token,
  244. # 2025/1/25
  245. # author Feng TODO------------不管accesstoken过没过期都给出一个新的返回
  246. # 如果login_token有效,返回新的access_token
  247. @csrf_exempt
  248. def get_access_token(request):
  249. try:
  250. # 获取参数
  251. # 获取请求参数
  252. params = aidog_request_tools.handle_post_request_parameters(request, ["user_id","access_token","login_token"])
  253. user_id,access_token,login_token = params["user_id"],params["access_token"],params["login_token"]
  254. if not user_id or not access_token or not login_token:
  255. raise ValueError("Missing required parameters")
  256. # 验证旧的login_token是否有效
  257. try:
  258. decoded_token = jwt.decode(login_token, SECRET_KEY, algorithms=['HS256'])
  259. # decoded_expired_token = jwt.decode(access_token, SECRET_KEY, algorithms=['HS256'])
  260. user_id = decoded_token['user_id']
  261. # if decoded_expired_token['user_id']!=user_id:
  262. # return JsonResponse({
  263. # "status": "error",
  264. # "code": 400,
  265. # "message": "Wrong match, please check params"
  266. # })
  267. # 取出数据库的uid:
  268. try:
  269. user = User.objects.get(uid=user_id)
  270. if user_id!=user.uid:
  271. return JsonResponse({
  272. "status": "error",
  273. "message": "user_id does not match the user associated with the login_token"
  274. })
  275. except User.DoesNotExist:
  276. return {"status": "error", "message": f"No user found with uid={user_id}"}
  277. except jwt.ExpiredSignatureError:
  278. # 旧token已过期,返回失败信息
  279. return JsonResponse({
  280. "status": "error",
  281. "code": 400,
  282. "message": "Old login_token expired, please login again"
  283. })
  284. # 生成新的access_token
  285. # 存储token
  286. # 生成新access_token
  287. new_access_token = generate_access_token(user_id)
  288. try:
  289. user_login_token =User.objects.get(uid=user_id)
  290. user_login_token.access_token = new_access_token
  291. user_login_token.save()
  292. except Exception as e:
  293. print(f"Error: {e}")
  294. return JsonResponse({"status": "error", "message": str(e)}, status=500)
  295. return JsonResponse({
  296. "status": "success",
  297. "code": 200,
  298. "message": "New access_token generated successfully",
  299. "access_token": new_access_token,
  300. })
  301. except Exception as e:
  302. import traceback
  303. traceback.print_exc()
  304. return JsonResponse({"status": "error", "message": str(e)}, status=500)
  305. #Login UUID登录临时账户 POST方式
  306. # 使用UUID登录 请求参数:login_token、uuid
  307. # 返回格式:result、message、login_token
  308. # 2025-2-13 author Feng
  309. @csrf_exempt
  310. def login_quick_start(request):
  311. try:
  312. # 获取请求参数
  313. params = aidog_request_tools.handle_post_request_parameters(request, [ "UUID"])
  314. UUID =params["UUID"]
  315. if not UUID:
  316. raise ValueError("Invalid input parameters: UUID is empty")
  317. try:
  318. user = User.objects.get(uuid=UUID)
  319. user_id = user.uid
  320. user_name=user.mobile
  321. except User.DoesNotExist:
  322. # 创建一条用户数据
  323. # 请求注册接口
  324. isRegUser=0
  325. mobile_number=''.join(random.choices("0123456789", k=11))
  326. user_name = '用户'+str(mobile_number) # 设置临时用户的用户名
  327. random_password=''.join(random.choice(string.ascii_letters) for _ in range(6))
  328. # 根据UUID、手机号和密码注册并返回用户信息
  329. register_user = register.register_user(mobile_number, random_password,user_name,UUID,isRegUser)
  330. if register_user['code'] != 200:
  331. raise ValueError(register_user['msg'])
  332. user_id=register_user['msg']# 获取用户的uid
  333. # 如果注册成功,返回uid,uid不为空则创建声纹库
  334. # 1.创建声纹特征库 createGroup
  335. message_response = generalRequest.req_url(api_name='createGroup', APPId=APPId,
  336. APIKey=APIKey, APISecret=APISecret, file_path=file_path,
  337. featureId='',
  338. groupId=str(register_user['msg']))
  339. if message_response.get('code') == 0:
  340. # 声纹库创建成功,返回给前端注册结果
  341. res = {
  342. "status": "success",
  343. "message": message_response,
  344. "user_id": register_user['msg'],
  345. "end_time": datetime.now().strftime('%Y-%m-%d %H:%M:%S')
  346. }
  347. else:
  348. res = {
  349. "status": message_response['status'],
  350. "message": message_response,
  351. "end_time": datetime.now().strftime('%Y-%m-%d %H:%M:%S')
  352. }
  353. # 存储token
  354. # 生成login_token
  355. login_token = generate_login_token(user_id)
  356. # 生成access_token
  357. access_token = generate_access_token(user_id)
  358. try:
  359. user_login_token =User.objects.get(uid=user_id)
  360. user_login_token.login_token=login_token
  361. user_login_token.access_token = access_token
  362. user_login_token.save()
  363. except Exception as e:
  364. print(f"Error: {e}")
  365. return JsonResponse({"status": "error", "message": str(e)}, status=500)
  366. res = {
  367. "status": "success",
  368. "message": "Login successful!",
  369. "login_token": login_token,
  370. "user_id": user_id,
  371. "access_token": access_token,
  372. "user_name":user_name,
  373. }
  374. return JsonResponse(res)
  375. except Exception as e:
  376. import traceback
  377. traceback.print_exc()
  378. return JsonResponse({"status": "error", "message": str(e)}, status=500)
  379. #检查并发放每日首次登录奖励
  380. # 2025-5-28 author Feng
  381. def check_and_give_daily_login_reward(user_id):
  382. try:
  383. today = timezone.now().date()
  384. # 获取用户对象
  385. user = User.objects.get(uid=user_id)
  386. # 检查今天是否已经登录过
  387. if not hasattr(user, 'last_login_date') or user.last_login_date.date() != today:
  388. # 今天首次登录,发放100金币
  389. if hasattr(user, 'coin'):
  390. user.coin += 100
  391. else:
  392. # 更新coin金币
  393. user.coin = getattr(user, 'coin', 0) + 100
  394. # 更新最后登录日期
  395. user.last_login_date = today
  396. user.save()
  397. return True, 100 # 返回是否发放奖励和奖励金额
  398. return False, 0 # 今天已经登录过,不发放奖励
  399. except Exception as e:
  400. print(f"发放每日登录奖励时出错: {e}")
  401. return False, 0
  402. #Login Token登录 POST方式
  403. # 使用logintoken登录 请求参数:login_token、uuid
  404. # 返回格式:result、message、user_id、login_token、access_token
  405. # 2025-2-9 author Feng
  406. @csrf_exempt
  407. def login_by_token(request):
  408. try:
  409. # 获取请求参数
  410. params = aidog_request_tools.handle_post_request_parameters(request, ["login_token", "UUID"])
  411. login_token, UUID = params["login_token"], params["UUID"]
  412. if not login_token :
  413. raise ValueError("Invalid input parameters: login_token is empty")
  414. # 验证旧的login_token是否有效
  415. try:
  416. decoded_token = jwt.decode(login_token, SECRET_KEY, algorithms=['HS256'])
  417. user_id = decoded_token['user_id']
  418. print(user_id)
  419. # 判断数据库uid是否有效
  420. except jwt.ExpiredSignatureError:
  421. # 旧login_token已过期,返回失败信息
  422. return JsonResponse({
  423. "status": "error",
  424. "code": 400,
  425. "message": "login_token expired, please login again"
  426. })
  427. # 如果login_token有效,生成新的 login_Token,并返回user_id,login_Token,access_token
  428. # 取出数据库的uid:
  429. try:
  430. user = User.objects.get(uid=user_id)
  431. if user.isRegUser == 0:
  432. # 检查uuid是否匹配
  433. if user.uuid != UUID:
  434. return JsonResponse({
  435. "status": "error",
  436. "message": "UUID does not match the user associated with the login_token"
  437. })
  438. except User.DoesNotExist:
  439. return {"status": "error", "message": f"No user found with uid={user_id}"}
  440. # 检查并发放每日首次登录奖励
  441. reward_given, reward_amount = check_and_give_daily_login_reward(user_id)
  442. # 存储token
  443. # 生成新login_token
  444. login_token = generate_login_token(user_id)
  445. # 生成新access_token
  446. access_token = generate_access_token(user_id)
  447. try:
  448. user_login_token =User.objects.get(uid=user_id)
  449. user_login_token.login_token=login_token
  450. user_login_token.access_token = access_token
  451. user_login_token.save()
  452. except Exception as e:
  453. print(f"Error: {e}")
  454. return JsonResponse({"status": "error", "message": str(e)}, status=500)
  455. res = {
  456. "status": "success",
  457. "message": "Login successful!",
  458. "login_token": login_token,
  459. "user_id": user_id,
  460. "access_token": access_token,
  461. # "daily_reward": {
  462. # "given": reward_given,
  463. # "amount": reward_amount
  464. # }
  465. }
  466. return JsonResponse(res)
  467. except Exception as e:
  468. import traceback
  469. traceback.print_exc()
  470. return JsonResponse({"status": "error", "message": str(e)}, status=500)
  471. # return JsonResponse(res)
  472. @csrf_exempt
  473. def login(request):
  474. # mobile_number = '1234567890'
  475. # password = 'ypwd121'
  476. try:
  477. # 获取请求参数
  478. params = aidog_request_tools.handle_post_request_has_empty_parameters(request,
  479. ["mobile_number", "password",
  480. "email", "client_language"])
  481. mobile_number, password,email, client_language = params[
  482. "mobile_number"], params["password"],params["email"], params[
  483. "client_language"]
  484. # mobile_number = '445445455'
  485. # password = 'tetst121'
  486. # res = None
  487. date_now = datetime.strftime(datetime.today(), '%Y-%m-%d %H:%M:%S')
  488. # 判断参数输入是否为空
  489. if not client_language:
  490. raise ValueError("Invalid input parameters: client_language is empty")
  491. # 判断参数输入是否为空
  492. if client_language == "zh-cn":
  493. # 使用mobile_number登录
  494. if not mobile_number or not password :
  495. raise ValueError("Invalid input parameters: mobile_number or password or username is empty")
  496. else:
  497. # 使用Email登录
  498. if not email or not password:
  499. raise ValueError("Invalid input parameters: Email or password or username is empty")
  500. # 请求登录接口
  501. message_response = login_func.login_user(mobile_number,email, password,client_language)
  502. if message_response is None or message_response['code'] != 200 :
  503. raise ValueError('login failed!')
  504. # 如果登录成功,生成 login_Token,返回uid,login_Token,access_token
  505. uid = message_response['user_id'] # 假设返回数据中包含 uid
  506. # # 生成新的access_token
  507. # 检查并发放每日首次登录奖励
  508. reward_given, reward_amount = check_and_give_daily_login_reward(uid)
  509. # 存储token
  510. # 生成新login_token
  511. login_token = generate_login_token(uid)
  512. # 生成新access_token
  513. access_token = generate_access_token(uid)
  514. try:
  515. user_login_token =User.objects.get(uid=uid)
  516. user_login_token.login_token=login_token
  517. user_login_token.access_token = access_token
  518. user_login_token.save()
  519. except Exception as e:
  520. print(f"Error: {e}")
  521. return JsonResponse({"status": "error", "message": str(e)}, status=500)
  522. res = {
  523. "status": "success",
  524. "message": "Login successful!",
  525. "login_token": login_token,
  526. "user_id": uid,
  527. "access_token": access_token,
  528. # "daily_reward": {
  529. # "given": reward_given,
  530. # "amount": reward_amount
  531. # }
  532. # "dog_list": message_response['dog_list'],
  533. # "response_end_time": datetime.now().strftime('%Y-%m-%d %H:%M:%S')
  534. }
  535. print(res)
  536. return JsonResponse(res)
  537. except Exception as e:
  538. import traceback
  539. traceback.print_exc()
  540. return JsonResponse({"status": "error", "message": str(e)}, status=500)
  541. @csrf_exempt
  542. def toRegister(request):
  543. try:
  544. # 获取请求参数
  545. params = aidog_request_tools.handle_post_request_has_empty_parameters(request, ["UUID","mobile_number","email","password","access_token","user_name","user_id","client_language" ])
  546. UUID,mobile_number,email,password, access_token, user_name,user_id,client_language= params["UUID"],params["mobile_number"],params["email"],params["password"], params["access_token"],params["user_name"], params["user_id"], params["client_language"]
  547. # mobile_number = '445445455'
  548. # password = 'tetst121'
  549. print(f"Updated-----params------- UUID {UUID}, mobile_number: {mobile_number}, access_token: {access_token}, user_id: {user_id}")
  550. res = None
  551. date_now = datetime.strftime(datetime.today(), '%Y-%m-%d %H:%M:%S')
  552. isRegUser = 1
  553. # 判断参数输入是否为空
  554. if not client_language:
  555. raise ValueError("Invalid input parameters: client_language is empty")
  556. # 根据系统语言判断输入参数
  557. if client_language == "zh-cn":
  558. # 使用mobile_number登录
  559. if not mobile_number or not password or not user_name:
  560. raise ValueError("Invalid input parameters: mobile_number or password or username is empty")
  561. else:
  562. # 使用Email登录
  563. if not email or not password or not user_name:
  564. raise ValueError("Invalid input parameters: Email or password or username is empty")
  565. if not user_id:
  566. #全新用户首次注册
  567. # 请求注册接口
  568. if client_language == "en":
  569. # 使用Email注册
  570. register_user = register.register_user_email(email, password, user_name, '',
  571. isRegUser) # 正式注册后清空uuid
  572. # user.email = email
  573. else:
  574. # 使用mobile_number注册
  575. register_user = register.register_user(mobile_number, password, user_name, '', isRegUser)
  576. if register_user['code'] != 200:
  577. raise ValueError(register_user['msg'])
  578. # register_user = register.register_user(mobile_number, password,user_name,'', isRegUser)
  579. # if register_user['code'] != 200:
  580. # raise ValueError(register_user['msg'])
  581. # 如果注册成功,返回uid,uid不为空则创建声纹库
  582. # 1.创建声纹特征库 createGroup
  583. message_response = generalRequest.req_url(api_name='createGroup', APPId=APPId,
  584. APIKey=APIKey, APISecret=APISecret, file_path=file_path,
  585. featureId='',
  586. groupId=str(register_user['msg']))
  587. if message_response.get('code') == 0:
  588. # 声纹库创建成功,返回给前端注册结果
  589. res = {
  590. "status": "success",
  591. "message": message_response,
  592. "user_id": register_user['msg'],
  593. "end_time": datetime.now().strftime('%Y-%m-%d %H:%M:%S')
  594. }
  595. else:
  596. res = {
  597. "status": message_response['status'],
  598. "message": message_response,
  599. "end_time": datetime.now().strftime('%Y-%m-%d %H:%M:%S')
  600. }
  601. else:
  602. #临时用户注册为正式用户
  603. # 验证access_token是否有效
  604. try:
  605. decoded_token = jwt.decode(access_token, SECRET_KEY, algorithms=['HS256'])
  606. uid = decoded_token['user_id']
  607. if uid!=user_id:
  608. # access_token匹配,返回失败信息
  609. return JsonResponse({
  610. "status": "error",
  611. "code": 400,
  612. "message": "AccessToken doesn't match!"
  613. })
  614. # 判断数据库uid是否有效
  615. except jwt.ExpiredSignatureError:
  616. # 旧access_token已过期,返回失败信息
  617. return JsonResponse({
  618. "status": "error",
  619. "code": 400,
  620. "message": "AccessToken expired, please refresh!"
  621. })
  622. # 取出数据库的uid:
  623. try:
  624. user = User.objects.get(uid=user_id)
  625. if user.isRegUser==1:
  626. raise ValueError("You're already a regular user")
  627. # 检查email是否存在
  628. if email and User.objects.filter(email=email).exists():
  629. return JsonResponse({
  630. "status": "error",
  631. "code": 400,
  632. "message": "duplicated email"
  633. })
  634. # 检查手机号是否存在
  635. if mobile_number and User.objects.filter(mobile=mobile_number).exists():
  636. return JsonResponse({
  637. "status": "error",
  638. "code": 400,
  639. "message": "duplicated mobile phone"
  640. })
  641. # 哈希加密密码
  642. hashed_password = hashlib.sha256(password.encode()).hexdigest()
  643. user.mobile = mobile_number
  644. user.user_name = user_name
  645. user.email = email
  646. user.password=hashed_password
  647. user.uuid=''# 正式注册后清空uuid
  648. user.isRegUser=isRegUser # 更新用户状态为正式
  649. user.registration_time=datetime.now().strftime('%Y-%m-%d %H:%M:%S')
  650. user.save()
  651. # 新增:插入默认道具数据到 道具 表
  652. # default_items = [
  653. # {'item_id': 'food_00001'},
  654. # {'item_id': 'food_00002'},
  655. # {'item_id': 'food_00003'},
  656. # {'item_id': 'water_00001'},
  657. # {'item_id': 'water_00002'},
  658. # {'item_id': 'toy_00001'},
  659. # {'item_id': 'other_00001'},
  660. # {'item_id': 'other_00001'}
  661. # ]
  662. current_time = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
  663. # item_list = []
  664. # for item in default_items:
  665. # new_item = UserInventory(
  666. # owner_id=user_id,
  667. # item_id=item['item_id'],
  668. # # update_time=current_time
  669. # )
  670. # item_list.append(new_item)
  671. #
  672. # # 批量插入道具记录
  673. # UserInventory.objects.bulk_create(item_list)
  674. res = {
  675. "status": "success",
  676. "message": "Register success!",
  677. "user_id": user_id,
  678. "user_name": user_name,
  679. "mobile_number": mobile_number,
  680. "email": email,
  681. }
  682. except User.DoesNotExist:
  683. return {"status": "error", "message": f"No user found with uid={user_id}"}
  684. return JsonResponse(res)
  685. except Exception as e:
  686. import traceback
  687. traceback.print_exc()
  688. return JsonResponse({"status": "error", "message": str(e)}, status=500)
  689. #启动更新狗状态和用户金币数量:客户端上传用户id、dog_id
  690. # 2024/12/31
  691. # author Feng
  692. # type==1:启动更新 type==2:投喂更新 互动更新 type==3 :口令更新
  693. @csrf_exempt
  694. def toUpdatePuppyStatus(request):
  695. try:
  696. # 获取请求参数
  697. params = aidog_request_tools.handle_get_request_parameters(request, ["user_id", "dog_id"])
  698. user_id, dog_id = params["user_id"], params["dog_id"]
  699. # user_id='JTYNZP9O'
  700. # dog_id='043341045'
  701. # 获取当前时间,并确保它是 aware datetime
  702. time_now = timezone.make_aware(datetime.now())
  703. # 启动更新狗的状态
  704. update_response = puppyStateUpdate.update_dog_state(user_id, dog_id, time_now)
  705. # 检查更新结果
  706. # if update_response['code'] != 200:
  707. # raise ValueError(update_response['msg'])
  708. # 成功返回结果
  709. res = {
  710. "status": "success",
  711. "date": time_now.strftime('%Y-%m-%d %H:%M:%S'),
  712. "dog_status": update_response['dog_status'],
  713. "dog_body_attrs":update_response['dog_body_attrs'],
  714. "dog_relationship_personality":update_response['dog_relationship_personality'],
  715. "dog_training":update_response['dog_training'],
  716. }
  717. return JsonResponse(res)
  718. except Exception as e:
  719. return handle_error(str(e))
  720. # 初始化狗状态:客户端上传用户id、access_token、 dog_name、sex、breed、skin
  721. # 2024/12/31
  722. # author Feng
  723. # 初始化狗属性信息
  724. # 2025/6/13 新增:领取第二只狗扣费,首次领取免费
  725. @csrf_exempt
  726. def initialPuppy(request):
  727. try:
  728. # 获取请求参数uid,dog_name,sex,breed,birthday,skin,got_time
  729. params = aidog_request_tools.handle_post_request_parameters(request,
  730. ["access_token", "user_id", "dog_name", "sex",
  731. "breed", "skin"])
  732. access_token, uid, dog_name, sex, breed, skin = params["access_token"], params["user_id"], params["dog_name"], \
  733. params["sex"], \
  734. params["breed"], params["skin"]
  735. # 获取当前时间
  736. # time_now = datetime.now()
  737. # 获取当前时间,并确保它是 aware datetime
  738. time_now = timezone.make_aware(datetime.now())
  739. birthday = datetime.now() # 获取服务器当前时间作为出生日期
  740. if not access_token or not uid or not dog_name or not sex or not breed or not skin:
  741. raise ValueError("Invalid input parameters: parameter is empty")
  742. # 验证旧的access_token是否有效
  743. # 验证访问令牌
  744. token_validation = aidog_tools.validate_access_token(access_token)
  745. if isinstance(token_validation, JsonResponse):
  746. return token_validation
  747. user_id = token_validation['user_id']
  748. # 新增功能:检查用户已有狗的数量
  749. # 查询用户已有的狗的数量
  750. existing_dogs_count = Doginfo.objects.filter(owner_id=user_id).count()
  751. # 如果是第二条狗,需要检查金币并扣费
  752. if existing_dogs_count >= 1:
  753. # 查询用户信息
  754. try:
  755. user = User.objects.get(uid=user_id)
  756. except User.DoesNotExist:
  757. return JsonResponse({
  758. "status": "error",
  759. "code": 404,
  760. "message": "User not found"
  761. })
  762. # 第二条狗需要1000金币
  763. dog_price = 1000
  764. # 检查用户金币是否足够
  765. if user.coin < dog_price:
  766. return JsonResponse({
  767. "status": "error",
  768. "code": 402,
  769. "message": f"Insufficient coins. You need {dog_price} coins but only have {user.coin} coins."
  770. })
  771. # 使用数据库事务确保原子性操作
  772. with transaction.atomic():
  773. # 调用函数初始化狗狗
  774. initialPuppy_response = initialPuppyState.getAPuppy(uid, dog_name, sex, breed, birthday, skin, time_now)
  775. # 检查初始化结果
  776. if initialPuppy_response.get('code') != 200:
  777. raise ValueError(initialPuppy_response.get('message', 'Failed to initialize puppy'))
  778. # 扣除用户金币
  779. user.coin -= dog_price
  780. user.save()
  781. # 记录金币变化(可选,如果有金币变化记录表)
  782. # CoinTransaction.objects.create(
  783. # user_id=uid,
  784. # amount=-dog_price,
  785. # transaction_type='dog_purchase',
  786. # description=f'Purchase second dog: {dog_name}'
  787. # )
  788. else:
  789. # 用户名下没有狗时,初始化一条狗免费
  790. initialPuppy_response = initialPuppyState.getAPuppy(uid, dog_name, sex, breed, birthday, skin, time_now)
  791. # 检查初始化结果
  792. if initialPuppy_response.get('code') != 200:
  793. raise ValueError(initialPuppy_response.get('message', 'Failed to initialize puppy'))
  794. # 成功返回结果
  795. res = {
  796. "status": "success",
  797. "date": time_now.strftime('%Y-%m-%d %H:%M:%S'),
  798. "message_all": initialPuppy_response,
  799. "message": initialPuppy_response['message'],
  800. "is_first_dog": existing_dogs_count == 0,
  801. "coins_deducted": 1000 if existing_dogs_count >= 1 else 0,
  802. "end_time": time_now.strftime('%Y-%m-%d %H:%M:%S')
  803. }
  804. return JsonResponse(res)
  805. except Exception as e:
  806. return JsonResponse({"status": "error", "message": str(e)}, status=500)
  807. # 初始化狗状态:客户端上传用户id、access_token、 dog_name、sex、breed、skin
  808. # 2024/12/31
  809. # author Feng
  810. # 初始化狗属性信息
  811. # @csrf_exempt
  812. # def initialPuppy(request):
  813. # try:
  814. # # 获取请求参数uid,dog_name,sex,breed,birthday,skin,got_time
  815. # params = aidog_request_tools.handle_post_request_parameters(request, ["access_token","user_id", "dog_name", "sex", "breed","skin"])
  816. # access_token,uid, dog_name, sex,breed,skin = params["access_token"],params["user_id"], params["dog_name"], params["sex"], \
  817. # params["breed"],params["skin"]
  818. # # 获取当前时间
  819. # # time_now = datetime.now()
  820. # # 获取当前时间,并确保它是 aware datetime
  821. # time_now = timezone.make_aware(datetime.now())
  822. #
  823. # birthday=datetime.now()#获取服务器当前时间作为出生日期
  824. # if not access_token or not uid or not dog_name or not sex or not breed or not skin:
  825. # raise ValueError("Invalid input parameters: parameter is empty")
  826. #
  827. # # 验证旧的access_token是否有效
  828. # try:
  829. # decoded_token = jwt.decode(access_token, SECRET_KEY, algorithms=['HS256'])
  830. # user_id = decoded_token['user_id']
  831. # print(user_id)
  832. # # 判断数据库uid是否有效
  833. #
  834. # except jwt.ExpiredSignatureError:
  835. # # 旧access_token已过期,返回失败信息
  836. # return JsonResponse({
  837. # "status": "error",
  838. # "code": 400,
  839. # "message": "access_token expired, please refresh again"
  840. # })
  841. #
  842. # # 调用函数初始化狗狗
  843. # initialPuppy_response = initialPuppyState.getAPuppy(uid,dog_name,sex,breed,birthday,skin, time_now)
  844. #
  845. # # 检查初始化结果
  846. # # if initialPuppy_response['code'] != 200:
  847. # # raise ValueError(initialPuppy_response['msg'])
  848. #
  849. # # 成功返回结果
  850. # res = {
  851. # "status": "success",
  852. # "date": time_now.strftime('%Y-%m-%d %H:%M:%S'),
  853. # "message_all": initialPuppy_response,
  854. # "message": initialPuppy_response['message'],
  855. # "end_time": time_now.strftime('%Y-%m-%d %H:%M:%S')
  856. # }
  857. #
  858. # return JsonResponse(res)
  859. #
  860. #
  861. # except Exception as e:
  862. # return JsonResponse({"status": "error", "message": str(e)}, status=500)
  863. # 根据投喂交互更新狗状态:客户端上传用户id、dog_id
  864. # 2024/12/31
  865. # author Feng
  866. # 投喂更新 互动更新
  867. def interaction(request):
  868. try:
  869. # 获取请求参数
  870. params = aidog_request_tools.handle_post_request_parameters(request, ["user_id", "dog_id", "interaction_type"])
  871. user_id, dog_id, interaction_type = params["user_id"], params["dog_id"], params["interaction_type"]
  872. # 获取当前时间,并确保它是 aware datetime
  873. time_now = timezone.make_aware(datetime.now())
  874. # 口令更新
  875. # 更新狗的状态
  876. if interaction_type == "feedInteraction":
  877. # 投喂更新
  878. update_response = puppyStateUpdate.voice_gain_state(user_id, dog_id, time_now)
  879. elif interaction_type == "touchInteraction":
  880. # 抚摸交互更新
  881. update_response = puppyStateUpdate.voice_gain_state(user_id, dog_id, time_now)
  882. else:
  883. raise ValueError("Invalid type parameter")
  884. # 检查更新结果
  885. if update_response['code'] != 200:
  886. raise ValueError(update_response['msg'])
  887. # 成功返回结果
  888. res = {
  889. "status": "success",
  890. "date": time_now.strftime('%Y-%m-%d %H:%M:%S'),
  891. "message_all": update_response,
  892. "message": update_response['message'],
  893. "end_time": time_now.strftime('%Y-%m-%d %H:%M:%S')
  894. }
  895. return JsonResponse(res)
  896. except Exception as e:
  897. return handle_error(str(e))
  898. # 使用道具接口:客户端上传access_token,用户id、item_id,dog_list,date_time
  899. # 2025/03/12
  900. # author Feng
  901. # 使用道具后, 所有狗的数据全部更新
  902. @csrf_exempt
  903. def use_props(request):
  904. try:
  905. # 获取请求参数
  906. params = aidog_request_tools.handle_post_request_parameters(request,
  907. ["access_token", "user_id", "item_id", "dog_list", "date_time"])
  908. access_token, user_id, item_id, dog_list, interaction_type = params["access_token"], params["user_id"], params[
  909. "item_id"], params["dog_list"], params["date_time"]
  910. time_now = timezone.make_aware(datetime.now())
  911. # 处理dog_list参数 - 它可能是字符串形式的列表或JSON字符串
  912. # 验证旧的access_token是否有效
  913. try:
  914. decoded_token = jwt.decode(access_token, SECRET_KEY, algorithms=['HS256'])
  915. user_id = decoded_token['user_id']
  916. # 取出数据库的uid:
  917. try:
  918. user = User.objects.get(uid=user_id)
  919. except User.DoesNotExist:
  920. return {"status": "error", "message": f"No user found with uid={user_id}"}
  921. except jwt.ExpiredSignatureError:
  922. # 旧access_token已过期,返回失败信息
  923. return JsonResponse({
  924. "status": "error",
  925. "code": 400,
  926. "message": "access_token expired, please refresh again"
  927. })
  928. # 确保dog_list是列表类型
  929. # if not isinstance(dog_list, list):
  930. # dog_list = [dog_list]
  931. # 处理dog_list参数 - 它可能是字符串形式的列表或JSON字符串
  932. if isinstance(dog_list, str):
  933. try:
  934. # 尝试解析为JSON
  935. dog_list = json.loads(dog_list)
  936. except json.JSONDecodeError:
  937. try:
  938. # 如果不是有效的JSON,尝试使用字面量评估
  939. # 这种方法可以处理Python列表字符串表示
  940. import ast
  941. dog_list = ast.literal_eval(dog_list)
  942. except (SyntaxError, ValueError):
  943. # 如果仍然失败,保持原样
  944. pass
  945. # 在Doginfo表中过滤出dog_list中存在的d_id对应的数据
  946. dog_info_list = Doginfo.objects.filter(owner_id=user_id, d_id__in=dog_list)
  947. # 检查是否有找到狗
  948. if not dog_info_list.exists():
  949. # 尝试不使用owner_id过滤,仅检查是否存在这些dog_id
  950. all_dogs = Doginfo.objects.filter(d_id__in=dog_list)
  951. if all_dogs.exists():
  952. # 狗存在,但不属于这个用户
  953. wrong_owner_dogs = [dog.d_id for dog in all_dogs]
  954. return JsonResponse({
  955. "status": "error",
  956. "message": f"Dogs found but don't belong to user {user_id}: {wrong_owner_dogs}"
  957. })
  958. else:
  959. # 狗完全不存在
  960. return JsonResponse({
  961. "status": "error",
  962. "message": f"No dogs found with the provided IDs: {dog_list}"
  963. })
  964. # 获取用户道具库存
  965. try:
  966. user_inventory = UserInventory.objects.get(owner_id=user_id, item_id=item_id)
  967. # 检查用户是否有足够的道具数量
  968. # if user_inventory.quantity < len(dog_info_list):
  969. if user_inventory.quantity < 1:
  970. return JsonResponse({
  971. "status": "error",
  972. "message": f"Insufficient item quantity. Required: {1}, Available: {user_inventory.quantity}"
  973. })
  974. except UserInventory.DoesNotExist:
  975. return JsonResponse({
  976. "status": "error",
  977. "message": f"User doesn't have this item in inventory: {item_id}"
  978. })
  979. # 更新每只狗的状态
  980. # 获取用户所有的狗
  981. dog_all_list = Doginfo.objects.filter(owner_id=user_id)
  982. dogs = []
  983. successful_updates = 0
  984. # 提取需要更新的狗的ID列表
  985. dog_info_d_ids = [dog.d_id for dog in dog_info_list]
  986. # 遍历所有狗数据
  987. for dog in dog_all_list:
  988. dog_id = dog.d_id
  989. # 获取狗的信息并转换为字典
  990. dog_serialized = serializers.serialize('json', [dog])
  991. dog_data = json.loads(dog_serialized)[0]['fields']
  992. # 如果当前狗在需要更新的列表中,调用更新接口
  993. if dog_id in dog_info_d_ids:
  994. update_response = puppyStateUpdate.props_gain_state(user_id, dog_id, item_id, time_now)
  995. if update_response["status"] == "error":
  996. # 如果更新某只狗时出错,记录错误但继续处理其他狗
  997. pass
  998. else:
  999. successful_updates += 1
  1000. # 获取狗的相关信息(无论是否更新,都获取最新状态)
  1001. new_dog_status = aidog_tools.model_to_dict_without_id(DogStatus.objects.filter(d_id=dog_id).first())
  1002. new_dog_training = aidog_tools.model_to_dict_without_id(DogTraining.objects.filter(d_id=dog_id).first())
  1003. new_dog_body_attributes = aidog_tools.model_to_dict_without_id(
  1004. DogBodyAttributes.objects.filter(d_id=dog_id).first())
  1005. new_dog_personality_relationship = aidog_tools.model_to_dict_without_id(
  1006. DogPersonalityRelationship.objects.filter(d_id=dog_id).first())
  1007. # 合并所有相关信息
  1008. dog_info_combined = {
  1009. **dog_data,
  1010. **new_dog_status,
  1011. **new_dog_training,
  1012. **new_dog_body_attributes,
  1013. **new_dog_personality_relationship,
  1014. }
  1015. # 只保留字段而不是数据库内部的元数据(如 '_state')
  1016. dog_info_clean = {key: value for key, value in dog_info_combined.items() if not key.startswith('_')}
  1017. dogs.append(dog_info_clean)
  1018. # 更新道具数量 (只扣除成功更新的狗的数量)
  1019. if successful_updates > 0 :
  1020. # user_inventory.quantity -= successful_updates #---todo==========按狗的数量扣除多个道具
  1021. if not item_id.startswith('toy_'):
  1022. user_inventory.quantity -= 1 #---todo==========无论几只狗每次只扣除一个道具
  1023. # if user_inventory.quantity <= 0:
  1024. # 如果道具数量为0或负数,删除库存记录
  1025. # user_inventory.delete()
  1026. # else:
  1027. user_inventory.save()
  1028. # 获取用户所有道具库存
  1029. user_inventory_all = UserInventory.objects.filter(owner_id=user_id)
  1030. props_dict = {
  1031. "food": {},
  1032. "toy": {},
  1033. "other": {}
  1034. }
  1035. for prop in user_inventory_all:
  1036. prop_serialized = serializers.serialize('json', [prop])
  1037. prop_data = json.loads(prop_serialized)[0]['fields']
  1038. # Determine the category based on item_id prefix
  1039. if prop_data['item_id'].startswith('food_') or prop_data['item_id'].startswith('water_'):
  1040. category = 'food'
  1041. elif prop_data['item_id'].startswith('toy_'):
  1042. category = 'toy'
  1043. else:
  1044. category = 'other'
  1045. # Add to the corresponding category dictionary
  1046. props_dict[category][prop_data['item_id']] = prop_data['quantity']
  1047. # 处理isRegUser的布尔值转换
  1048. isRegUser = True if getattr(user, 'isRegUser', 0) == 1 else False
  1049. # 成功返回结果
  1050. res = {
  1051. "status": "success",
  1052. "message": f"item:{str(item_id)} is used",
  1053. "user_info": {
  1054. "user_name": user.user_name,
  1055. "coin": user.coin,
  1056. "isRegUser": isRegUser,
  1057. "mobile": user.mobile,
  1058. "email": user.email,
  1059. "level": user.level,
  1060. "uuid": user.uuid,
  1061. "registration_time": user.registration_time
  1062. },
  1063. "status": "success",
  1064. "dogs":dogs,
  1065. "props": props_dict,
  1066. }
  1067. return JsonResponse(res)
  1068. except Exception as e:
  1069. return handle_error(str(e))