最新版本

This commit is contained in:
root 2024-09-23 09:56:57 +00:00
parent 0fca263911
commit 3f369584fb
78 changed files with 43666 additions and 43305 deletions

4
--ini Executable file
View File

@ -0,0 +1,4 @@
unable to find logger stdout
unable to find logger stdout
unable to find logger stdout
unable to find logger stdout

7634
API日志.log Executable file → Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1 +0,0 @@
2024-09-04 13:54:21,364 - API日志 - INFO - {'frameRate': 60, 'resolution': '720p', 'frameDurationMultiplier': 18, 'webhook': 'https://www.typeframes.cc/api/webhook/?userid=10&videoid=1725429259_10', 'creationParams': {'mediaType': 'stockVideo', 'origin': '/create', 'inputText': '宇宙的故事始于138亿年前的一场大爆炸从这一点爆发出无尽的能量和物质逐渐形成了今天我们所见的银河系、恒星和行星。在这一过程中重力将物质聚集成团恒星点燃行星诞生生命在地球上萌芽。然而这一壮丽的宇宙图景可能终将走向衰亡', 'flowType': 'text-to-video', 'slug': 'create-tiktok-video', 'disableCaptions': True, 'hasToGenerateVoice': False, 'hasToTranscript': False, 'hasToSearchMedia': True, 'hasAvatar': False, 'hasWebsiteRecorder': False, 'hasTextSmallAtBottom': False, 'captionPresetName': 'Wrap 1', 'captionPositionName': 'bottom', 'disableAudio': True, 'ratio': '16 / 9', 'selectedAudio': 'Bladerunner 2049', 'selectedVoice': 'zh-CN-YunxiNeural', 'sourceType': 'contentScraping', 'selectedStoryStyle': {'value': 'custom', 'label': 'Custom'}, 'hasToGenerateVideos': False, 'selectedRecording': 'https://www.typeframes.cc/media/63508bd2-3d2a-418b-900b-4de3457f243c.mp3', 'selectedRecordingType': 'audio', 'generationPreset': 'LEONARDO', 'audioUrl': 'https://cdn.tfrv.xyz/audio/_bladerunner-2049.mp3'}}

164
API日志.log.2024-09-20 Normal file
View File

