deliveryman-api/app/api/endpoints/order.py
2025-02-17 18:21:40 +08:00

924 lines
32 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 app.core.account import AccountManager
from fastapi import APIRouter, Depends
from sqlalchemy.orm import Session
from typing import List, Optional
from app.models.order import (
ShippingOrderDB,
ShippingOrderPackageDB,
OrderCreate,
OrderInfo,
OrderPackageInfo,
OrderPriceCalculateRequest,
OrderPriceInfo,
OrderStatus,
OrderCancel,
OrderComplete,
OrderPriceResult
)
from app.models.database import get_db
from app.api.deps import get_current_user, get_deliveryman_user, get_admin_user
from app.models.user import UserDB,UserRole
from app.core.response import success_response, error_response, ResponseModel
from app.models.coupon import UserCouponDB, CouponStatus
from datetime import datetime, timezone
from app.core.config import settings
from app.models.address import AddressDB
from sqlalchemy.orm import joinedload
from app.models.community import CommunityDB
from app.models.community_building import CommunityBuildingDB, CommunityBuildingInfo
from app.models.station import StationDB
from app.models.point import PointRecordDB, PointRecordType
from app.core.utils import CommonUtils
import logging
from sqlalchemy import func
router = APIRouter()
def calculate_price(price_request: OrderPriceCalculateRequest,user: UserDB,db: Session) -> OrderPriceResult:
"""
计算订单价格,自动使用优惠券或积分抵扣
Args:
price_request: 价格计算请求
user: 用户信息
Returns:
OrderPriceResult: 包含价格信息和使用的优惠券/积分信息
"""
# 计算所有包裹中的取件码总数
package_count = sum(
# 如果package.pickup_codes是空字符串则取0
0 if len(package.pickup_codes.split(',')) == 0 else len(package.pickup_codes.split(','))
for package in price_request.packages
if package.pickup_codes
)
result = OrderPriceResult(
price_info=OrderPriceInfo(
package_count=package_count,
original_amount=settings.ORDER_BASE_PRICE,
coupon_discount_amount=0,
points_discount_amount=0,
final_amount=settings.ORDER_BASE_PRICE
),
price_detail_text=settings.ORDER_PREORDER_PRICE_TEXT
)
original_amount = settings.ORDER_BASE_PRICE
# 超过阈值的包裹额外收费
if package_count > settings.ORDER_EXTRA_PACKAGE_THRESHOLD:
extra_count = package_count - settings.ORDER_EXTRA_PACKAGE_THRESHOLD
original_amount += extra_count * settings.ORDER_EXTRA_PACKAGE_PRICE
result.price_info.package_count = package_count
result.price_info.original_amount = original_amount
result.price_info.final_amount = original_amount
remaining_amount = original_amount
# 1. 查找用户可用的优惠券(按金额从大到小排序)
available_coupon = db.query(UserCouponDB).filter(
UserCouponDB.user_id == user.userid,
UserCouponDB.status == CouponStatus.UNUSED,
UserCouponDB.expire_time > datetime.now()
).order_by(UserCouponDB.coupon_amount.desc()).first()
# 2. 如果有可用优惠券,优先使用优惠券
if available_coupon:
coupon_discount = min(remaining_amount, available_coupon.coupon_amount)
result.price_info.coupon_discount_amount = coupon_discount
result.price_info.coupon_id = available_coupon.id
result.used_coupon_id = available_coupon.id
remaining_amount -= coupon_discount
# 3. 如果没有优惠券,且用户有积分,则使用积分抵扣
elif user.points > 0:
# 计算最大可抵扣金额
max_points_discount = user.points // settings.POINT_RATIO # 使用整除
points_discount_amount = min(remaining_amount, max_points_discount)
if points_discount_amount > 0:
result.price_info.points_discount_amount = points_discount_amount
result.used_points = int(points_discount_amount * settings.POINT_RATIO)
remaining_amount -= points_discount_amount
# 计算最终金额
result.price_info.final_amount = remaining_amount
return result
@router.post("/pre-order", response_model=ResponseModel)
async def pre_order(
request: OrderPriceCalculateRequest,
db: Session = Depends(get_db),
current_user: UserDB = Depends(get_current_user)
):
# 检查是否有未支付的订单
unpay_order = db.query(ShippingOrderDB).filter(
ShippingOrderDB.userid == current_user.userid,
ShippingOrderDB.status == OrderStatus.UNPAID
).first()
if unpay_order:
return error_response(code=400, message="存在未支付的订单", data={
"orderid": unpay_order.orderid
})
"""预下单 - 计算价格"""
price_info = calculate_price(request, current_user, db)
return success_response(data=price_info)
@router.post("", response_model=ResponseModel)
async def create_order(
order: OrderCreate,
db: Session = Depends(get_db),
current_user: UserDB = Depends(get_current_user)
):
"""创建配送订单"""
# 计算订单价格
price_result = calculate_price(order.price_request, current_user, db)
price_info = price_result.price_info
# 生成订单号
orderid = CommonUtils.generate_order_id('D')
# 计算原始金额
original_amount = price_info.original_amount
# 计算优惠券折扣
coupon_discount = price_info.coupon_discount_amount
coupon_id = price_info.coupon_id
# 查询用户优惠券
if coupon_id:
user_coupon = db.query(UserCouponDB).filter(
UserCouponDB.id == coupon_id
).first()
if user_coupon:
coupon_discount = user_coupon.coupon_amount
coupon_id = user_coupon.id
# 更新优惠券状态
user_coupon.status = CouponStatus.USED
# 查询地址信息
address = db.query(AddressDB).filter(
AddressDB.id == order.addressid
).first()
# 创建订单
db_order = ShippingOrderDB(
orderid=orderid,
userid=current_user.userid,
address_customer_name=address.name,
address_customer_phone=address.phone,
address_customer_gender=address.gender,
address_community_id=address.community_id,
address_community_building_id=address.community_building_id,
address_community_name=address.community_name,
address_community_building_name=address.community_building_name,
address_detail=address.address_detail,
package_count=price_info.package_count,
original_amount=original_amount,
coupon_discount_amount=coupon_discount,
point_discount_amount=price_info.points_discount_amount,
coupon_id=coupon_id,
final_amount=price_info.final_amount,
status=OrderStatus.CREATED,
delivery_method=order.delivery_method
)
db.add(db_order)
# 创建订单包裹
for package in order.price_request.packages:
# 如果包裹有取件码,则创建包裹
if len(package.pickup_codes) > 0:
station = db.query(StationDB).filter(
StationDB.id == package.station_id
).first()
db_package = ShippingOrderPackageDB(
orderid=orderid,
station_id=package.station_id,
station_name=station.name,
pickup_codes=package.pickup_codes
)
db.add(db_package)
try:
# 如果使用了优惠券,更新优惠券状态
if price_result.used_coupon_id:
coupon = db.query(UserCouponDB).filter(
UserCouponDB.id == price_result.used_coupon_id,
).first()
if coupon:
coupon.status = CouponStatus.USED
# 如果使用了积分,扣减用户积分并记录
if price_result.used_points:
# 扣减用户积分
current_user.points -= price_result.used_points
# 记录积分变动
point_record = PointRecordDB(
user_id=current_user.userid,
points=-price_result.used_points, # 负数表示扣减
type=PointRecordType.CONSUME_DEDUCT,
order_id=db_order.orderid,
description=f"配送订单抵扣积分"
)
db.add(point_record)
db.commit()
db.refresh(db_order)
# 查询包裹信息
packages = db.query(ShippingOrderPackageDB).filter(
ShippingOrderPackageDB.orderid == orderid
).all()
return success_response(
message="订单创建成功",
data={
"order": OrderInfo.model_validate(db_order),
"packages": [OrderPackageInfo.model_validate(p) for p in packages],
"success_text" : settings.ORDER_SUCCESS_TEXT
}
)
except Exception as e:
db.rollback()
return error_response(code=500, message=f"订单创建失败: {str(e)}")
@router.get("/{orderid}", response_model=ResponseModel)
async def get_order_detail(
orderid: str,
db: Session = Depends(get_db),
current_user: UserDB = Depends(get_current_user)
):
"""获取订单详情"""
# 使用 join 查询获取订单和相关地址信息
order = db.query(
ShippingOrderDB
).filter(
ShippingOrderDB.orderid == orderid
).first()
if not order:
return error_response(code=404, message="订单不存在")
# 检查权限
if order.userid != current_user.userid and UserRole.ADMIN not in current_user.roles:
return error_response(code=403, message="无权查看此订单")
# 查询包裹信息,包含驿站名称
packages = db.query(
ShippingOrderPackageDB,
StationDB.name.label('station_name')
).join(
StationDB,
ShippingOrderPackageDB.station_id == StationDB.id
).filter(
ShippingOrderPackageDB.orderid == orderid
).all()
# 如果有配送员 id则获取配送员信息
if order.deliveryman_user_id:
deliveryman_user = db.query(UserDB).filter(
UserDB.userid == order.deliveryman_user_id
).first()
deliveryman_user_name = deliveryman_user.nickname
deliveryman_user_avatar = deliveryman_user.optimized_avatar
deliveryman_user_phone = deliveryman_user.phone
delivery_count = db.query(ShippingOrderDB).filter(
ShippingOrderDB.deliveryman_user_id == order.deliveryman_user_id,
ShippingOrderDB.status == OrderStatus.COMPLETED
).count()
else:
deliveryman_user_name = None
delivery_count = 0
deliveryman_user_avatar = None
deliveryman_user_phone = None
# 构建响应数据
order_data = {
"orderid": order.orderid,
"userid": order.userid,
"package_count": order.package_count,
"original_amount": order.original_amount,
"coupon_discount_amount": order.coupon_discount_amount,
"coupon_id": order.coupon_id,
"final_amount": order.final_amount,
"status": order.status,
"complete_images": order.complete_images.split(",") if order.complete_images else None,
"create_time": order.create_time,
"delivery_method": order.delivery_method,
"deliveryman_user_id": order.deliveryman_user_id,
"deliveryman_nickname": deliveryman_user_name,
"deliveryman_avatar": deliveryman_user_avatar,
"deliveryman_phone": deliveryman_user_phone,
"delivery_count": delivery_count,
# 地址相关信息
"address_name": order.address_customer_name,
"address_phone": order.address_customer_phone,
"address_detail": order.address_detail,
"building_name": order.address_community_building_name,
"community_name": order.address_community_name
}
# 构建包裹信息,包含驿站名称
package_list = [{
"id": p.ShippingOrderPackageDB.id,
"orderid": p.ShippingOrderPackageDB.orderid,
"station_id": p.ShippingOrderPackageDB.station_id,
"station_name": p.station_name,
"pickup_codes": p.ShippingOrderPackageDB.pickup_codes,
"create_time": p.ShippingOrderPackageDB.create_time
} for p in packages]
return success_response(data={
"order": order_data,
"packages": package_list
})
# 提供一个接口传入community_id返回订单状态数量
@router.get("/status/count", response_model=ResponseModel)
async def get_order_status_count(
community_id: int,
db: Session = Depends(get_db),
current_user: UserDB = Depends(get_current_user)
):
"""获取社区订单状态数量"""
status_order_count = db.query(
ShippingOrderDB.status,
func.count(ShippingOrderDB.orderid)
).filter(
ShippingOrderDB.address_community_id == community_id
).group_by(
ShippingOrderDB.status
).all()
result = []
for status, count in status_order_count:
result.append({
"status": status,
"count": count
})
return success_response(data=result)
# 提供一个接口,传入 community_id 返回每栋楼栋的订单数量
@router.get("/community_building/count", response_model=ResponseModel)
async def get_community_building_order_count(
community_id: int,
db: Session = Depends(get_db),
current_user: UserDB = Depends(get_current_user)
):
"""获取社区每栋楼栋的订单数量"""
# 查询当前社区所有楼栋
community_buildings = db.query(
CommunityBuildingDB
).filter(
CommunityBuildingDB.community_id == community_id
).all()
if not community_buildings:
return error_response(code=404, message="社区不存在")
# 查询每个楼栋的订单数量
building_order_count = db.query(
ShippingOrderDB.address_community_building_name,
func.count(ShippingOrderDB.orderid)
).filter(
ShippingOrderDB.address_community_building_name.in_(
[building.building_name for building in community_buildings]
)
).group_by(
ShippingOrderDB.address_community_building_name
).all()
# 没有订单的楼栋订单数量为0
result = []
building_order_count_dict = dict(building_order_count)
for building in community_buildings:
if building.building_name not in building_order_count_dict:
result.append({
"building_name": building.building_name,
"order_count": 0
})
else:
result.append({
"building_name": building.building_name,
"order_count": building_order_count_dict[building.building_name]
})
return success_response(data=result)
@router.get("/user/list", response_model=ResponseModel)
async def get_user_orders(
status: Optional[OrderStatus] = None,
skip: int = 0,
limit: int = 20,
db: Session = Depends(get_db),
current_user: UserDB = Depends(get_current_user)
):
"""获取用户订单列表"""
try:
# 查询订单
query = db.query(
ShippingOrderDB
).filter(
ShippingOrderDB.userid == current_user.userid
)
# 添加状态过滤
if status:
query = query.filter(ShippingOrderDB.status == status)
# 获取总数
total = query.count()
# 分页查询
results = query.order_by(
ShippingOrderDB.create_time.desc()
).offset(skip).limit(limit).all()
orders = []
for order in results:
# 查询订单包裹信息
packages = db.query(
ShippingOrderPackageDB
).filter(
ShippingOrderPackageDB.orderid == order.orderid
).all()
# 格式化包裹信息
package_list = [{
"id": package.id,
"station_id": package.station_id,
"station_name": package.station_name,
"pickup_codes": package.pickup_codes
} for package in packages]
orders.append({
"orderid": order.orderid,
"userid": order.userid,
"status": order.status,
"package_count": order.package_count,
"create_time": order.create_time,
"delivery_method": order.delivery_method,
"original_amount": order.original_amount,
"coupon_discount_amount": order.coupon_discount_amount,
"point_discount_amount": order.point_discount_amount,
"final_amount": order.final_amount,
"packages": package_list,
"address": {
"name": order.address_customer_name,
"phone": order.address_customer_phone,
"community_id": order.address_community_id,
"community_name": order.address_community_name,
"building_id": order.address_community_building_id,
"building_name": order.address_community_building_name,
"address_detail": order.address_detail
}
})
return success_response(data={
"total": total,
"items": orders
})
except Exception as e:
return error_response(code=500, message=f"获取订单列表失败: {str(e)}")
@router.post("/{orderid}/user/cancel", response_model=ResponseModel)
async def cancel_order(
orderid: str,
db: Session = Depends(get_db),
current_user: UserDB = Depends(get_current_user)
):
"""取消订单"""
# 查询订单
order = db.query(ShippingOrderDB).filter(
ShippingOrderDB.orderid == orderid,
ShippingOrderDB.userid == current_user.userid
).first()
if not order:
return error_response(code=404, message="订单不存在")
# 检查订单状态是否可取消
if order.status not in [OrderStatus.CREATED, OrderStatus.RECEIVED]:
return error_response(code=400, message="当前订单状态不可取消")
try:
# 更新订单状态、取消原因和取消用户
order.status = OrderStatus.CANCELLED
order.cancel_reason = "用户主动取消"
order.cancel_user_id = current_user.userid # 记录取消订单的用户ID
# 如果使用了优惠券,返还优惠券
if order.coupon_id:
coupon = db.query(UserCouponDB).filter(
UserCouponDB.id == order.coupon_id
).first()
if coupon:
coupon.status = CouponStatus.UNUSED
# 如果使用了积分,返还积分
if order.point_discount_amount > 0:
# 返还积分
return_points = int(order.point_discount_amount * settings.POINT_RATIO)
current_user.points += return_points
# 记录积分变动
point_record = PointRecordDB(
user_id=current_user.userid,
points=return_points,
type=PointRecordType.CONSUME_RETURN,
order_id=order.orderid,
description=f"订单取消返还积分"
)
db.add(point_record)
db.commit()
return success_response(
message="订单取消成功",
data=OrderInfo.model_validate(order)
)
except Exception as e:
db.rollback()
return error_response(code=500, message=f"取消订单失败: {str(e)}")
@router.get("/deliveryman/list", response_model=ResponseModel)
async def get_deliveryman_orders(
status: Optional[OrderStatus] = None,
building_name: Optional[str] = None,
skip: int = 0,
limit: int = 20,
db: Session = Depends(get_db),
deliveryman: UserDB = Depends(get_deliveryman_user)
):
"""获取配送员订单列表"""
# 基础查询
query = db.query(
ShippingOrderDB
)
# 状态筛选
if status:
query = query.filter(ShippingOrderDB.status == status)
# 楼栋筛选
if building_name:
query = query.filter(ShippingOrderDB.address_community_building_name == building_name)
# 获取总数
total = query.count()
# 获取分页数据
results = query.order_by(
ShippingOrderDB.create_time.desc()
).offset(skip).limit(limit).all()
# 格式化返回数据
orders = []
for order in results:
# 查询订单包裹信息
packages = db.query(
ShippingOrderPackageDB,
StationDB.name.label('station_name')
).join(
StationDB,
ShippingOrderPackageDB.station_id == StationDB.id
).filter(
ShippingOrderPackageDB.orderid == order.orderid
).all()
# 格式化包裹信息
package_list = [{
"id": package.ShippingOrderPackageDB.id,
"station_id": package.ShippingOrderPackageDB.station_id,
"station_name": package.station_name,
"pickup_codes": package.ShippingOrderPackageDB.pickup_codes
} for package in packages]
orders.append({
"orderid": order.orderid,
"userid": order.userid,
"status": order.status,
"package_count": order.package_count,
"create_time": order.create_time,
"delivery_method": order.delivery_method,
"packages": package_list,
"address": {
"name": order.address_customer_name,
"phone": order.address_customer_phone,
"community_name": order.address_community_name,
"building_name": order.address_community_building_name,
"address_detail": order.address_detail
},
"complete_images": order.complete_images.split(",") if order.complete_images else None,
"received_time": order.received_time,
"pickup_time": order.pickup_time,
"completed_time": order.completed_time
})
return success_response(data={
"total": total,
"items": orders
})
@router.post("/{orderid}/deliveryman/cancel", response_model=ResponseModel)
async def deliveryman_cancel_order(
orderid: str,
cancel_data: OrderCancel,
db: Session = Depends(get_db),
deliveryman: UserDB = Depends(get_deliveryman_user)
):
"""配送员取消订单"""
order = db.query(ShippingOrderDB).filter(
ShippingOrderDB.orderid == orderid,
ShippingOrderDB.deliveryman_user_id == deliveryman.userid
).first()
if not order:
return error_response(code=404, message="订单不存在")
# 检查订单状态
if order.status != OrderStatus.CREATED and order.status != OrderStatus.RECEIVED:
return error_response(code=400, message="只有未接单或者已接单的订单才能取消")
try:
# 更新订单状态、取消原因和取消用户
order.status = OrderStatus.CANCELLED
order.cancel_reason = cancel_data.reason
order.cancel_user_id = deliveryman.userid
# 如果使用了优惠券,返还优惠券
if order.coupon_id:
coupon = db.query(UserCouponDB).filter(
UserCouponDB.id == order.coupon_id
).first()
if coupon:
coupon.status = CouponStatus.UNUSED
# 如果使用了积分,返还积分
if order.point_discount_amount > 0:
# 返还积分
return_points = int(order.point_discount_amount * settings.POINT_RATIO)
order_user = db.query(UserDB).filter(
UserDB.userid == order.userid
).first()
order_user.points += return_points
# 记录积分变动
point_record = PointRecordDB(
user_id=order_user.userid,
points=return_points,
type=PointRecordType.CONSUME_RETURN,
order_id=order.orderid,
description=f"订单取消返还积分"
)
db.add(point_record)
db.commit()
return success_response(
message="订单取消成功",
data=OrderInfo.model_validate(order)
)
except Exception as e:
db.rollback()
return error_response(code=500, message=f"取消订单失败: {str(e)}")
@router.post("/{orderid}/deliveryman/complete", response_model=ResponseModel)
async def complete_order(
orderid: str,
complete_data: OrderComplete,
db: Session = Depends(get_db),
current_user: UserDB = Depends(get_deliveryman_user)
):
"""完成订单"""
# 查询订单
order = db.query(ShippingOrderDB).filter(
ShippingOrderDB.orderid == orderid,
ShippingOrderDB.deliveryman_user_id == current_user.userid
).first()
if not order:
return error_response(code=404, message="订单不存在")
# 检查订单状态
if order.status != OrderStatus.DELIVERING:
return error_response(code=400, message="只有配送中的订单才能标记为完成")
try:
# 根据订单金额决定状态
if order.final_amount > 0:
order.status = OrderStatus.UNPAID # 需要支付
else:
order.status = OrderStatus.COMPLETED # 无需支付,直接完成
# 只有在订单完成状态时才进行分账
# 计算配送员分账金额
deliveryman_share = order.original_amount * settings.ORDER_DELIVERYMAN_SHARE_RATIO
# 使用账户管理器处理分账
account_manager = AccountManager(db)
account_manager.change_balance(
user_id=order.deliveryman_user_id,
amount=deliveryman_share,
description=f"配送订单收益",
transaction_id=orderid
)
# 保存完成图片
if complete_data.images:
order.complete_images = ",".join(complete_data.images)
# 更新完成时间
order.completed_time = datetime.now()
db.commit()
return success_response(
message="订单已完成" if order.final_amount == 0 else "请继续支付",
data=OrderInfo.model_validate(order)
)
except Exception as e:
db.rollback()
return error_response(code=500, message=f"操作失败: {str(e)}")
@router.post("/{orderid}/deliveryman/receive", response_model=ResponseModel)
async def receive_order(
orderid: str,
db: Session = Depends(get_db),
deliveryman: UserDB = Depends(get_deliveryman_user)
):
"""接单(仅配送员可用)"""
# 查询订单
order = db.query(ShippingOrderDB).filter(
ShippingOrderDB.orderid == orderid
).first()
if not order:
return error_response(code=404, message="订单不存在")
# 检查订单状态
if order.status != OrderStatus.CREATED:
return error_response(code=400, message="只能接待新创建的订单")
# 检查订单是否已被接单
if order.deliveryman_user_id is not None:
return error_response(code=400, message="订单已被其他配送员接单")
try:
# 更新订单状态和配送员ID
order.status = OrderStatus.RECEIVED
order.deliveryman_user_id = deliveryman.userid
order.received_time = datetime.now()
db.commit()
return success_response(
message="接单成功",
data=OrderInfo.model_validate(order)
)
except Exception as e:
db.rollback()
return error_response(code=500, message=f"接单失败: {str(e)}")
@router.post("/{orderid}/deliveryman/pickup", response_model=ResponseModel)
async def pickup_order(
orderid: str,
db: Session = Depends(get_db),
deliveryman: UserDB = Depends(get_deliveryman_user)
):
"""标记订单为已取货(仅配送员可用)"""
# 查询订单
order = db.query(ShippingOrderDB).filter(
ShippingOrderDB.orderid == orderid,
ShippingOrderDB.deliveryman_user_id == deliveryman.userid # 必须是该配送员的订单
).first()
if not order:
return error_response(code=404, message="订单不存在")
# 检查订单状态
if order.status != OrderStatus.RECEIVED:
return error_response(code=400, message="只有已接单的订单才能标记为已取货")
try:
# 更新订单状态为配送中
order.status = OrderStatus.DELIVERING
order.pickup_time = datetime.now()
db.commit()
return success_response(
message="已标记为取货",
data=OrderInfo.model_validate(order)
)
except Exception as e:
db.rollback()
return error_response(code=500, message=f"操作失败: {str(e)}")
@router.get("/admin/list", response_model=ResponseModel)
async def get_admin_orders(
status: Optional[OrderStatus] = None,
user_id: Optional[int] = None,
order_id: Optional[str] = None,
skip: int = 0,
limit: int = 20,
db: Session = Depends(get_db),
admin_user: UserDB = Depends(get_admin_user)
):
"""获取订单列表(管理员接口)
Args:
status: 订单状态过滤
user_id: 用户ID过滤
order_id: 订单号过滤
skip: 跳过记录数
limit: 返回记录数
"""
try:
# 构建基础查询
query = db.query(ShippingOrderDB)
# 添加用户ID过滤
if user_id:
query = query.filter(ShippingOrderDB.userid == user_id)
# 添加状态过滤
if status:
query = query.filter(ShippingOrderDB.status == status)
# 添加订单号过滤
if order_id:
query = query.filter(ShippingOrderDB.orderid == order_id)
# 获取总数
total = query.count()
# 分页查询
results = query.order_by(
ShippingOrderDB.create_time.desc()
).offset(skip).limit(limit).all()
orders = []
for order in results:
# 查询订单包裹信息
packages = db.query(
ShippingOrderPackageDB,
StationDB.name.label('station_name')
).join(
StationDB,
ShippingOrderPackageDB.station_id == StationDB.id
).filter(
ShippingOrderPackageDB.orderid == order.orderid
).all()
# 格式化包裹信息
package_list = [{
"id": package.ShippingOrderPackageDB.id,
"station_id": package.ShippingOrderPackageDB.station_id,
"station_name": package.station_name,
"pickup_codes": package.ShippingOrderPackageDB.pickup_codes
} for package in packages]
orders.append({
"orderid": order.orderid,
"userid": order.userid,
"status": order.status,
"package_count": order.package_count,
"create_time": order.create_time,
"delivery_method": order.delivery_method,
"original_amount": order.original_amount,
"coupon_discount_amount": order.coupon_discount_amount,
"point_discount_amount": order.point_discount_amount,
"final_amount": order.final_amount,
"packages": package_list,
"address": {
"name": order.address_customer_name,
"phone": order.address_customer_phone,
"community_name": order.address_community_name,
"building_name": order.address_community_building_name,
"address_detail": order.address_detail
}
})
return success_response(data={
"total": total,
"items": orders
})
except Exception as e:
logging.exception(f"获取订单列表失败: {str(e)}")
return error_response(code=500, message=f"获取订单列表失败: {str(e)}")