Files
market_page/backend/shop/views.py
2026-02-02 14:41:21 +08:00

146 lines
5.7 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
from rest_framework import viewsets, status
from rest_framework.decorators import action
from rest_framework.response import Response
from django.shortcuts import render
from drf_spectacular.utils import extend_schema, extend_schema_view, OpenApiParameter, OpenApiExample
from .models import ESP32Config, Order, WeChatPayConfig, Service, ARService, ServiceOrder
from .serializers import ESP32ConfigSerializer, OrderSerializer, ServiceSerializer, ARServiceSerializer, ServiceOrderSerializer
@extend_schema_view(
list=extend_schema(summary="获取AR服务列表", description="获取所有可用的AR服务"),
retrieve=extend_schema(summary="获取AR服务详情", description="获取指定AR服务的详细信息")
)
class ARServiceViewSet(viewsets.ReadOnlyModelViewSet):
"""
AR服务列表和详情
"""
queryset = ARService.objects.all().order_by('-created_at')
serializer_class = ARServiceSerializer
import uuid
import time
import hashlib
def order_check_view(request):
"""
订单查询页面视图
"""
return render(request, 'shop/order_check.html')
@extend_schema_view(
list=extend_schema(summary="获取AI服务列表", description="获取所有可用的AI服务"),
retrieve=extend_schema(summary="获取AI服务详情", description="获取指定AI服务的详细信息")
)
class ServiceViewSet(viewsets.ReadOnlyModelViewSet):
"""
AI服务列表和详情
"""
queryset = Service.objects.all().order_by('-created_at')
serializer_class = ServiceSerializer
class ServiceOrderViewSet(viewsets.ModelViewSet):
"""
AI服务订单管理
"""
queryset = ServiceOrder.objects.all()
serializer_class = ServiceOrderSerializer
@extend_schema_view(
list=extend_schema(summary="获取ESP32配置列表", description="获取所有可用的ESP32硬件配置选项"),
retrieve=extend_schema(summary="获取ESP32配置详情", description="获取指定ESP32配置的详细信息")
)
class ESP32ConfigViewSet(viewsets.ReadOnlyModelViewSet):
"""
提供ESP32配置选项的列表和详情
"""
queryset = ESP32Config.objects.all()
serializer_class = ESP32ConfigSerializer
class OrderViewSet(viewsets.ModelViewSet):
"""
订单管理视图集
支持创建订单和查询订单状态
"""
queryset = Order.objects.all()
serializer_class = OrderSerializer
@action(detail=False, methods=['get'])
def lookup(self, request):
"""
根据电话号码查询订单状态
URL: /api/orders/lookup/?phone=13800138000
"""
phone = request.query_params.get('phone')
if not phone:
return Response({'error': '请提供电话号码'}, status=status.HTTP_400_BAD_REQUEST)
# 简单校验
orders = Order.objects.filter(phone_number=phone).order_by('-created_at')
serializer = self.get_serializer(orders, many=True)
return Response(serializer.data)
@action(detail=True, methods=['post'])
def initiate_payment(self, request, pk=None):
"""
发起支付请求
获取微信支付配置并生成签名
"""
order = self.get_object()
if order.status == 'paid':
return Response({'error': '订单已支付'}, status=status.HTTP_400_BAD_REQUEST)
# 获取微信支付配置
wechat_config = WeChatPayConfig.objects.filter(is_active=True).first()
if not wechat_config:
# 如果没有配置,为了演示方便,回退到模拟数据,或者报错
# 这里我们报错提示需要在后台配置
return Response({'error': '支付系统维护中 (未配置支付参数)'}, status=status.HTTP_503_SERVICE_UNAVAILABLE)
# 构造支付参数
# 注意:实际生产环境必须在此处调用微信【统一下单】接口获取真实的 prepay_id
# 这里为了演示完整流程,我们使用配置中的参数生成合法的签名结构,但 prepay_id 是模拟的
app_id = wechat_config.app_id
timestamp = str(int(time.time()))
nonce_str = str(uuid.uuid4()).replace('-', '')
# 模拟的 prepay_id
prepay_id = f"wx{str(uuid.uuid4()).replace('-', '')}"
package = f"prepay_id={prepay_id}"
sign_type = 'MD5'
# 生成签名 (WeChat Pay V2 MD5 Signature)
# 签名步骤:
# 1. 设所有发送或者接收到的数据为集合M将集合M内非空参数值的参数按照参数名ASCII码从小到大排序字典序
# 2. 使用URL键值对的格式即key1=value1&key2=value2…拼接成字符串stringA
# 3. 在stringA最后拼接上key得到stringSignTemp字符串并对stringSignTemp进行MD5运算再将得到的字符串所有字符转换为大写
stringA = f"appId={app_id}&nonceStr={nonce_str}&package={package}&signType={sign_type}&timeStamp={timestamp}"
string_sign_temp = f"{stringA}&key={wechat_config.api_key}"
pay_sign = hashlib.md5(string_sign_temp.encode('utf-8')).hexdigest().upper()
payment_params = {
'appId': app_id,
'timeStamp': timestamp,
'nonceStr': nonce_str,
'package': package,
'signType': sign_type,
'paySign': pay_sign,
'orderId': order.id,
'amount': str(order.total_price)
}
return Response(payment_params)
@action(detail=True, methods=['post'])
def confirm_payment(self, request, pk=None):
"""
模拟支付成功回调/确认
"""
order = self.get_object()
order.status = 'paid'
order.wechat_trade_no = f"WX_{str(uuid.uuid4())[:18]}"
order.save()
return Response({'status': 'success', 'message': '支付成功'})