增加 验证码的 qrcode url 获取。
This commit is contained in:
parent
9a92b4f29e
commit
fd6a0ba830
@ -1,7 +1,7 @@
|
|||||||
from fastapi import APIRouter, Depends, HTTPException
|
from fastapi import APIRouter, Depends, HTTPException
|
||||||
from sqlalchemy.orm import Session
|
from sqlalchemy.orm import Session
|
||||||
from sqlalchemy import func
|
from sqlalchemy import func
|
||||||
from typing import List
|
from typing import List, Optional
|
||||||
from app.models.merchant_order import (
|
from app.models.merchant_order import (
|
||||||
MerchantOrderDB,
|
MerchantOrderDB,
|
||||||
MerchantOrderCreate,
|
MerchantOrderCreate,
|
||||||
@ -21,6 +21,13 @@ from app.core.wechat import WeChatClient
|
|||||||
from pydantic import BaseModel
|
from pydantic import BaseModel
|
||||||
from app.core.config import settings
|
from app.core.config import settings
|
||||||
from app.core.utils import CommonUtils
|
from app.core.utils import CommonUtils
|
||||||
|
from sqlalchemy.sql import text
|
||||||
|
import qrcode
|
||||||
|
import io
|
||||||
|
from fastapi import UploadFile
|
||||||
|
from app.core.qcloud import qcloud_manager
|
||||||
|
from app.core.imageprocessor import process_image, ImageFormat
|
||||||
|
from starlette.datastructures import Headers
|
||||||
|
|
||||||
router = APIRouter()
|
router = APIRouter()
|
||||||
|
|
||||||
@ -268,6 +275,8 @@ async def confirm_refund(
|
|||||||
@router.get("/{order_id}", response_model=ResponseModel)
|
@router.get("/{order_id}", response_model=ResponseModel)
|
||||||
async def get_order_detail(
|
async def get_order_detail(
|
||||||
order_id: str,
|
order_id: str,
|
||||||
|
longitude: Optional[float] = None,
|
||||||
|
latitude: Optional[float] = None,
|
||||||
db: Session = Depends(get_db),
|
db: Session = Depends(get_db),
|
||||||
current_user: UserDB = Depends(get_current_user)
|
current_user: UserDB = Depends(get_current_user)
|
||||||
):
|
):
|
||||||
@ -279,7 +288,13 @@ async def get_order_detail(
|
|||||||
MerchantDB.name.label('merchant_name'),
|
MerchantDB.name.label('merchant_name'),
|
||||||
MerchantDB.latitude.label('merchant_latitude'),
|
MerchantDB.latitude.label('merchant_latitude'),
|
||||||
MerchantDB.longitude.label('merchant_longitude'),
|
MerchantDB.longitude.label('merchant_longitude'),
|
||||||
MerchantDB.phone.label('merchant_phone')
|
MerchantDB.phone.label('merchant_phone'),
|
||||||
|
text("CASE WHEN :lat IS NOT NULL AND :lon IS NOT NULL THEN "
|
||||||
|
"ST_Distance_Sphere(point(merchants.longitude, merchants.latitude), point(:lon, :lat)) "
|
||||||
|
"ELSE NULL END as distance").params(
|
||||||
|
lat=latitude,
|
||||||
|
lon=longitude
|
||||||
|
) if longitude and latitude else text("NULL as distance")
|
||||||
).join(
|
).join(
|
||||||
MerchantProductDB,
|
MerchantProductDB,
|
||||||
MerchantOrderDB.merchant_product_id == MerchantProductDB.id
|
MerchantOrderDB.merchant_product_id == MerchantProductDB.id
|
||||||
@ -317,7 +332,9 @@ async def get_order_detail(
|
|||||||
"merchant_name": order.merchant_name,
|
"merchant_name": order.merchant_name,
|
||||||
"merchant_latitude": order.merchant_latitude,
|
"merchant_latitude": order.merchant_latitude,
|
||||||
"merchant_longitude": order.merchant_longitude,
|
"merchant_longitude": order.merchant_longitude,
|
||||||
"merchant_phone": order.merchant_phone
|
"merchant_phone": order.merchant_phone,
|
||||||
|
# 距离信息
|
||||||
|
"distance": round(order.distance) if order.distance else None
|
||||||
}
|
}
|
||||||
|
|
||||||
return success_response(data=order_data)
|
return success_response(data=order_data)
|
||||||
@ -391,4 +408,63 @@ async def refund_merchant_order(
|
|||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
db.rollback()
|
db.rollback()
|
||||||
return error_response(code=500, message=f"处理退款失败: {str(e)}")
|
return error_response(code=500, message=f"处理退款失败: {str(e)}")
|
||||||
|
|
||||||
|
@router.get("/{order_id}/verify-qrcode", response_model=ResponseModel)
|
||||||
|
async def get_order_qrcode(
|
||||||
|
order_id: str,
|
||||||
|
db: Session = Depends(get_db),
|
||||||
|
current_user: UserDB = Depends(get_current_user)
|
||||||
|
):
|
||||||
|
"""获取订单核销二维码"""
|
||||||
|
# 查询订单
|
||||||
|
order = db.query(MerchantOrderDB).filter(
|
||||||
|
MerchantOrderDB.order_id == order_id
|
||||||
|
).first()
|
||||||
|
|
||||||
|
if not order:
|
||||||
|
return error_response(code=404, message="订单不存在")
|
||||||
|
|
||||||
|
# 如果已经有二维码,直接返回
|
||||||
|
if order.qrcode_url:
|
||||||
|
url = process_image(order.qrcode_url).thumbnail(800, 800).format(ImageFormat.WEBP).quality(90).build()
|
||||||
|
return success_response(data={"qrcode_url":url})
|
||||||
|
|
||||||
|
try:
|
||||||
|
# 生成二维码
|
||||||
|
qr = qrcode.QRCode(
|
||||||
|
version=1,
|
||||||
|
error_correction=qrcode.constants.ERROR_CORRECT_L,
|
||||||
|
box_size=10,
|
||||||
|
border=1,
|
||||||
|
)
|
||||||
|
qr.add_data(order.order_verify_code)
|
||||||
|
qr.make(fit=True)
|
||||||
|
|
||||||
|
# 创建图片
|
||||||
|
img = qr.make_image(fill_color="black", back_color="white")
|
||||||
|
|
||||||
|
# 将图片转换为字节流
|
||||||
|
img_byte_arr = io.BytesIO()
|
||||||
|
img.save(img_byte_arr, format='PNG')
|
||||||
|
img_byte_arr.seek(0)
|
||||||
|
|
||||||
|
# 创建 UploadFile 对象
|
||||||
|
file = UploadFile(
|
||||||
|
file=img_byte_arr,
|
||||||
|
filename=f"qrcode_{order_id}.png",
|
||||||
|
headers=Headers({"content-type": "image/png"})
|
||||||
|
)
|
||||||
|
|
||||||
|
# 上传到腾讯云
|
||||||
|
url = await qcloud_manager.upload_file(file)
|
||||||
|
|
||||||
|
# 更新订单的二维码URL
|
||||||
|
order.qrcode_url = url
|
||||||
|
db.commit()
|
||||||
|
|
||||||
|
process_url = process_image(url).thumbnail(800, 800).format(ImageFormat.WEBP).quality(90).build()
|
||||||
|
return success_response(data={"qrcode_url": process_url})
|
||||||
|
except Exception as e:
|
||||||
|
db.rollback()
|
||||||
|
return error_response(code=500, message=f"生成二维码失败: {str(e)}")
|
||||||
@ -21,6 +21,7 @@ class MerchantOrderDB(Base):
|
|||||||
|
|
||||||
id = Column(Integer, primary_key=True, autoincrement=True)
|
id = Column(Integer, primary_key=True, autoincrement=True)
|
||||||
order_id = Column(String(15), unique=True, nullable=False)
|
order_id = Column(String(15), unique=True, nullable=False)
|
||||||
|
qrcode_url = Column(String(200)) # 核销码二维码图片地址
|
||||||
user_id = Column(Integer, ForeignKey("users.userid"), nullable=False)
|
user_id = Column(Integer, ForeignKey("users.userid"), nullable=False)
|
||||||
merchant_product_id = Column(Integer, ForeignKey("merchant_products.id"), nullable=False)
|
merchant_product_id = Column(Integer, ForeignKey("merchant_products.id"), nullable=False)
|
||||||
order_amount = Column(DECIMAL(10,2), nullable=False)
|
order_amount = Column(DECIMAL(10,2), nullable=False)
|
||||||
|
|||||||
@ -13,4 +13,6 @@ tencentcloud-sdk-python==3.0.1035
|
|||||||
cos-python-sdk-v5
|
cos-python-sdk-v5
|
||||||
bcrypt
|
bcrypt
|
||||||
aiohttp==3.9.1
|
aiohttp==3.9.1
|
||||||
cryptography==42.0.2
|
cryptography==42.0.2
|
||||||
|
qrcode>=7.3.1
|
||||||
|
pillow>=9.0.0
|
||||||
Loading…
Reference in New Issue
Block a user