coupon 增加类型 和 核销功能。
This commit is contained in:
parent
0d2e503965
commit
c0ec42ca8a
@ -36,6 +36,33 @@ async def create_coupon(
|
||||
except Exception as e:
|
||||
db.rollback()
|
||||
return error_response(code=500, message=f"创建优惠券失败: {str(e)}")
|
||||
|
||||
|
||||
@router.put("/{coupon_id}/beused", response_model=ResponseModel)
|
||||
async def beused_coupon(
|
||||
coupon_id: int,
|
||||
db: Session = Depends(get_db),
|
||||
current_user: UserDB = Depends(get_current_user)
|
||||
):
|
||||
""" 使用优惠券 """
|
||||
|
||||
coupon = db.query(UserCouponDB).filter(
|
||||
UserCouponDB.id == coupon_id,
|
||||
UserCouponDB.user_id == current_user.userid,
|
||||
UserCouponDB.status == CouponStatus.UNUSED,
|
||||
UserCouponDB.expire_time > datetime.now()
|
||||
).first()
|
||||
|
||||
if not coupon:
|
||||
return error_response(code=404, message="优惠券不存在")
|
||||
|
||||
coupon.status = CouponStatus.USED
|
||||
coupon.used_time = datetime.now()
|
||||
|
||||
db.commit()
|
||||
|
||||
return success_response(data=CouponInfo.model_validate(coupon))
|
||||
|
||||
|
||||
@router.put("/{coupon_id}", response_model=ResponseModel)
|
||||
async def update_coupon(
|
||||
|
||||
@ -19,7 +19,7 @@ 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 app.models.coupon import UserCouponDB, CouponStatus, CouponType
|
||||
from app.models.point_product_order import PointProductOrderDB, PointProductOrderInfo, PointProductOrderStatus
|
||||
from datetime import datetime, timezone
|
||||
from app.core.config import settings
|
||||
@ -115,6 +115,7 @@ def calculate_price(price_request: OrderPriceCalculateRequest,user: UserDB,db: S
|
||||
# 1. 查找用户可用的优惠券(按金额从大到小排序)
|
||||
available_coupon = db.query(UserCouponDB).filter(
|
||||
UserCouponDB.user_id == user.userid,
|
||||
UserCouponDB.coupon_type == CouponType.CASH,
|
||||
UserCouponDB.status == CouponStatus.UNUSED,
|
||||
UserCouponDB.expire_time > datetime.now()
|
||||
).order_by(UserCouponDB.coupon_amount.desc()).first()
|
||||
@ -192,7 +193,7 @@ async def create_order(
|
||||
# 查询用户优惠券
|
||||
if coupon_id:
|
||||
user_coupon = db.query(UserCouponDB).filter(
|
||||
UserCouponDB.id == coupon_id
|
||||
UserCouponDB.id == coupon_id,
|
||||
).first()
|
||||
|
||||
if user_coupon:
|
||||
@ -268,6 +269,7 @@ async def create_order(
|
||||
).first()
|
||||
if coupon:
|
||||
coupon.status = CouponStatus.USED
|
||||
coupon.used_time = datetime.now()
|
||||
|
||||
# 如果使用了积分,扣减用户积分并记录
|
||||
if price_result.used_points:
|
||||
@ -672,6 +674,7 @@ async def cancel_order(
|
||||
).first()
|
||||
if coupon:
|
||||
coupon.status = CouponStatus.UNUSED
|
||||
coupon.used_time = None
|
||||
|
||||
# 检查子订单是否全部取消
|
||||
sub_orders = db.query(PointProductOrderDB).filter(
|
||||
@ -877,6 +880,7 @@ async def deliveryman_cancel_order(
|
||||
).first()
|
||||
if coupon:
|
||||
coupon.status = CouponStatus.UNUSED
|
||||
coupon.used_time = None
|
||||
|
||||
# 检查子订单是否全部取消
|
||||
sub_orders = db.query(PointProductOrderDB).filter(
|
||||
|
||||
@ -24,6 +24,8 @@ from app.core.qcloud import qcloud_manager
|
||||
from app.models.merchant import MerchantDB
|
||||
from app.models.address import AddressDB, AddressInfo
|
||||
from app.models.user import UserUpdateRoles, UserUpdateDeliveryCommissionRate
|
||||
from app.models.order import ShippingOrderDB
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
# Redis 连接
|
||||
@ -343,6 +345,8 @@ async def password_login(
|
||||
|
||||
@router.get("/referrals", response_model=ResponseModel)
|
||||
async def get_referral_users(
|
||||
skip: int = 0,
|
||||
limit: int = 10,
|
||||
db: Session = Depends(get_db),
|
||||
current_user: UserDB = Depends(get_current_user)
|
||||
):
|
||||
@ -351,19 +355,30 @@ async def get_referral_users(
|
||||
UserDB.referral_code == current_user.user_code
|
||||
).order_by(
|
||||
UserDB.create_time.desc()
|
||||
).all()
|
||||
).offset(skip).limit(limit).all()
|
||||
|
||||
# 处理手机号脱敏
|
||||
def mask_phone(phone: str) -> str:
|
||||
return f"{phone[:3]}****{phone[7:]}"
|
||||
total = db.query(UserDB).filter(
|
||||
UserDB.referral_code == current_user.user_code
|
||||
).count()
|
||||
|
||||
user_list = []
|
||||
|
||||
# 获取用户是否下单
|
||||
for user in referral_users:
|
||||
u = ReferralUserInfo.model_validate(user).model_dump()
|
||||
|
||||
order_count = db.query(ShippingOrderDB).filter(
|
||||
ShippingOrderDB.userid == user.userid
|
||||
).count()
|
||||
|
||||
u['is_place_order'] = order_count > 0
|
||||
u['phone'] = f"{u['phone'][:3]}****{u['phone'][7:]}"
|
||||
user_list.append(u)
|
||||
|
||||
return success_response(data=[
|
||||
ReferralUserInfo(
|
||||
nickname=user.nickname,
|
||||
phone=mask_phone(user.phone),
|
||||
create_time=user.create_time
|
||||
) for user in referral_users
|
||||
])
|
||||
return success_response(data={
|
||||
"total": total,
|
||||
"items": user_list
|
||||
})
|
||||
|
||||
def issue_register_coupons(db: Session, user_id: int):
|
||||
"""发放注册优惠券
|
||||
|
||||
@ -85,7 +85,6 @@ async def exception_handler(request, exc):
|
||||
**请求信息**
|
||||
> 请求方法:{request.method}
|
||||
> 请求URL:{request.url}
|
||||
> 请求头:{request.headers}
|
||||
> 请求体:{request.body}
|
||||
|
||||
**异常信息**
|
||||
@ -96,5 +95,8 @@ async def exception_handler(request, exc):
|
||||
|
||||
return CustomJSONResponse(
|
||||
status_code=500,
|
||||
content=str(exc)
|
||||
content={
|
||||
"code": 500,
|
||||
"message": str(exc)
|
||||
}
|
||||
)
|
||||
@ -11,6 +11,10 @@ class CouponStatus(str, enum.Enum):
|
||||
USED = "USED"
|
||||
EXPIRED = "EXPIRED"
|
||||
|
||||
class CouponType(str, enum.Enum):
|
||||
PRODUCT = "PRODUCT" # 商品
|
||||
CASH = "CASH" # 现金
|
||||
|
||||
# 数据库模型
|
||||
class CouponDB(Base):
|
||||
__tablename__ = "coupons"
|
||||
@ -18,6 +22,7 @@ class CouponDB(Base):
|
||||
id = Column(Integer, primary_key=True, autoincrement=True)
|
||||
name = Column(String(100), nullable=False)
|
||||
amount = Column(Float, nullable=False)
|
||||
coupon_type = Column(Enum(CouponType), nullable=False, default=CouponType.CASH)
|
||||
create_time = Column(DateTime(timezone=True), server_default=func.now())
|
||||
update_time = Column(DateTime(timezone=True), onupdate=func.now())
|
||||
|
||||
@ -28,8 +33,10 @@ class UserCouponDB(Base):
|
||||
user_id = Column(Integer, ForeignKey("users.userid"), index=True)
|
||||
coupon_id = Column(Integer, ForeignKey("coupons.id"), index=True)
|
||||
coupon_name = Column(String(100), nullable=False)
|
||||
coupon_type = Column(Enum(CouponType), nullable=False)
|
||||
coupon_amount = Column(Float, nullable=False)
|
||||
expire_time = Column(DateTime(timezone=True), nullable=False)
|
||||
used_time = Column(DateTime(timezone=True), nullable=True)
|
||||
status = Column(Enum(CouponStatus), default=CouponStatus.UNUSED)
|
||||
create_time = Column(DateTime(timezone=True), server_default=func.now())
|
||||
update_time = Column(DateTime(timezone=True), onupdate=func.now())
|
||||
@ -37,16 +44,19 @@ class UserCouponDB(Base):
|
||||
# Pydantic 模型
|
||||
class CouponCreate(BaseModel):
|
||||
name: str = Field(..., max_length=100)
|
||||
amount: float = Field(..., gt=0)
|
||||
amount: Optional[float] = Field(None, gt=0)
|
||||
coupon_type: CouponType = Field(CouponType.CASH)
|
||||
|
||||
class CouponUpdate(BaseModel):
|
||||
name: Optional[str] = Field(None, max_length=100)
|
||||
amount: Optional[float] = Field(None, gt=0)
|
||||
coupon_type: CouponType = Field(CouponType.CASH)
|
||||
|
||||
class CouponInfo(BaseModel):
|
||||
id: int
|
||||
name: str
|
||||
amount: float
|
||||
coupon_type: CouponType
|
||||
create_time: datetime
|
||||
|
||||
class Config:
|
||||
@ -64,7 +74,9 @@ class UserCouponInfo(BaseModel):
|
||||
coupon_id: int
|
||||
coupon_name: str
|
||||
coupon_amount: float
|
||||
coupon_type: CouponType
|
||||
expire_time: datetime
|
||||
used_time: datetime
|
||||
status: CouponStatus
|
||||
create_time: datetime
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user