115 lines
4.1 KiB
Python
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
|