from fastapi import HTTPException from datetime import datetime from ..db import get_connection from ..utils.jwt_handler import verify_token def get_user_coupons_service(token: str): """获取用户所有优惠券""" try: payload = verify_token(token) # 新增:通过phone_number查询用户ID connection = get_connection() cursor = connection.cursor(dictionary=True) cursor.execute("SELECT user_id FROM users WHERE phone_number = %s", (payload["sub"],)) user = cursor.fetchone() if not user: raise HTTPException(status_code=404, detail="用户不存在") user_id = user['user_id'] # 获取有效期内且未被使用的优惠券 cursor.execute(""" SELECT c.* FROM user_coupons uc JOIN coupons c ON uc.coupon_id = c.coupon_id WHERE uc.user_id = %s AND c.valid_from <= NOW() AND c.valid_to >= NOW() """, (user_id,)) coupons = [] for coupon in cursor.fetchall(): # 生成描述文字 if coupon['discount_type'] == 'fixed': desc = f"满{coupon['min_order_amount'] or 0}元,减{coupon['discount_amount']}元" else: # 转换百分比折扣为中文(如85 -> 八五折) discount = int(coupon['discount_amount']) chinese_num = ''.join(['〇一二三四五六七八九'[int(d)] for d in str(discount)]) desc = f"满{coupon['min_order_amount'] or 0}元,打{chinese_num}折" coupons.append({ "coupon_id": coupon['coupon_id'], "description": desc }) return coupons except Exception as e: raise HTTPException(status_code=500, detail=str(e)) def apply_coupon_service(token: str, coupon_id: int, order_id: float): """使用优惠券计算价格""" try: payload = verify_token(token) # 新增:通过phone_number查询用户ID connection = get_connection() cursor = connection.cursor(dictionary=True) cursor.execute("SELECT user_id FROM users WHERE phone_number = %s", (payload["sub"],)) user = cursor.fetchone() if not user: raise HTTPException(status_code=404, detail="用户不存在") user_id = user['user_id'] # 验证优惠券归属 cursor.execute(""" SELECT c.* FROM user_coupons uc JOIN coupons c ON uc.coupon_id = c.coupon_id WHERE uc.user_id = %s AND uc.coupon_id = %s AND c.valid_from <= NOW() AND c.valid_to >= NOW() LIMIT 1 """, (user_id, coupon_id)) coupon = cursor.fetchone() if not coupon: raise HTTPException(status_code=400, detail="无效优惠券") # print(coupon) discount_amount = float(coupon['discount_amount']) min_order_amount = float(coupon['min_order_amount']) if coupon['min_order_amount'] else None # discount_amount = 0.0 # min_order_amount = 0.0 cursor.execute(""" SELECT payable_price FROM orders WHERE order_id = %s AND user_id = %s AND order_status = 'pending' """, (order_id, user['user_id'])) order = cursor.fetchone() price = float(order['payable_price']) # 检查最低消费 if coupon['min_order_amount'] and price < min_order_amount: raise HTTPException(status_code=400, detail="未达到最低消费金额") # 计算折扣 if coupon['discount_type'] == 'fixed': final_price = max(price - discount_amount, 0) else: discount = price * (discount_amount / 100) final_price = max(discount, 0) return {"final_price": round(final_price, 2)} except Exception as e: raise HTTPException(status_code=500, detail=str(e)) finally: cursor.close() connection.close()