增加 验证码的 qrcode url 获取。

This commit is contained in:
aaron 2025-02-12 22:08:46 +08:00
parent 9a92b4f29e
commit fd6a0ba830
3 changed files with 84 additions and 5 deletions

View File

@ -1,7 +1,7 @@
from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy.orm import Session
from sqlalchemy import func
from typing import List
from typing import List, Optional
from app.models.merchant_order import (
MerchantOrderDB,
MerchantOrderCreate,
@ -21,6 +21,13 @@ from app.core.wechat import WeChatClient
from pydantic import BaseModel
from app.core.config import settings
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()
@ -268,6 +275,8 @@ async def confirm_refund(
@router.get("/{order_id}", response_model=ResponseModel)
async def get_order_detail(
order_id: str,
longitude: Optional[float] = None,
latitude: Optional[float] = None,
db: Session = Depends(get_db),
current_user: UserDB = Depends(get_current_user)
):
@ -279,7 +288,13 @@ async def get_order_detail(
MerchantDB.name.label('merchant_name'),
MerchantDB.latitude.label('merchant_latitude'),
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(
MerchantProductDB,
MerchantOrderDB.merchant_product_id == MerchantProductDB.id
@ -317,7 +332,9 @@ async def get_order_detail(
"merchant_name": order.merchant_name,
"merchant_latitude": order.merchant_latitude,
"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)
@ -391,4 +408,63 @@ async def refund_merchant_order(
except Exception as e:
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)}")

View File

@ -21,6 +21,7 @@ class MerchantOrderDB(Base):
id = Column(Integer, primary_key=True, autoincrement=True)
order_id = Column(String(15), unique=True, nullable=False)
qrcode_url = Column(String(200)) # 核销码二维码图片地址
user_id = Column(Integer, ForeignKey("users.userid"), nullable=False)
merchant_product_id = Column(Integer, ForeignKey("merchant_products.id"), nullable=False)
order_amount = Column(DECIMAL(10,2), nullable=False)

View File

@ -13,4 +13,6 @@ tencentcloud-sdk-python==3.0.1035
cos-python-sdk-v5
bcrypt
aiohttp==3.9.1
cryptography==42.0.2
cryptography==42.0.2
qrcode>=7.3.1
pillow>=9.0.0