Files
smart-project-pricing/后端服务/app/schemas/competitor.py
2026-01-31 21:33:06 +08:00

115 lines
4.1 KiB
Python

"""竞品机构 Schema"""
from typing import Optional
from datetime import datetime, date
from enum import Enum
from pydantic import BaseModel, Field
class Positioning(str, Enum):
"""机构定位枚举"""
HIGH = "high" # 高端
MEDIUM = "medium" # 中端
BUDGET = "budget" # 大众
class PriceSource(str, Enum):
"""价格来源枚举"""
OFFICIAL = "official" # 官网
MEITUAN = "meituan" # 美团
DIANPING = "dianping" # 大众点评
SURVEY = "survey" # 实地调研
# ============ 竞品机构 Schema ============
class CompetitorBase(BaseModel):
"""竞品机构基础字段"""
competitor_name: str = Field(..., min_length=1, max_length=100, description="机构名称")
address: Optional[str] = Field(None, max_length=200, description="地址")
distance_km: Optional[float] = Field(None, ge=0, description="距离(公里)")
positioning: Positioning = Field(Positioning.MEDIUM, description="定位")
contact: Optional[str] = Field(None, max_length=50, description="联系方式")
is_key_competitor: bool = Field(False, description="是否重点关注")
is_active: bool = Field(True, description="是否启用")
class CompetitorCreate(CompetitorBase):
"""创建竞品机构请求"""
pass
class CompetitorUpdate(BaseModel):
"""更新竞品机构请求"""
competitor_name: Optional[str] = Field(None, min_length=1, max_length=100, description="机构名称")
address: Optional[str] = Field(None, max_length=200, description="地址")
distance_km: Optional[float] = Field(None, ge=0, description="距离(公里)")
positioning: Optional[Positioning] = Field(None, description="定位")
contact: Optional[str] = Field(None, max_length=50, description="联系方式")
is_key_competitor: Optional[bool] = Field(None, description="是否重点关注")
is_active: Optional[bool] = Field(None, description="是否启用")
class CompetitorResponse(CompetitorBase):
"""竞品机构响应"""
id: int
price_count: int = Field(0, description="价格记录数")
last_price_update: Optional[date] = Field(None, description="最后价格更新日期")
created_at: datetime
updated_at: datetime
class Config:
from_attributes = True
# ============ 竞品价格 Schema ============
class CompetitorPriceBase(BaseModel):
"""竞品价格基础字段"""
project_id: Optional[int] = Field(None, description="关联本店项目ID")
project_name: str = Field(..., min_length=1, max_length=100, description="竞品项目名称")
original_price: float = Field(..., gt=0, description="原价")
promo_price: Optional[float] = Field(None, gt=0, description="促销价")
member_price: Optional[float] = Field(None, gt=0, description="会员价")
price_source: PriceSource = Field(..., description="价格来源")
collected_at: date = Field(..., description="采集日期")
remark: Optional[str] = Field(None, max_length=200, description="备注")
class CompetitorPriceCreate(CompetitorPriceBase):
"""创建竞品价格请求"""
pass
class CompetitorPriceUpdate(BaseModel):
"""更新竞品价格请求"""
project_id: Optional[int] = Field(None, description="关联本店项目ID")
project_name: Optional[str] = Field(None, min_length=1, max_length=100, description="竞品项目名称")
original_price: Optional[float] = Field(None, gt=0, description="原价")
promo_price: Optional[float] = Field(None, gt=0, description="促销价")
member_price: Optional[float] = Field(None, gt=0, description="会员价")
price_source: Optional[PriceSource] = Field(None, description="价格来源")
collected_at: Optional[date] = Field(None, description="采集日期")
remark: Optional[str] = Field(None, max_length=200, description="备注")
class CompetitorPriceResponse(CompetitorPriceBase):
"""竞品价格响应"""
id: int
competitor_id: int
competitor_name: Optional[str] = Field(None, description="竞品机构名称")
created_at: datetime
updated_at: datetime
class Config:
from_attributes = True