@ -0,0 +1,164 @@
2024-09-21 14:02:29,146 - API日志 - INFO - [支付执行] 获取的访问令牌: A21AAIVwWsRmSYRX_McyZN1RISbr4rs-amzjrc5R8H2rYRMZfH_Ia3QNs4HvEFVKxK2VAEMVe2dWfciYCJ5yhzGlbJgMBDuYQ
2024-09-21 14:02:50,451 - API日志 - INFO - [支付执行] 接收到来自前端的 POST 请求,开始处理支付...
2024-09-21 14:02:50,452 - API日志 - INFO - [支付执行] 请求内容: paymentId=PAYID-M3XGC5I9U46968696522382D, PayerID=8RSF8T3UK8NT2
2024-09-21 14:02:50,454 - API日志 - INFO - [支付执行] 获取到的订单信息: Order PAYID-M3XGC5I9U46968696522382D - pending
2024-09-21 14:02:50,527 - API日志 - INFO - [支付执行] 获取的访问令牌: A21AAIVwWsRmSYRX_McyZN1RISbr4rs-amzjrc5R8H2rYRMZfH_Ia3QNs4HvEFVKxK2VAEMVe2dWfciYCJ5yhzGlbJgMBDuYQ
2024-09-21 14:02:50,527 - API日志 - INFO - [支付执行] 获取到的 PayPal 访问令牌: A21AAIVwWsRmSYRX_McyZN1RISbr4rs-amzjrc5R8H2rYRMZfH_Ia3QNs4HvEFVKxK2VAEMVe2dWfciYCJ5yhzGlbJgMBDuYQ
2024-09-21 14:02:50,528 - API日志 - INFO - [支付执行] 发送支付请求URL: https://api.sandbox.paypal.com/v1/payments/payment/PAYID-M3XGC5I9U46968696522382D/execute, 请求头: {'Content-Type': 'application/json', 'Authorization': 'Bearer A21AAIVwWsRmSYRX_McyZN1RISbr4rs-amzjrc5R8H2rYRMZfH_Ia3QNs4HvEFVKxK2VAEMVe2dWfciYCJ5yhzGlbJgMBDuYQ'}, 请求体: {'payer_id': '8RSF8T3UK8NT2'}
2024-09-21 14:02:51,294 - API日志 - INFO - [支付执行] PayPal API 响应状态码: 200
2024-09-21 14:02:51,295 - API日志 - INFO - [支付执行] PayPal API 响应内容: {'id': 'PAYID-M3XGC5I9U46968696522382D', 'intent': 'sale', 'state': 'approved', 'cart': '2Y943631F86154047', 'payer': {'payment_method': 'paypal', 'status': 'VERIFIED', 'payer_info': {'email': 'sb-pztpq32086919@personal.example.com', 'first_name': 'John', 'last_name': 'Doe', 'payer_id': '8RSF8T3UK8NT2', 'shipping_address': {'recipient_name': 'Doe John', 'line1': 'NO 1 Nan Jin Road', 'city': 'Shanghai', 'state': 'Shanghai', 'postal_code': '200000', 'country_code': 'C2'}, 'country_code': 'C2'}}, 'transactions': [{'amount': {'total': '1.00', 'currency': 'USD', 'details': {'subtotal': '1.00', 'shipping': '0.00', 'insurance': '0.00', 'handling_fee': '0.00', 'shipping_discount': '0.00', 'discount': '0.00'}}, 'payee': {'merchant_id': 'AQJTM59Z4T3EG', 'email': 'sb-05ob032098751@business.example.com'}, 'description': '购买 Hobby 计划', 'item_list': {'items': [{'name': 'Hobby', 'sku': '1', 'price': '1.00', 'currency': 'USD', 'tax': '0.00', 'quantity': 1, 'image_url': ''}], 'shipping_address': {'recipient_name': 'Doe John', 'line1': 'NO 1 Nan Jin Road', 'city': 'Shanghai', 'state': 'Shanghai', 'postal_code': '200000', 'country_code': 'C2'}}, 'related_resources': [{'sale': {'id': '40C15537SF235414R', 'state': 'completed', 'amount': {'total': '1.00', 'currency': 'USD', 'details': {'subtotal': '1.00', 'shipping': '0.00', 'insurance': '0.00', 'handling_fee': '0.00', 'shipping_discount': '0.00', 'discount': '0.00'}}, 'payment_mode': 'INSTANT_TRANSFER', 'protection_eligibility': 'ELIGIBLE', 'protection_eligibility_type': 'ITEM_NOT_RECEIVED_ELIGIBLE,UNAUTHORIZED_PAYMENT_ELIGIBLE', 'transaction_fee': {'value': '0.33', 'currency': 'USD'}, 'parent_payment': 'PAYID-M3XGC5I9U46968696522382D', 'create_time': '2024-09-21T06:02:50Z', 'update_time': '2024-09-21T06:02:50Z', 'links': [{'href': 'https://api.sandbox.paypal.com/v1/payments/sale/40C15537SF235414R', 'rel': 'self', 'method': 'GET'}, {'href': 'https://api.sandbox.paypal.com/v1/payments/sale/40C15537SF235414R/refund', 'rel': 'refund', 'method': 'POST'}, {'href': 'https://api.sandbox.paypal.com/v1/payments/payment/PAYID-M3XGC5I9U46968696522382D', 'rel': 'parent_payment', 'method': 'GET'}]}}]}], 'failed_transactions': [], 'create_time': '2024-09-21T06:02:29Z', 'update_time': '2024-09-21T06:02:50Z', 'links': [{'href': 'https://api.sandbox.paypal.com/v1/payments/payment/PAYID-M3XGC5I9U46968696522382D', 'rel': 'self', 'method': 'GET'}]}
2024-09-21 14:02:51,295 - API日志 - INFO - [支付执行] 支付成功,订单状态更新为 'approved'
2024-09-21 14:02:51,352 - API日志 - INFO - [支付执行] 用户 19978615506 当前积分: 50
2024-09-21 14:02:51,352 - API日志 - ERROR - [支付执行] 支付执行过程中发生异常: 'Plan' object has no attribute 'name'
2024-09-21 14:03:02,480 - API日志 - INFO - 接收到 PayPal Webhook 请求...
2024-09-21 14:03:02,481 - API日志 - INFO - 验证 PayPal Webhook 签名...
2024-09-21 14:03:02,661 - API日志 - INFO - 获取的访问令牌: A21AAIVwWsRmSYRX_McyZN1RISbr4rs-amzjrc5R8H2rYRMZfH_Ia3QNs4HvEFVKxK2VAEMVe2dWfciYCJ5yhzGlbJgMBDuYQ
2024-09-21 14:03:02,784 - API日志 - INFO - Webhook 签名验证成功
2024-09-21 14:03:02,784 - API日志 - INFO - 接收到 PayPal Webhook 事件: PAYMENTS.PAYMENT.CREATED
2024-09-21 14:03:02,785 - API日志 - INFO - Webhook payload: {
"id": "WH-53X19961TT501671H-9G343651RY447041V",
"event_version": "1.0",
"create_time": "2024-09-21T06:02:53.663Z",
"resource_type": "payment",
"event_type": "PAYMENTS.PAYMENT.CREATED",
"summary": "Checkout payment is created and approved by buyer",
"resource": {
"update_time": "2024-09-21T06:02:50Z",
"create_time": "2024-09-21T06:02:29Z",
"links": [
{
"href": "https://api.sandbox.paypal.com/v1/payments/payment/PAYID-M3XGC5I9U46968696522382D",
"rel": "self",
"method": "GET"
}
],
"id": "PAYID-M3XGC5I9U46968696522382D",
"state": "approved",
"transactions": [
{
"amount": {
"total": "1.00",
"currency": "USD",
"details": {
"subtotal": "1.00",
"shipping": "0.00",
"insurance": "0.00",
"handling_fee": "0.00",
"shipping_discount": "0.00",
"discount": "0.00"
}
},
"payee": {
"merchant_id": "AQJTM59Z4T3EG",
"email": "sb-05ob032098751@business.example.com"
},
"description": "\u8d2d\u4e70 Hobby \u8ba1\u5212",
"item_list": {
"items": [
{
"name": "Hobby",
"sku": "1",
"price": "1.00",
"currency": "USD",
"tax": "0.00",
"quantity": 1,
"image_url": ""
}
],
"shipping_address": {
"recipient_name": "John Doe",
"line1": "NO 1 Nan Jin Road",
"city": "Shanghai",
"state": "Shanghai",
"postal_code": "200000",
"country_code": "C2"
}
},
"related_resources": [
{
"sale": {
"id": "40C15537SF235414R",
"state": "completed",
"amount": {
"total": "1.00",
"currency": "USD",
"details": {
"subtotal": "1.00",
"shipping": "0.00",
"insurance": "0.00",
"handling_fee": "0.00",
"shipping_discount": "0.00",
"discount": "0.00"
}
},
"payment_mode": "INSTANT_TRANSFER",
"protection_eligibility": "ELIGIBLE",
"protection_eligibility_type": "ITEM_NOT_RECEIVED_ELIGIBLE,UNAUTHORIZED_PAYMENT_ELIGIBLE",
"transaction_fee": {
"value": "0.33",
"currency": "USD"
},
"parent_payment": "PAYID-M3XGC5I9U46968696522382D",
"create_time": "2024-09-21T06:02:50Z",
"update_time": "2024-09-21T06:02:50Z",
"links": [
{
"href": "https://api.sandbox.paypal.com/v1/payments/sale/40C15537SF235414R",
"rel": "self",
"method": "GET"
},
{
"href": "https://api.sandbox.paypal.com/v1/payments/sale/40C15537SF235414R/refund",
"rel": "refund",
"method": "POST"
},
{
"href": "https://api.sandbox.paypal.com/v1/payments/payment/PAYID-M3XGC5I9U46968696522382D",
"rel": "parent_payment",
"method": "GET"
}
]
}
}
]
}
],
"intent": "sale",
"payer": {
"payment_method": "paypal",
"status": "VERIFIED",
"payer_info": {
"email": "sb-pztpq32086919@personal.example.com",
"first_name": "John",
"last_name": "Doe",
"payer_id": "8RSF8T3UK8NT2",
"shipping_address": {
"recipient_name": "John Doe",
"line1": "NO 1 Nan Jin Road",
"city": "Shanghai",
"state": "Shanghai",
"postal_code": "200000",
"country_code": "C2"
},
"phone": "2192589204",
"country_code": "C2"
}
},
"cart": "2Y943631F86154047"
},
"links": [
{
"href": "https://api.sandbox.paypal.com/v1/notifications/webhooks-events/WH-53X19961TT501671H-9G343651RY447041V",
"rel": "self",
"method": "GET"
},
{
"href": "https://api.sandbox.paypal.com/v1/notifications/webhooks-events/WH-53X19961TT501671H-9G343651RY447041V/resend",
"rel": "resend",
"method": "POST"
}
]
}
2024-09-21 14:03:02,785 - API日志 - INFO - 回调接收到 开始执行支付订单ID: PAYID-M3XGC5I9U46968696522382D, 付款人ID: 8RSF8T3UK8NT2
2024-09-21 14:03:02,795 - API日志 - INFO - 订单 PAYID-M3XGC5I9U46968696522382D 已经支付,不需要再次执行支付
2024-09-21 14:06:05,605 - API日志 - INFO - [支付执行] 获取的访问令牌: A21AAIVwWsRmSYRX_McyZN1RISbr4rs-amzjrc5R8H2rYRMZfH_Ia3QNs4HvEFVKxK2VAEMVe2dWfciYCJ5yhzGlbJgMBDuYQ

7
API日志.log.2024-09-21 Normal file
View File

