This commit is contained in:
aaron 2025-03-06 13:37:43 +08:00
parent 08c648bc88
commit 27d014c2bf
8 changed files with 74 additions and 26 deletions

View File

@ -20,8 +20,8 @@ async def get_current_user(
if not token:
raise HTTPException(status_code=401, detail="未提供有效的认证信息")
phone = verify_token(token)
if not phone:
sub, phone = verify_token(token)
if not sub:
raise HTTPException(status_code=401, detail="Token已过期或无效")
user = db.query(UserDB).filter(UserDB.phone == phone).first()

View File

@ -18,7 +18,7 @@ from typing import List, Optional
import logging
from sqlalchemy.orm import joinedload
from app.core.redis_client import redis_client
from datetime import datetime
from datetime import datetime, timedelta
router = APIRouter()
@router.post("", response_model=ResponseModel)
@ -120,21 +120,52 @@ async def get_community_time_periods(
).order_by(TimePeriodDB.from_time).all()
result = []
tomorrow_count=0
today_date = datetime.now().date()
tomorrow_date = today_date + timedelta(days=1)
# 构建今日配送时段
for ctp in community_time_periods:
# 获取今日订单数量
today_orders_count = redis_client.get_community_period_today_orders_count(ctp.CommunityTimePeriodDB.id)
today_orders_count = redis_client.get_community_period_orders_count(today_date,ctp.CommunityTimePeriodDB.id)
# 如果已经过了时段,则不加入列表
if datetime.now().time() > ctp.time_period_to_time:
tomorrow_count+=1
continue
result.append({
"communtiy_time_period_id" :ctp.CommunityTimePeriodDB.id,
"time_period_id": ctp.CommunityTimePeriodDB.time_period_id,
"time_period_name": ctp.time_period_name,
"time_period_name": f"今日 {ctp.time_period_name}",
"time_period_date": today_date,
"capacity": ctp.CommunityTimePeriodDB.capacity,
"from_time": ctp.time_period_from_time,
"to_time": ctp.time_period_to_time,
"order_full": today_orders_count >= ctp.CommunityTimePeriodDB.capacity,
"expired": datetime.now().time() > ctp.time_period_from_time
"is_default": False
})
# 构建明日配送时段
for i in range(tomorrow_count):
ctp = community_time_periods[i]
result.append({
"communtiy_time_period_id" :ctp.CommunityTimePeriodDB.id,
"time_period_id": ctp.CommunityTimePeriodDB.time_period_id,
"time_period_name": f"明日 {ctp.time_period_name}",
"time_period_date": tomorrow_date,
"capacity": ctp.CommunityTimePeriodDB.capacity,
"from_time": ctp.time_period_from_time,
"to_time": ctp.time_period_to_time,
"order_full": False,
"is_default": False
})
for ctp in result:
if not ctp['order_full']:
ctp['is_default'] = True
break
return success_response(data=result)
except Exception as e:

View File

@ -240,6 +240,7 @@ async def create_order(
final_amount=price_info.final_amount,
status=OrderStatus.CREATED,
delivery_method=order.delivery_method,
delivery_date=order.delivery_date,
is_first_order=is_first_order
)
@ -444,7 +445,14 @@ async def get_order_detail(
# 如果配送时段不为空,则使用配送时段的时间
if order.time_period_id:
delivery_time = f"预计 {order.time_period_name} 送达"
if order.delivery_date == datetime.now().date():
delivery_time = f"今日 {order.time_period_name}"
elif order.delivery_date == datetime.now().date() + timedelta(days=1):
delivery_time = f"明日 {order.time_period_name}"
else:
delivery_time = f"{order.delivery_date} {order.time_period_name}"
else:
delivery_time = f"今日"
# 构建响应数据
order_data = {
@ -471,6 +479,7 @@ async def get_order_detail(
"pickup_time": order.pickup_time,
"received_time": order.received_time,
"delivery_date": order.delivery_date,
"delivery_method": order.delivery_method,
"deliveryman_user_id": order.deliveryman_user_id,
"deliveryman_nickname": deliveryman_user_name,

View File

@ -103,7 +103,7 @@ async def login(
# 创建访问令牌
access_token = create_access_token(
data={"phone": user.phone,"userid":user.userid}
data={"sub": user.userid, "phone": user.phone}
)
# 设置JWT cookie
@ -203,7 +203,7 @@ async def phone_login(
# 创建访问令牌
access_token = create_access_token(
data={"phone": user.phone,"userid":user.userid}
data={"phone": user.phone,"sub":user.userid}
)
# 设置JWT cookie
@ -343,7 +343,7 @@ async def password_login(
return error_response(code=401, message="配送员账户,请先设置归属小区")
# 生成访问令牌
access_token = create_access_token(data={"phone": user.phone,"userid":user.userid})
access_token = create_access_token(data={"phone": user.phone,"sub":user.userid})
# 设置JWT cookie
if response:

View File

@ -111,7 +111,7 @@ async def wechat_phone_login(
# 创建访问令牌
access_token = create_access_token(
data={"phone": user.phone, "userid": user.userid}
data={"phone": user.phone, "sub": user.userid}
)
# 设置JWT cookie

View File

@ -7,6 +7,7 @@ from sqlalchemy.orm import Session
from app.models.user import UserDB
from datetime import datetime
from app.models.user import UserRole
from datetime import date
class RedisClient:
"""Redis 客户端"""
@ -37,12 +38,12 @@ class RedisClient:
return self.client
def push_order_to_community_period_today_queue(self, community_time_period_id: int, order_id: str) -> bool:
def push_order_to_community_period_queue(self, delivery_date: date,community_time_period_id: int, order_id: str) -> bool:
"""
添加新订单到今日队列
"""
try:
today_date_str = datetime.now().strftime("%Y-%m-%d")
today_date_str = delivery_date.strftime("%Y-%m-%d")
key = f"community_period:{community_time_period_id}:today_orders:{today_date_str}"
self.client.lpush(key, order_id)
@ -54,12 +55,12 @@ class RedisClient:
logging.error(f"添加新订单到今日队列失败: {str(e)}")
return False
def get_community_period_today_orders_count(self, community_time_period_id: int) -> int:
def get_community_period_orders_count(self, delivery_date: date, community_time_period_id: int) -> int:
"""
获取今日队列中的订单数量
"""
try:
today_date_str = datetime.now().strftime("%Y-%m-%d")
today_date_str = delivery_date.strftime("%Y-%m-%d")
key = f"community_period:{community_time_period_id}:today_orders:{today_date_str}"
return self.client.llen(key)
except Exception as e:

View File

@ -11,11 +11,10 @@ pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
def create_access_token(data: dict, expires_delta: Optional[timedelta] = None) -> str:
to_encode = data.copy()
# 更新 token 数据,不设置过期时间
to_encode.update({
"userid": data.get("userid"),
"phone": data.get("phone")
})
if expires_delta:
to_encode.update({"exp": datetime.now(timezone.utc) + expires_delta})
else:
to_encode.update({"exp": datetime.now(timezone.utc) + timedelta(days=180)})
encoded_jwt = jwt.encode(to_encode, settings.SECRET_KEY, algorithm="HS256")
return encoded_jwt
@ -44,12 +43,11 @@ def clear_jwt_cookie(response: Response):
def verify_token(token: str) -> Optional[str]:
try:
payload = jwt.decode(token, settings.SECRET_KEY, algorithms=["HS256"])
sub: str = payload.get("sub")
phone: str = payload.get("phone")
if phone is None:
return None
return phone
return sub, phone
except JWTError:
return None
return None, None
def get_password_hash(password: str) -> str:
"""获取密码哈希值"""
@ -64,7 +62,7 @@ def decode_jwt(token: str) -> dict:
try:
payload = jwt.decode(token, settings.SECRET_KEY, algorithms=["HS256"])
return {
"userid": payload.get("userid"),
"userid": payload.get("sub"),
"phone": payload.get("phone")
}
except:

View File

@ -1,6 +1,6 @@
from datetime import datetime
from typing import Optional, List
from sqlalchemy import Column, String, Integer, Float, DateTime, ForeignKey, Enum, Boolean, Time
from sqlalchemy import Column, String, Integer, Float, DateTime, ForeignKey, Enum, Boolean, Time, Date
from sqlalchemy.sql import func
from pydantic import BaseModel, Field
from .database import Base
@ -8,6 +8,9 @@ import enum
from app.models.user import Gender
from app.core.imageprocessor import process_image, ImageFormat
from datetime import time
from datetime import date
class OrderStatus(str, enum.Enum):
CREATED = "CREATED" # 已创建
CANCELLED = "CANCELLED" # 已取消
@ -63,6 +66,7 @@ class ShippingOrderDB(Base):
pickup_code_count = Column(Integer, nullable=False, default=0) # 取件码数量
delivery_method = Column(Enum(DeliveryMethod), nullable=False)
delivery_date = Column(Date, nullable=False, default=datetime.now().date())
package_count = Column(Integer, nullable=False)
original_amount = Column(Float, nullable=False)
coupon_discount_amount = Column(Float, default=0)
@ -126,6 +130,10 @@ class OrderCreate(BaseModel):
addressid: int
price_request: OrderPriceCalculateRequest
community_time_period_id: int = 0
delivery_date: date = Field(
default=datetime.now().date(),
description="配送日期"
)
delivery_method: DeliveryMethod = Field(
default=DeliveryMethod.DELIVERY_AT_DOORSTEP,
description="配送方式:放在门口或投递到家"
@ -163,6 +171,7 @@ class OrderInfo(BaseModel):
optimized_complete_images: Optional[List[str]] = None
create_time: datetime
delivery_method: DeliveryMethod
delivery_date: date
deliveryman_user_id: Optional[int] = None