a1886074dd
后端: FastAPI + SQLAlchemy 2.0 (async) + Alembic + MinIO + Casdoor + 企微 前端: Vue 3 + Vite + TypeScript + Element Plus + Pinia 功能清单: - 8 张数据表自动建表 / Casdoor OIDC 登录 / 企微静默登录 - 双布局: 移动端(填报) + PC端(汇总管理) - 拜访记录 CRUD + MinIO 照片直传 + 缩略图预览 + 同访人草稿 - 今日纪要 (6 分类) / 工作计划 / 小微商机 / 要客拜访 CRUD - 客户档案: 备注/收支费用/联系人/归属分配/批量转移 - 客户导入导出 + 模板下载 + 搜索/分页/筛选 - 仪表盘: 四卡统计 + 填报进度 (拜访+纪要双维度) - 周报详情: 五 Tab + 按人/客户筛选 + 时间轴 - 用户管理 / 客户经理 PC 端工作台 - 企微: 催办/公告/定时提醒 / 时区修正 - Docker 部署配置 Co-Authored-By: Claude <noreply@anthropic.com>
119 lines
2.4 KiB
Python
119 lines
2.4 KiB
Python
from pydantic import BaseModel, Field
|
|
from typing import Optional
|
|
import uuid
|
|
from datetime import date, datetime
|
|
|
|
|
|
# ── User ──
|
|
class UserCreate(BaseModel):
|
|
name: str
|
|
role: str = "manager"
|
|
department: str = ""
|
|
wecom_userid: Optional[str] = None
|
|
|
|
|
|
class UserOut(BaseModel):
|
|
id: uuid.UUID
|
|
casdoor_id: str
|
|
name: str
|
|
role: str
|
|
department: str
|
|
wecom_userid: Optional[str] = None
|
|
|
|
model_config = {"from_attributes": True}
|
|
|
|
|
|
# ── CustomerContact ──
|
|
class ContactCreate(BaseModel):
|
|
name: str
|
|
phone: str = ""
|
|
role_desc: str = ""
|
|
|
|
|
|
class ContactOut(BaseModel):
|
|
id: uuid.UUID
|
|
customer_id: uuid.UUID
|
|
name: str
|
|
phone: str
|
|
role_desc: str
|
|
|
|
model_config = {"from_attributes": True}
|
|
|
|
|
|
# ── Customer ──
|
|
class CustomerCreate(BaseModel):
|
|
name: str
|
|
industry: str = ""
|
|
address: str = ""
|
|
in_use_services: str = ""
|
|
monthly_fee: str = ""
|
|
remarks: str = ""
|
|
contacts: list[ContactCreate] = []
|
|
assignee_id: Optional[uuid.UUID] = None
|
|
|
|
|
|
class CustomerUpdate(BaseModel):
|
|
name: Optional[str] = None
|
|
industry: Optional[str] = None
|
|
address: Optional[str] = None
|
|
in_use_services: Optional[str] = None
|
|
monthly_fee: Optional[str] = None
|
|
remarks: Optional[str] = None
|
|
assignee_id: Optional[uuid.UUID] = None
|
|
|
|
|
|
class CustomerOut(BaseModel):
|
|
id: uuid.UUID
|
|
name: str
|
|
industry: str
|
|
address: str
|
|
in_use_services: str
|
|
monthly_fee: str
|
|
remarks: str = ""
|
|
created_by: uuid.UUID
|
|
created_at: datetime
|
|
updated_at: datetime
|
|
contacts: list[ContactOut] = []
|
|
primary_manager_name: Optional[str] = None
|
|
|
|
model_config = {"from_attributes": True}
|
|
|
|
|
|
class CustomerListOut(BaseModel):
|
|
id: uuid.UUID
|
|
name: str
|
|
industry: str
|
|
in_use_services: str
|
|
|
|
model_config = {"from_attributes": True}
|
|
|
|
|
|
class CustomerListResponse(BaseModel):
|
|
items: list[CustomerListOut]
|
|
total: int
|
|
page: int
|
|
page_size: int
|
|
|
|
|
|
# ── CustomerAssignment ──
|
|
class AssignmentCreate(BaseModel):
|
|
customer_id: uuid.UUID
|
|
manager_id: uuid.UUID
|
|
role: str = "primary"
|
|
|
|
|
|
class AssignmentOut(BaseModel):
|
|
id: uuid.UUID
|
|
customer_id: uuid.UUID
|
|
manager_id: uuid.UUID
|
|
role: str
|
|
assigned_at: datetime
|
|
assigned_by: uuid.UUID
|
|
|
|
model_config = {"from_attributes": True}
|
|
|
|
|
|
class BatchAssignRequest(BaseModel):
|
|
customer_ids: list[uuid.UUID]
|
|
manager_id: uuid.UUID
|