@ -0,0 +1,7 @@
2024-09-22 18:04:02,758 - API日志 - INFO - [支付执行] 获取的访问令牌: A21AAMX8udSqwN2hgx455qnPAztVrGR8JEIEml8vS52RV_fA0EhIk78KooWj4TccndnZ2M7RFuVn8fnxikBQF8Qhmy7giu35w
2024-09-22 18:09:52,408 - API日志 - INFO - [支付执行] 获取的访问令牌: A21AAMX8udSqwN2hgx455qnPAztVrGR8JEIEml8vS52RV_fA0EhIk78KooWj4TccndnZ2M7RFuVn8fnxikBQF8Qhmy7giu35w
2024-09-22 18:18:20,687 - API日志 - INFO - 接收到 PayPal Webhook 请求...
2024-09-22 18:18:20,688 - API日志 - INFO - 验证 PayPal Webhook 签名...
2024-09-22 18:18:20,768 - API日志 - INFO - 获取的访问令牌: A21AAMX8udSqwN2hgx455qnPAztVrGR8JEIEml8vS52RV_fA0EhIk78KooWj4TccndnZ2M7RFuVn8fnxikBQF8Qhmy7giu35w
2024-09-22 18:18:20,943 - API日志 - ERROR - Webhook 签名验证失败: {"verification_status":"FAILURE"}
2024-09-22 18:18:20,944 - API日志 - ERROR - Webhook 签名验证失败

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -239,27 +239,24 @@ def update_user_membership(order):
更新用户积分信息
"""
try:
# 验证订单状态是否为成功
if order.status not in ("completed", "TRADE_SUCCESS", "TRADE_FINISHED"):
print("订单未成功")
# 如果订单已经是 'completed' 状态,说明已经处理过,跳过处理
if order.status == 'completed':
print("订单已处理,无需再次更新")
return False
# 从订单中获取关联的套餐信息
# 获取套餐信息
plan = order.plan
# 检查汇率是否有效
# 获取美元对人民币的汇率
usd_to_cny_rate = get_usd_to_cny_rate()
if not usd_to_cny_rate:
print("无法进行价格转换,汇率不可用")
return False
# 将订单金额从美元转换回人民币
order_amount_cny = order.amount
# 确保订单的套餐与实际套餐详情匹配
if not plan or convert_cny_to_usd(plan.price) != order_amount_cny:
print(f"订单的套餐信息与实际套餐不匹配plan.price{plan.price}---")
if not plan or convert_cny_to_usd(plan.price) != order.amount:
print(f"订单的套餐信息与实际套餐不匹配convert_cny_to_usd(plan.price){convert_cny_to_usd(plan.price)}--order_amount_cny{order.amount}")
return False
# 获取用户信息
@ -269,13 +266,18 @@ def update_user_membership(order):
user.points += plan.credits_per_month
user.save()
print(f"用户 {user.username} 的积分已更新")
# 更新订单状态为 'completed'
order.status = 'completed'
order.save()
print(f"用户 {user.username} 的积分已更新--增加{plan.credits_per_month}--现在{user.points}")
return True
except Exception as e:
print(f"更新用户积分信息时出错: {e}")
return False
@csrf_exempt
def alipay_notify(request):
"""
@ -285,7 +287,7 @@ def alipay_notify(request):
data = request.POST.dict()
print(f"接收到的异步通知数据: {data}")
# 直接使用返回的数据处理逻辑
# 获取订单ID和交易状态
order_id = data.get('out_trade_no')
trade_status = data.get('trade_status')
print(f"订单ID: {order_id}, 支付状态: {trade_status}")
@ -296,9 +298,13 @@ def alipay_notify(request):
print(f"订单 {order_id} 不存在")
return JsonResponse({"code": 400, "message": "订单不存在"})
# 如果订单状态已经是 'completed',表示已经处理过,无需再次处理
if order.status == 'completed':
print(f"订单 {order_id} 已处理,无需再次更新")
return JsonResponse({"code": 200, "message": "订单已处理"})
# 如果支付成功或交易完成,更新订单状态并处理会员更新
if trade_status in ("TRADE_SUCCESS", "TRADE_FINISHED"):
order.status = 'completed'
order.save()
print(f"订单 {order_id} 支付成功")
update_user_membership(order)
return JsonResponse({"code": 200, "message": "支付成功"})

View File

@ -270,8 +270,6 @@ def webhook(request):
if not data:
return HttpResponse(status=400) # Bad Request
# 记录完整的接收到的数据
logger.info("Received complete callback data:\n%s\n", json.dumps(data, indent=4))
# 提取基本信息
video_url = data.get('videoUrl', '') # 编辑视频 URL
@ -316,8 +314,6 @@ def webhook(request):
else:
return HttpResponse(status=405) # Method Not Allowed
#获取视频列表
@csrf_exempt
@require_http_methods(["GET"])
@login_required
@ -328,26 +324,30 @@ def get_video_list(request):
try:
user = request.user
# 检查是否有用户ID参数
user_id = request.GET.get('user_id', None)
# 获取分页参数
page = request.GET.get('page', 1)
page_size = request.GET.get('page_size', 10)
# 如果有user_id参数并且当前用户是管理员则获取该用户的视频列表
if user_id and user.is_staff:
# 检查是否有user_id参数并且当前用户是管理员
user_id = request.GET.get('user_id', None)
if user.is_staff:
# 管理员可以查看指定用户的视频列表,或查看所有用户视频列表
if user_id:
try:
specific_user = User.objects.get(id=user_id)
video_list = VideoGeneration.objects.filter(user=specific_user).order_by('-created_at')
except ObjectDoesNotExist:
return JsonResponse({'code': 404, 'message': '用户不存在'}, status=404)
# 如果没有user_id参数或者当前用户不是管理员则获取当前用户的视频列表
elif not user.is_staff:
video_list = VideoGeneration.objects.filter(user=user).order_by('-created_at')
print(f"管理员查询用户 {specific_user.username} 的视频列表")
except User.DoesNotExist:
return JsonResponse({'code': 404, 'message': '用户不存在', 'data': {}}, status=404)
else:
# 管理员返回所有记录
# 没有指定用户ID管理员查询所有用户的视频列表
video_list = VideoGeneration.objects.all().order_by('-created_at')
print("管理员查询所有用户的视频列表")
else:
# 普通用户只能查看自己的视频列表,忽略传入的 user_id 参数
video_list = VideoGeneration.objects.filter(user=user).order_by('-created_at')
print(f"普通用户 {user.username} 查询自己的视频列表")
# 使用Paginator进行分页
paginator = Paginator(video_list, page_size)
@ -355,10 +355,12 @@ def get_video_list(request):
try:
videos = paginator.page(page)
except PageNotAnInteger:
videos = paginator.page(1)
videos = paginator.page(1) # 如果页码不是整数,返回第一页
except EmptyPage:
videos = paginator.page(paginator.num_pages)
# 如果页码超出范围,返回空列表
return JsonResponse({'code': 200, 'message': '没有更多数据', 'data': {'list': [], 'page': page, 'page_size': page_size, 'total_pages': paginator.num_pages, 'total_videos': paginator.count}}, status=200)
# 组织视频数据
video_data = []
for video in videos:
video_data.append({
@ -374,24 +376,30 @@ def get_video_list(request):
'status': video.status,
'created_at': video.created_at,
'updated_at': video.updated_at,
'pid':video.pid,
'video_id':video.video_id,
'pid': video.pid,
'video_id': video.video_id,
'slug': video.slug,
})
# 响应数据
response_data = {
'code': 200,
'data': {"list":video_data,'page': videos.number,
'message': '成功获取视频列表',
'data': {
'list': video_data,
'page': videos.number,
'page_size': paginator.per_page,
'total_pages': paginator.num_pages,
'total_videos': paginator.count}
'total_videos': paginator.count
}
}
return JsonResponse(response_data)
return JsonResponse(response_data, status=200)
except Exception as e:
logger.error(f"Error fetching video list: {str(e)}")
return JsonResponse({"code": 500, "message": str(e)}, status=500)
return JsonResponse({"code": 500, "message": f"服务器错误: {str(e)}", "data": {}}, status=500)
@require_http_methods(["GET"])
def get_plans(request):

View File

@ -5,6 +5,12 @@ from django.http import JsonResponse
from .models import VideoGeneration
from django.views.decorators.csrf import csrf_exempt
from .base import logger,deduct_points
import http.client
import random
import urllib
import hashlib
from langdetect import detect
from langdetect.lang_detect_exception import LangDetectException
def generate_video_id(user_id):
"""
根据用户ID和当前时间戳生成唯一的视频ID
@ -14,6 +20,37 @@ def generate_video_id(user_id):
print(f"生成的视频ID: {video_id}")
return video_id
appid = '20240601002067404' # 填写你的appid
secretKey = '6pRZ9HCSqGuMqzLO55hB' # 填写你的密钥
def translate(text, from_lang='auto', to_lang='en'):
myurl = '/api/trans/vip/translate'
salt = random.randint(32768, 65536)
sign = appid + text + str(salt) + secretKey
sign = hashlib.md5(sign.encode()).hexdigest()
myurl = (myurl + '?appid=' + appid + '&q=' + urllib.parse.quote(text) +
'&from=' + from_lang + '&to=' + to_lang + '&salt=' + str(salt) +
'&sign=' + sign)
try:
httpClient = http.client.HTTPConnection('api.fanyi.baidu.com')
httpClient.request('GET', myurl)
# response是HTTPResponse对象
response = httpClient.getresponse()
result_all = response.read().decode("utf-8")
result = json.loads(result_all)
print(f'请求结果{result}')
return result['trans_result'][0]['dst']
except Exception as e:
return str(e)
finally:
if httpClient:
httpClient.close()
def get_dimensions(model, width=None, height=None):
"""
根据模型返回相应的宽高分辨率:
@ -40,6 +77,8 @@ def get_headers():
"Authorization": "12e76710fad2047db8c0cc6b25987e2a2" # 替换为你的真实授权密钥
}
@csrf_exempt
def text_to_video(request):
"""
@ -51,9 +90,22 @@ def text_to_video(request):
return JsonResponse({'code': 401, 'message': '用户未登录'})
user = request.user
data = json.loads(request.body)
text_prompt = data.get('text_prompt')
print(f'文生视频原内容---{text_prompt}')
# 判断是否需要翻译
try:
language = detect(text_prompt)
print(f"检测到的语言: {language}")
if language == 'en':
description = text_prompt # 英文无需翻译
else:
description = translate(text_prompt, 'auto', 'en') # 翻译成英文
print(f'文生视频翻译内容---{description}')
except LangDetectException:
return JsonResponse({'code': 400, 'message': '无法检测语言,请输入有效文本'})
# 获取参数
text_prompt = data.get('text_prompt')
style = data.get('style', '') # 选择的风格,默认是 'general'
model = data.get('model', 'gen3') # 选择模型,默认是 'gen3'
time_duration = int(data.get('time', 5)) # 视频时长
@ -82,14 +134,14 @@ def text_to_video(request):
# 准备POST请求数据
payload = {
"text_prompt": f"{text_prompt}. Style: {style}",
"text_prompt": f"{description}. Style: {style}",
"model": model,
"width": width,
"height": height,
"motion": motion, # 视频画面丰富度
"seed": 0,
"upscale": False,
"interpolate": False,
"upscale": True,
"interpolate": True,
"callback_url": "https://www.typeframes.ai/api/callback/",
"time": time_duration # 视频时长
}
@ -139,6 +191,9 @@ def text_to_video(request):
@csrf_exempt
def image_to_video(request):
"""
@ -153,6 +208,20 @@ def image_to_video(request):
# 获取参数
text_prompt = data.get('text_prompt')
print(f' 图片生视频原内容---{text_prompt}')
# 判断是否需要翻译
try:
language = detect(text_prompt)
print(f"检测到的语言: {language}")
if language == 'en':
description = text_prompt # 英文无需翻译
else:
description = translate(text_prompt, 'auto', 'en') # 翻译成英文
print(f'图片生视翻译内容---{description}')
except LangDetectException:
return JsonResponse({'code': 400, 'message': '无法检测语言,请输入有效文本'})
image_url = data.get('image_url')
model = data.get('model', 'gen3') # 选择模型,默认是 'gen3'
time_duration = int(data.get('time', 5)) # 视频时长
@ -175,14 +244,14 @@ def image_to_video(request):
# 准备POST请求数据宽高不需要传入图片自适应
payload = {
"text_prompt": text_prompt,
"text_prompt": description,
"model": model,
"img_prompt": image_url,
"image_as_end_frame": False, # 图片不作为最后一帧
"motion": motion, # 视频丰富度
"seed": 0,
"upscale": False,
"interpolate": False,
"upscale": True,
"interpolate": True,
"callback_url": "https://www.typeframes.ai/api/callback/",
"time": time_duration # 视频时长
}
@ -246,10 +315,10 @@ def extend_video(request):
return JsonResponse({'code': 401, 'message': '用户未登录'})
user = request.user
data = json.loads(request.body)
print(data)
# 获取参数
pid = data.get('pid')
motion = int(data.get('motion', 5)) # 视频丰富度
pid = data.get('task_id')
motion = 6 # 视频丰富度
# 获取当前视频生成记录
video_generation = VideoGeneration.objects.get(pid=pid)
@ -284,8 +353,8 @@ def extend_video(request):
"uuid": pid, # 视频的 UUID
"motion": motion, # 视频丰富度
"seed": 0, # 默认 seed 为 0
"upscale": False, # 默认开启 upscale
"interpolate": False, # 默认开启 interpolate
"upscale": True, # 默认开启 upscale
"interpolate": True, # 默认开启 interpolate
"callback_url": "https://www.typeframes.ai/api/callback/"
}
print(f"extend_video 请求体: {payload}")

View File

@ -5,14 +5,16 @@ from django.views.decorators.csrf import csrf_exempt
from datetime import datetime
from .models import Order, Plan, User
import json
import logging
logger = logging.getLogger(__name__)
from .base import logger
def get_paypal_access_token():
"""获取 PayPal 访问令牌"""
print("正在获取 PayPal 访问令牌...")
url = f"https://api.{settings.PAYPAL_MODE}.paypal.com/v1/oauth2/token"
# 根据配置文件选择 PayPal URL
paypal_base_url = "https://api.sandbox.paypal.com" if settings.PAYPAL_MODE == 'sandbox' else "https://api.paypal.com"
url = f"{paypal_base_url}/v1/oauth2/token"
auth = (
settings.PAYPAL_CLIENT_ID_SANDBOX if settings.PAYPAL_MODE == 'sandbox' else settings.PAYPAL_CLIENT_ID_PRODUCTION,
settings.PAYPAL_SECRET_KEY_SANDBOX if settings.PAYPAL_MODE == 'sandbox' else settings.PAYPAL_SECRET_KEY_PRODUCTION
@ -30,12 +32,13 @@ def get_paypal_access_token():
if response.status_code == 200:
access_token = response.json().get('access_token')
logger.info(f"[支付执行] 获取的访问令牌: {access_token}")
print(f"获取的访问令牌: {access_token}")
return access_token
else:
logger.error(f"[支付执行] 获取 PayPal 访问令牌失败: {response.text}")
print(f"获取 PayPal 访问令牌失败: {response.text}")
return None
@csrf_exempt
def create_paypal_payment(request):
"""创建 PayPal 支付"""
@ -66,7 +69,7 @@ def create_paypal_payment(request):
return JsonResponse({"code": 500, "message": "无法获取支付访问令牌", "data": {}})
# 配置支付请求
url = f"https://api.{settings.PAYPAL_MODE}.paypal.com/v1/payments/payment"
url = f"https://api.paypal.com/v1/payments/payment"
headers = {
"Content-Type": "application/json",
"Authorization": f"Bearer {access_token}"
@ -143,27 +146,50 @@ def create_paypal_payment(request):
else:
return JsonResponse({"code": 405, "message": "方法不允许", "data": {}})
@csrf_exempt
def execute_paypal_payment(request):
"""执行 PayPal 支付"""
if request.method == 'POST':
try:
logger.info("[支付执行] 接收到来自前端的 POST 请求,开始处理支付...")
# 解析请求体
data = json.loads(request.body)
payment_id = data.get('paymentId')
payer_id = data.get('PayerID')
logger.info(f"[支付执行] 请求内容: paymentId={payment_id}, PayerID={payer_id}")
print(f"请求内容: paymentId={payment_id}, PayerID={payer_id}")
if not payment_id or not payer_id:
logger.error("[支付执行] 缺少支付ID或付款人ID")
return JsonResponse({"code": 400, "message": "缺少支付ID或付款人ID", "data": {}})
# 获取订单信息
try:
order = Order.objects.get(order_id=payment_id)
logger.info(f"[支付执行] 获取到的订单信息: {order}")
except Order.DoesNotExist:
logger.error("[支付执行] 订单不存在")
return JsonResponse({"code": 400, "message": "订单不存在", "data": {}})
# 检查订单是否已经支付
if order.status == 'completed':
logger.info(f"[支付执行] 订单 {payment_id} 已支付,无需再次执行")
print(f"订单 {payment_id} 已支付,无需再次执行")
return JsonResponse({"code": 400, "message": "订单已支付", "data": {}})
# 获取PayPal访问令牌
# 获取 PayPal 访问令牌
access_token = get_paypal_access_token()
if not access_token:
logger.error("[支付执行] 无法获取支付访问令牌")
return JsonResponse({"code": 500, "message": "无法获取支付访问令牌", "data": {}})
logger.info(f"[支付执行] 获取到的 PayPal 访问令牌: {access_token}")
# 执行支付确认请求
url = f"https://api.{settings.PAYPAL_MODE}.paypal.com/v1/payments/payment/{payment_id}/execute"
# 设置 PayPal API 请求的 URL 和头部信息
paypal_base_url = "https://api.sandbox.paypal.com" if settings.PAYPAL_MODE == 'sandbox' else "https://api.paypal.com"
url = f"{paypal_base_url}/v1/payments/payment/{payment_id}/execute"
headers = {
"Content-Type": "application/json",
"Authorization": f"Bearer {access_token}"
@ -172,28 +198,68 @@ def execute_paypal_payment(request):
"payer_id": payer_id
}
logger.info(f"[支付执行] 发送支付请求URL: {url}, 请求头: {headers}, 请求体: {payload}")
print(f"发送支付请求URL: {url}, 请求体: {payload}")
# 执行 PayPal 支付请求
response = requests.post(url, headers=headers, json=payload)
# 打印 PayPal API 请求的响应
logger.info(f"[支付执行] PayPal API 响应状态码: {response.status_code}")
print(f"PayPal API 响应状态码: {response.status_code}")
logger.info(f"[支付执行] PayPal API 响应内容: {response.json()}")
print(f"PayPal API 响应内容: {response.json()}")
# 判断支付是否成功
if response.status_code == 200:
try:
payment_data = response.json()
if payment_data['state'] == 'approved':
logger.info(f"[支付执行] 支付成功,订单状态更新为 'approved'")
# 确保订单未完成过
if order.status != 'completed':
order.status = 'completed'
order.updated_at = datetime.now()
order.save()
# 更新用户积分
# 获取用户当前积分并进行累加
user = order.user
user.points += order.plan.credits_per_month
current_points = user.points if user.points else 0 # 防止积分为 None
added_points = order.plan.credits_per_month
user.points = current_points + added_points
user.save()
return JsonResponse({"code": 200, "message": "支付成功", "data": {}})
except Order.DoesNotExist:
return JsonResponse({"code": 400, "message": "订单不存在", "data": {}})
# 打印用户当前积分、购买的套餐和增加的积分
logger.info(f"[支付执行] 用户 {user.username} 当前积分: {current_points}")
logger.info(f"[支付执行] 购买的套餐: {order.plan.title}")
logger.info(f"[支付执行] 增加的积分: {added_points}")
logger.info(f"[支付执行] 用户新的总积分: {user.points}")
print(f"用户 {user.username} 当前积分: {current_points}")
print(f"购买的套餐: {order.plan.title}")
print(f"增加的积分: {added_points}")
print(f"新的总积分: {user.points}")
return JsonResponse({"code": 200, "message": "支付成功,积分已更新", "data": {}})
else:
logger.info(f"[支付执行] 订单 {payment_id} 已支付,无需再次更新积分")
return JsonResponse({"code": 400, "message": "订单已支付,积分不重复增加", "data": {}})
else:
logger.error(f"[支付执行] 支付未完成,状态为: {payment_data['state']}")
print(f"支付未完成,状态为: {payment_data['state']}")
return JsonResponse({"code": 400, "message": "支付状态未完成", "data": payment_data})
else:
logger.error(f"[支付执行] 支付执行失败,状态码: {response.status_code}")
print(f"支付执行失败,状态码: {response.status_code}")
return JsonResponse({"code": 400, "message": "支付执行失败", "data": response.json()})
except json.JSONDecodeError:
logger.error("[支付执行] 请求体不是有效的 JSON 格式")
return JsonResponse({"code": 400, "message": "请求体不是有效的JSON", "data": {}})
except Exception as e:
logger.error(f"[支付执行] 支付执行过程中发生异常: {str(e)}")
print(f"支付执行过程中发生异常: {str(e)}")
return JsonResponse({"code": 500, "message": f"支付执行过程中发生异常: {str(e)}", "data": {}})
else:
logger.error(f"[支付执行] 请求方法 {request.method} 不被允许")
return JsonResponse({"code": 405, "message": "方法不允许", "data": {}})

View File

@ -5,14 +5,12 @@ from django.views.decorators.csrf import csrf_exempt
from datetime import datetime
from .models import Order
import json
import logging
logger = logging.getLogger(__name__)
from .base import logger
def get_paypal_access_token():
"""获取 PayPal 访问令牌"""
print("正在获取 PayPal 访问令牌...")
url = f"https://api.{settings.PAYPAL_MODE}.paypal.com/v1/oauth2/token"
url = f"https://api.paypal.com/v1/oauth2/token"
auth = (
settings.PAYPAL_CLIENT_ID_SANDBOX if settings.PAYPAL_MODE == 'sandbox' else settings.PAYPAL_CLIENT_ID_PRODUCTION,
settings.PAYPAL_SECRET_KEY_SANDBOX if settings.PAYPAL_MODE == 'sandbox' else settings.PAYPAL_SECRET_KEY_PRODUCTION
@ -30,18 +28,24 @@ def get_paypal_access_token():
if response.status_code == 200:
access_token = response.json().get('access_token')
logger.info(f"获取的访问令牌: {access_token}")
print(f"获取的访问令牌: {access_token}")
return access_token
else:
logger.error(f"获取 PayPal 访问令牌失败: {response.text}")
print(f"获取 PayPal 访问令牌失败: {response.text}")
return None
def verify_paypal_webhook(headers, body):
"""使用 PayPal API 验证 Webhook 签名"""
logger.info("验证 PayPal Webhook 签名...")
print("验证 PayPal Webhook 签名...")
verify_url = f"https://api.{settings.PAYPAL_MODE}.paypal.com/v1/notifications/verify-webhook-signature"
verify_url = f"https://api.paypal.com/v1/notifications/verify-webhook-signature"
auth_token = get_paypal_access_token()
if not auth_token:
logger.error("无法获取 PayPal 访问令牌,无法验证 Webhook 签名")
print("无法获取 PayPal 访问令牌,无法验证 Webhook 签名")
return False
@ -61,60 +65,53 @@ def verify_paypal_webhook(headers, body):
}
response = requests.post(verify_url, headers=verify_headers, json=verify_payload)
if response.status_code == 200 and response.json().get('verification_status') == 'SUCCESS':
logger.info("Webhook 签名验证成功")
print("Webhook 签名验证成功")
return True
else:
logger.error(f"Webhook 签名验证失败: {response.text}")
print(f"Webhook 签名验证失败: {response.text}")
return False
@csrf_exempt
def paypal_webhook(request):
"""PayPal Webhook 处理函数,用于接收和处理 PayPal 异步通知"""
def execute_paypal_payment(payment_id, payer_id):
"""执行 PayPal 支付"""
try:
print("接收到 PayPal Webhook 请求...")
headers = request.headers
payload = json.loads(request.body)
logger.info(f"回调接收到 开始执行支付订单ID: {payment_id}, 付款人ID: {payer_id}")
order = Order.objects.get(order_id=payment_id)
# 验证 Webhook 签名
if not verify_paypal_webhook(headers, request.body):
return JsonResponse({"code": 400, "message": "Webhook 签名验证失败", "data": {}})
event_type = payload.get('event_type')
# 打印接收到的 Webhook payload 以供调试
print(f"接收到 PayPal Webhook 事件: {event_type}")
print(f"Webhook payload: {json.dumps(payload, indent=2)}")
# 处理不同类型的事件
if event_type == 'PAYMENT.SALE.COMPLETED':
sale_id = payload['resource'].get('id')
parent_payment = payload['resource'].get('parent_payment') # 使用parent_payment作为订单ID
if parent_payment:
try:
order = Order.objects.get(order_id=parent_payment)
# 检查订单状态,防止重复更新
if order.status == 'completed':
print(f"订单 {parent_payment} 已经完成,不重复更新")
return JsonResponse({"code": 200, "message": "订单已处理", "data": {}})
logger.info(f"订单 {payment_id} 已经支付,不需要再次执行支付")
print(f"订单 {payment_id} 已经支付,不需要再次执行支付")
return JsonResponse({"code": 400, "message": "订单已支付", "data": {}})
# 再次向 PayPal 查询订单状态,确保支付确实完成
# 获取 PayPal 访问令牌
access_token = get_paypal_access_token()
if not access_token:
print("无法获取 PayPal 访问令牌,无法验证订单状态")
logger.error("无法获取支付访问令牌")
return JsonResponse({"code": 500, "message": "无法获取支付访问令牌", "data": {}})
payment_details_url = f"https://api.{settings.PAYPAL_MODE}.paypal.com/v1/payments/payment/{parent_payment}"
# 根据配置文件选择 PayPal URL
paypal_base_url = "https://api.sandbox.paypal.com" if settings.PAYPAL_MODE == 'sandbox' else "https://api.paypal.com"
url = f"{paypal_base_url}/v1/payments/payment/{payment_id}/execute"
headers = {
"Content-Type": "application/json",
"Authorization": f"Bearer {access_token}"
}
payment_details_response = requests.get(payment_details_url, headers=headers)
payload = {
"payer_id": payer_id
}
if payment_details_response.status_code == 200:
payment_details = payment_details_response.json()
if payment_details['state'] == 'approved':
logger.info(f"执行 PayPal 支付请求, URL: {url}, 请求体: {payload}")
print(f"执行 PayPal 支付请求, URL: {url}, 请求体: {payload}")
response = requests.post(url, headers=headers, json=payload)
# 处理支付执行结果
if response.status_code == 200:
order.status = 'completed'
order.updated_at = datetime.now()
order.save()
@ -124,22 +121,96 @@ def paypal_webhook(request):
user.points += order.plan.credits_per_month
user.save()
print(f"订单 {parent_payment} 状态更新为 'completed' 并已更新用户积分")
logger.info(f"订单 {payment_id} 支付成功,用户积分已更新: {order.plan.credits_per_month}")
print(f"订单 {payment_id} 支付成功,用户积分已更新: {order.plan.credits_per_month}")
return JsonResponse({"code": 200, "message": "支付成功", "data": {}})
else:
print(f"支付未完成,状态: {payment_details['state']}")
else:
print(f"查询支付状态失败: {payment_details_response.text}")
return JsonResponse({"code": 500, "message": "查询支付状态失败", "data": {}})
logger.error(f"支付执行失败: {response.text}")
print(f"支付执行失败: {response.text}")
return JsonResponse({"code": 400, "message": "支付执行失败", "data": response.json()})
except Order.DoesNotExist:
logger.error(f"订单 {payment_id} 不存在")
print(f"订单 {payment_id} 不存在")
return JsonResponse({"code": 400, "message": "订单不存在", "data": {}})
except Exception as e:
logger.error(f"支付执行过程中发生异常: {str(e)}")
print(f"支付执行过程中发生异常: {str(e)}")
return JsonResponse({"code": 500, "message": f"支付执行过程中发生异常: {str(e)}", "data": {}})
@csrf_exempt
def paypal_webhook(request):
"""PayPal Webhook 处理函数,用于接收和处理 PayPal 异步通知"""
try:
logger.info("接收到 PayPal Webhook 请求...")
print("接收到 PayPal Webhook 请求...")
headers = request.headers
payload = json.loads(request.body)
# 验证 Webhook 签名
if not verify_paypal_webhook(headers, request.body):
logger.error("Webhook 签名验证失败")
return JsonResponse({"code": 400, "message": "Webhook 签名验证失败", "data": {}})
event_type = payload.get('event_type')
# 打印接收到的 Webhook payload 以供调试
logger.info(f"接收到 PayPal Webhook 事件: {event_type}")
print(f"接收到 PayPal Webhook 事件: {event_type}")
logger.info(f"Webhook payload: {json.dumps(payload, indent=2)}")
# 处理不同类型的事件
if event_type == 'PAYMENT.SALE.COMPLETED':
parent_payment = payload['resource'].get('parent_payment') # 使用 parent_payment 作为订单 ID
state = payload['resource'].get('state') # 获取支付状态
if parent_payment:
try:
order = Order.objects.get(order_id=parent_payment)
# 通过 state 判断支付是否完成
if state == 'completed':
if order.status == 'completed':
logger.info(f"订单 {parent_payment} 已经完成,不重复更新")
print(f"订单 {parent_payment} 已经完成,不重复更新")
return JsonResponse({"code": 200, "message": "订单已处理", "data": {}})
# 更新订单状态为已完成
order.status = 'completed'
order.updated_at = datetime.now()
order.save()
# 更新用户积分
user = order.user
user.points += order.plan.credits_per_month
user.save()
logger.info(f"订单 {parent_payment} 状态更新为 'completed' 并已更新用户积分")
print(f"订单 {parent_payment} 状态更新为 'completed' 并已更新用户积分")
return JsonResponse({"code": 200, "message": "支付完成,订单更新成功", "data": {}})
else:
logger.error(f"支付状态为 {state},未完成支付")
print(f"支付状态为 {state},未完成支付")
return JsonResponse({"code": 400, "message": f"支付状态为 {state},未完成支付", "data": {}})
except Order.DoesNotExist:
logger.error(f"未找到订单 {parent_payment}")
print(f"未找到订单 {parent_payment}")
return JsonResponse({"code": 400, "message": "订单不存在", "data": {}})
else:
logger.error("Webhook payload 中缺少 parent_payment")
print("Webhook payload 中缺少 parent_payment")
return JsonResponse({"code": 400, "message": "Webhook payload 中缺少 parent_payment", "data": {}})
elif event_type == 'PAYMENTS.PAYMENT.CREATED':
# 支付创建时的逻辑,可以执行支付
payment_id = payload['resource']['id']
payer_id = payload['resource']['payer']['payer_info']['payer_id']
execute_paypal_payment(payment_id, payer_id)
elif event_type == 'PAYMENT.SALE.DENIED':
sale_id = payload['resource'].get('id')
parent_payment = payload['resource'].get('parent_payment')
if parent_payment:
try:
@ -147,19 +218,20 @@ def paypal_webhook(request):
order.status = 'failed'
order.updated_at = datetime.now()
order.save()
logger.info(f"订单 {parent_payment} 状态更新为 'failed'")
print(f"订单 {parent_payment} 状态更新为 'failed'")
except Order.DoesNotExist:
logger.error(f"未找到订单 {parent_payment}")
print(f"未找到订单 {parent_payment}")
return JsonResponse({"code": 400, "message": "订单不存在", "data": {}})
else:
print("Webhook payload 中缺少 parent_payment")
return JsonResponse({"code": 400, "message": "Webhook payload 中缺少 parent_payment", "data": {}})
return JsonResponse({"code": 200, "message": "Webhook 处理成功", "data": {}})
except json.JSONDecodeError:
logger.error("请求体不是有效的JSON")
print("请求体不是有效的JSON")
return JsonResponse({"code": 400, "message": "请求体不是有效的JSON", "data": {}})
except Exception as e:
print(f"处理 PayPal Webhook 时发生错误: {e}")
logger.error(f"处理 PayPal Webhook 时发生错误: {str(e)}")
print(f"处理 PayPal Webhook 时发生错误: {str(e)}")
return JsonResponse({"code": 500, "message": f"处理 PayPal Webhook 时发生错误: {str(e)}", "data": {}})

View File

@ -5,33 +5,63 @@ from .models import User, UserSource
@receiver(user_logged_in)
def user_logged_in_handler(request, user, **kwargs):
print('1111111111111111111111111')
print('信号处理开始: user_logged_in_handler 被触发')
# 防止信号被重复处理
if hasattr(request, '_google_user_logged_in_handled'):
print('重复信号,跳过处理')
return
request._google_user_logged_in_handled = True
print('处理信号标志设置完成')
try:
social_account = SocialAccount.objects.get(user=user, provider='google')
print(social_account.extra_data) # 打印 extra_data 内容以进行调试
print(f'找到 social_account用户ID: {user.id}')
google_id = social_account.extra_data.get('sub')
email = social_account.extra_data.get('email')
username = social_account.extra_data.get('name')
print(f'从 social_account 获取的 google_id: {google_id}, email: {email}, username: {username}')
google_id = social_account.extra_data['sub'] # 使用 'sub' 字段
email = social_account.extra_data['email']
username = social_account.extra_data['name']
if not google_id:
# 如果 google_id 为空,不要继续创建用户,记录日志或处理错误
print('google_id 为空,终止处理')
return
# 优化:根据 google_id 和 email 双重检查用户是否已存在
try:
custom_user = User.objects.get(google_id=google_id)
print(f'根据 google_id 找到用户: {custom_user.username}')
except User.DoesNotExist:
print(f'没有找到 google_id 为 {google_id} 的用户,检查 email: {email}')
# 进一步检查是否有相同的 email 用户存在
if User.objects.filter(email=email).exists():
custom_user = User.objects.get(email=email)
print(f'找到 email 为 {email} 的用户: {custom_user.username}')
# 如果用户存在但 google_id 不同,更新 google_id
custom_user.google_id = google_id
custom_user.save()
print(f'更新用户的 google_id 为: {google_id}')
else:
custom_user = User.objects.create(
username=username,
email=email,
google_id=google_id,
password_hash='', # Google 登录不需要密码
# password_hash='', # Google 登录不需要密码
)
print(f'创建新用户: {custom_user.username}google_id: {google_id}')
UserSource.objects.create(user=custom_user, source='Google')
print(f'创建 UserSource 记录,来源为 Google')
# 更新登录次数和最后登录IP
x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
if x_forwarded_for:
ip = x_forwarded_for.split(',')[0] # 可能有多个 IP 地址,取第一个
else:
ip = request.META.get('REMOTE_ADDR') # 使用 REMOTE_ADDR 作为备用
# 更新登录次数和 IP 地址
custom_user.login_count += 1
custom_user.last_login_ip = request.META.get('REMOTE_ADDR')
custom_user.last_login_ip = ip
custom_user.save()
print(f'更新用户信息: 登录次数 {custom_user.login_count}, IP 地址 {custom_user.last_login_ip}')
# 确保 Django 用户同步
user.username = custom_user.username
user.save()
except SocialAccount.DoesNotExist:
pass
print('未找到与用户关联的 Google social_account')

View File

@ -22,6 +22,7 @@ from .aliyun_sms import send_verification_sms, verify_sms_code
# 定义积分奖励值
REWARD_POINTS = 50 # 例如奖励50积分
def check_and_reward_points(user, openid):
"""
根据 openid 查询原系统会员状态为原系统的用户增加一天会员时长不论是否为会员
@ -151,7 +152,7 @@ def send_verification_email_view(request):
if request.method == 'POST':
try:
body = json.loads(request.body)
email = body.get('phone_number')
email = body.get('email')
if not email:
return JsonResponse({'code': 400, 'message': '邮箱地址是必须的'})
@ -193,8 +194,8 @@ def send_verification_sms_view(request):
if not phone_number:
return JsonResponse({'code': 400, 'message': '手机号码是必须的'})
sign_name = "福铭科技" # 替换为实际的签名名称
template_code = "SMS_299200388" # 替换为实际的短信模板代码
sign_name = "光映" # 替换为实际的签名名称
template_code = "SMS_473670066" # 替换为实际的短信模板代码
response = send_verification_sms(phone_number, sign_name, template_code)
return JsonResponse(response)
@ -379,7 +380,7 @@ def send_verification_code_view(request):
if '@' in identifier:
response = send_verification_email(identifier)
else:
response = send_verification_sms(identifier, "福铭科技", "SMS_299200388")
response = send_verification_sms(identifier, "光映", "SMS_473670066")
return JsonResponse(response)
except json.JSONDecodeError:

Binary file not shown.

View File

@ -23,7 +23,7 @@ BASE_DIR = Path(__file__).resolve().parent.parent
SECRET_KEY = "django-insecure-!4a*kl(!=s*76xngra89q*86d&e8ya=l49!bibepo6p1(50+$s"
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
DEBUG = False
ALLOWED_HOSTS = ['*']
# settings.py
@ -63,7 +63,7 @@ AUTHENTICATION_BACKENDS = (
'django.contrib.auth.backends.ModelBackend',
'allauth.account.auth_backends.AuthenticationBackend',
)
LOGIN_REDIRECT_URL = '/user/userinfo/' # 登录后重定向的URL
LOGIN_REDIRECT_URL = '/create' # 登录后重定向的URL
LOGIN_URL = '/'
LOGOUT_REDIRECT_URL = '/'
@ -159,10 +159,10 @@ DATABASES = {
{
'ENGINE': 'django.db.backends.mysql', # 数据库引擎
'NAME': 'admin_data', # 数据库名称
'HOST': '1Panel-mysql-61G1', # 数据库地址,本机 ip 地址 127.0.0.1
'HOST': '127.0.0.1', # 数据库地址,本机 ip 地址 127.0.0.1
'PORT': 3306, # mysql端口
'USER': 'admin_data', # 数据库用户名
'PASSWORD': 'mPmFz2NeXSYbzrt5', # 数据库密码
'PASSWORD': 'kyRz3c3hGMmDADrW', # 数据库密码
'OPTIONS': {
'charset': 'utf8mb4',
'use_unicode': True,
@ -231,7 +231,7 @@ AZURE_CONTAINER_NAME = 'audio'
#支付宝电脑版支付配置
# 支付宝配置
ALIPAY_DEBUG = True # True 表示沙箱环境False 表示生产环境
ALIPAY_DEBUG = False # True 表示沙箱环境False 表示生产环境
# 沙箱环境配 电脑支付宝
ALIPAY_APP_ID_SANDBOX_PC = '9021000139657593' # 沙箱环境电脑端应用ID
@ -250,20 +250,19 @@ ALIPAY_PUBLIC_KEY_PRODUCTION_PC = 'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAo
ALIPAY_APP_ID_PRODUCTION_MOBILE = '2021004169658094' # 生产环境移动端应用ID
ALIPAY_APP_PRIVATE_KEY_PRODUCTION_MOBILE = 'MIIEowIBAAKCAQEAlkLen9IPB0OhhRnDw0Ks1yX74oXSLJ4hEaqQmJqXI8qfNFL+DiuEWs+yAZRad8mDOUqERka1YrMI9Y7iVyGWhcFRHe91+oNNDZlrXp1K/SzPWtA1tPbkBrgxV5lgj/fGKJrMlJhlfF7Bio8b9jOfyMtaqolP777tD0zMAdIbKYCW1wmUgUeRsNplDO/8GIDoJV+qGxTEd2TN3eJfC9MBIkCW/b1QHTXukJIFzKGufNRNJIWbPi/wmyMaUd+lyemz//sNhD2+CpiuB4pi/v3c8tQsPJeOslRpo9+T0lg9wLlDgMMeajf+PMzjErRmiOxI1ZwNn8xkaE6ZfeDhh18v1wIDAQABAoIBAQCQ225bjNpIGn8AHdKHzyNpVoj53CC+OsOOkGxNcdr6+j945fleF73E/i2RMD/28yG6fYf/Z/M9b3PXpyO09AB0eeWFgnCuTR5fWeQUlnbQk/5igg8Eom85uyB2XrqkkC1Mv88yAaj0uTTEKyq9sw77OG/zr+SML/fBpDuYFcFxw7JnD+TxKBeqT6gd1RHcfeyta1MWiEsQeX7y2PGicn5HjbGLCsJxvJVGyvaQFPBN5eoIesSm74DEFL25ZdR1vpaWYGm7XZgAY6dgzPbijFx2nLMRAM9e+M6I0u75k0mDSVb9y+1TXqEKPSG7FegIbzhylj20ZcwWYb0SgJ8sHuvBAoGBAOcRBlbtkq4uGqFyTY1y1WedxSMJf0bMfYum3CvT7YAOVffVxye2I3s4v1Os1NPR5M+om7eEtgN+9Zl2DIagPlTB6CrYRg26hwnDuNhLqLZHo8IW0IK2xY8QSPzvRJcx1sSvTqLXG/MdsFDV9SGNxYazYpIqlL2Q2cUHImc6+JqZAoGBAKZ5rnVPlOQ20aXCe/0nn7K6PIFCQhBHayBjXmqaNi7ZGVgM1CXrvFffpGrc7e60gVfbOkZjzUy0XJAmagYTNZ8+HDh52y6YRoMR3XjPKgrs4+hdraG1vBVSmxRpzUfYqqq+k9T2dnK3pjkYIrDZiiwsT57o2EispQBWRfNmKZPvAoGAeclBXCPPgbqPErTaJ0l1LS28r+DbkodJTIff18HVlf74VK36T/Xx8YpRXVrkudgRD1pA6JMsE9+gtwe/Rl3DPI0PPzXKhoXfksfz7xzBiYFs0GmR8LNAoUzmC1pY/o+oMPZtLerOsm7ddV2v28WLbJmzxHJo/xkPjodaHKq6SVECgYAxGLHa5x2CMKijujfW8Vin3UT62g+hvW5anvO5fMF+D4jp7t6iUGO7hrl2yrFhNNrwjjchi02A0bB60tlx8ThfPnIUNdvuYfpprVsjxfUgQ7zzSq1qg650m2ghHRLtnXi34ny20fkc3AypyfRxM7cMUAUrWIBw7nm7H7aBkh+xAQKBgH4Zaxjcn/OsF4QPCJqzf02+zHh7FGGLnsjZXmtVoNDmmFJFXj5ey05jfcNyoRdtffl0Fa/mbkiL1YcAUoBmkyS7MA4mrrM5vG5ZKtLcul1qeC9JrJ2FEcZBmny2fdbfzFFuBdhz0jbOGoDOKl5KWM7EQoxk377DQVRQ884B0Cc+' # 生产环境移动端应用私钥
ALIPAY_PUBLIC_KEY_PRODUCTION_MOBILE = 'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAomw6g4rBmCr/QoX3NI3DVLyDpkaUytZ2uFhdfQaegIDAuUfZfgpTCASlAtO82t8ISAbSOSyp9CUpwdGV4EYOiCBbLxMYB6taaHPiIjJ1zNT1EakJzWgU53hz1AVeABB9kdAvMqSvjH6KLoVupmqm4Li8ZwDW9M2ANAmyDfKgiF0Lt4aUUnaZktoCrTWTkpmtfRZCHNACj851IllvN2wyC4OL7dJq5UzOFxmn07Dy/2z4UAhaaSAyRVawpOui5AIYJTXZERLYL3KMyRnMuZoFq3xltzVTzRPM06nRa9RfeVNVwWVtGBIe/r8tcg5wyhI57KUszGNOmUIm/se6G2lnAQIDAQAB' # 生产环境移动端支付宝公钥
ALIPAY_NOTIFY_URL = 'https://www.typeframes.com.cn/api/alipay/notify/'
ALIPAY_RETURN_URL = 'https://www.typeframes.com.cn/user/userinfo/'
ALIPAY_RETURN_URL = 'https://www.typeframes.com.cn/create'
# settings.py
# PayPal 配置
PAYPAL_CLIENT_ID_SANDBOX = 'AfwWNEZE92XpbmoHywwdDEXH2x2Elak1Gxbireb5bv-u17OtKiJUuz7CMLnqayAZkqeU2kGtWXHXcXGS'
PAYPAL_SECRET_KEY_SANDBOX = 'ELmuFW7AspHp4km8amEhlM-NB3OGGx_iuqQbntTQ-2RTnJWbxdLTl6xlET1F1ezxSHbU1CUpK0_8ToI3'
PAYPAL_CLIENT_ID_PRODUCTION = 'YOUR_PRODUCTION_CLIENT_ID' # 替换为实际的生产环境客户端ID
PAYPAL_SECRET_KEY_PRODUCTION = 'YOUR_PRODUCTION_SECRET_KEY' # 替换为实际的生产环境密钥
PAYPAL_CLIENT_ID_PRODUCTION = 'Aelz9E_u5mlLP_-8nOGuXS14P-osTWYqxPx8HknC1PNBqRtG_RzAtWblryvr0o8pIyqIomI-2KMFagk2' # 替换为实际的生产环境客户端ID
PAYPAL_SECRET_KEY_PRODUCTION = 'EIA_O_JeOWUjolXK3yi4VC88wpcZaIYgQvAPJ251LX_OTsatYzjt_Y2aFKLjXt5fInRkdTfeIbrwlZEh' # 替换为实际的生产环境密钥
PAYPAL_MODE = 'sandbox' #'sandbox' if DEBUG else 'live' # 根据DEBUG模式选择环境
PAYPAL_RETURN_URL = 'https://www.typeframes.ai/user/plan_list/' # 支付成功后跳转的URL
PAYPAL_CANCEL_URL = 'https://www.typeframes.ai/user/plan_list/' # 支付取消后跳转的URL
PAYPAL_MODE = 'sandbox' if DEBUG else 'live' # 根据DEBUG模式选择环境
PAYPAL_RETURN_URL = 'https://www.typeframes.ai/create' # 支付成功后跳转的URL
PAYPAL_CANCEL_URL = 'https://www.typeframes.ai/create' # 支付取消后跳转的URL
PAYPAL_WEBHOOK_ID = '5L31025588094031T' # 替换为你的实际 Webhook ID
PAYPAL_WEBHOOK_ID = '1Y325150YP471005S' # 替换为你的实际 Webhook ID

0
gunicorn_acess.log Executable file
View File

0
gunicorn_error.log Executable file
View File

View File

@ -1,11 +1,25 @@
[uwsgi]
chdir = /app
# 项目目录
chdir = /www/wwwroot/Ai_Admin
# 指定项目application
module = WebSite.wsgi:application
# 进程个数
processes = 4
# 线程个数
threads = 2
# 指定启动时的pid文件路径用于停止服务和重启服务请勿删除
pidfile = /www/wwwroot/Ai_Admin/uwsgi.pid
# 指定ip及端口
http = 0.0.0.0:3001
http=0.0.0.0:3001
# 启动uwsgi的用户名和用户组
uid = root
gid = root
# 启用主进程
master = true
@ -14,20 +28,18 @@ master = true
buffer-size = 32768
http-timeout = 60
post-buffering = 8192
# 后台运行,并输出日志
daemonize = /www/wwwroot/Ai_Admin/uwsgi.log
# 处理 SIGTERM 信号以便优雅地关闭
die-on-term = true
# 处理静态和媒体文件
static-map = /static=/app/static
static-map = /media=/app/media
static-map = /media/avatars=/app/media/avatars
static-map = /media/audios=/app/media/audios
static-map = /.well-known/acme-challenge/=/app/.well-known/acme-challenge
# 日志输出到标准输出
logger = stdout
# 启用thunder lock
thunder-lock = true
# 添加以下配置以处理静态和媒体文件
static-map = /static=/www/wwwroot/Ai_Admin/static
static-map = /media=/www/wwwroot/Ai_Admin/media
static-map = /media/avatars=/www/wwwroot/Ai_Admin/media/avatars
static-map = /media/audios=/www/wwwroot/Ai_Admin/media/audios
static-map = /.well-known/acme-challenge/=/www/wwwroot/java_node_ssl/.well-known/acme-challenge

1209
uwsgi.log Executable file

File diff suppressed because it is too large Load Diff

1
uwsgi.pid Executable file
View File

@ -0,0 +1 @@
145523