162 lines
4.3 KiB
Python
162 lines
4.3 KiB
Python
from datetime import date, datetime
|
||
from typing import Any, Dict, List, Optional
|
||
|
||
from pydantic import BaseModel, Field
|
||
|
||
|
||
class CustomerBase(BaseModel):
|
||
name: str = Field(..., description="Customer name")
|
||
contact_info: Optional[str] = Field(None, description="Contact information")
|
||
tags: Optional[str] = Field(None, description="Comma-separated tags, e.g. 重点客户,已签约")
|
||
|
||
|
||
class CustomerCreate(CustomerBase):
|
||
pass
|
||
|
||
|
||
class CustomerUpdate(BaseModel):
|
||
name: Optional[str] = None
|
||
contact_info: Optional[str] = None
|
||
tags: Optional[str] = None
|
||
|
||
|
||
class CustomerRead(CustomerBase):
|
||
id: int
|
||
created_at: datetime
|
||
|
||
class Config:
|
||
from_attributes = True
|
||
|
||
|
||
class ProjectRead(BaseModel):
|
||
id: int
|
||
customer_id: int
|
||
raw_requirement: str
|
||
ai_solution_md: Optional[str] = None
|
||
status: str
|
||
created_at: datetime
|
||
customer: Optional[CustomerRead] = None
|
||
|
||
class Config:
|
||
from_attributes = True
|
||
|
||
|
||
class ProjectUpdate(BaseModel):
|
||
raw_requirement: Optional[str] = None
|
||
ai_solution_md: Optional[str] = None
|
||
status: Optional[str] = None
|
||
|
||
|
||
class RequirementAnalyzeRequest(BaseModel):
|
||
customer_id: int = Field(..., description="Related customer id")
|
||
raw_text: str = Field(..., description="Raw requirement text from chat or WeChat")
|
||
|
||
|
||
class RequirementAnalyzeResponse(BaseModel):
|
||
project_id: int
|
||
ai_solution_md: str
|
||
ai_solution_json: Dict[str, Any]
|
||
|
||
|
||
class QuoteGenerateResponse(BaseModel):
|
||
quote_id: int
|
||
project_id: int
|
||
total_amount: float
|
||
excel_path: str
|
||
pdf_path: str
|
||
|
||
|
||
class ContractGenerateRequest(BaseModel):
|
||
delivery_date: str = Field(..., description="Delivery date, e.g. 2026-03-31")
|
||
extra_placeholders: Dict[str, str] = Field(
|
||
default_factory=dict,
|
||
description="Additional placeholder mappings for the contract template",
|
||
)
|
||
|
||
|
||
class ContractGenerateResponse(BaseModel):
|
||
project_id: int
|
||
contract_path: str
|
||
|
||
|
||
class PushToCloudRequest(BaseModel):
|
||
platform: str = Field(..., description="feishu | yuque | tencent")
|
||
title: Optional[str] = Field(None, description="文档标题,默认使用「项目方案 - 项目#id」")
|
||
body_md: Optional[str] = Field(None, description="要推送的 Markdown 内容,不传则使用项目已保存的方案")
|
||
|
||
|
||
class PushToCloudResponse(BaseModel):
|
||
url: str
|
||
cloud_doc_id: str
|
||
|
||
|
||
class FinanceSyncResult(BaseModel):
|
||
id: int
|
||
month: str
|
||
type: str
|
||
file_name: str
|
||
file_path: str
|
||
|
||
|
||
class FinanceSyncResponse(BaseModel):
|
||
status: str = "success"
|
||
new_files: int = 0
|
||
details: List[FinanceSyncResult] = Field(default_factory=list)
|
||
|
||
|
||
class FinanceSyncRequest(BaseModel):
|
||
"""
|
||
邮箱附件同步策略:
|
||
- mode=incremental:默认策略。首次(无历史)全量,否则仅同步 UNSEEN。
|
||
- mode=all:同步全部附件(可配合时间范围)。
|
||
- mode=latest:只同步「最新一封」邮件中的附件(可配合时间范围)。
|
||
时间范围为任意起止日期(含起止日),内部会转为 IMAP 的 SINCE/BEFORE。
|
||
"""
|
||
mode: str = Field("incremental", description="incremental | all | latest")
|
||
start_date: Optional[date] = Field(None, description="YYYY-MM-DD")
|
||
end_date: Optional[date] = Field(None, description="YYYY-MM-DD")
|
||
doc_types: Optional[List[str]] = Field(
|
||
None,
|
||
description="要同步的附件类型:invoices/receipts/statements。为空表示默认全部类型。",
|
||
)
|
||
|
||
|
||
class FinanceRecordRead(BaseModel):
|
||
id: int
|
||
month: str
|
||
type: str
|
||
file_name: str
|
||
file_path: str
|
||
tags: Optional[str] = None
|
||
meta_json: Optional[str] = None
|
||
amount: Optional[float] = None
|
||
billing_date: Optional[date] = None
|
||
created_at: datetime
|
||
|
||
class Config:
|
||
from_attributes = True
|
||
|
||
|
||
class FinanceRecordUpdate(BaseModel):
|
||
amount: Optional[float] = None
|
||
billing_date: Optional[date] = None
|
||
|
||
|
||
class FinanceBatchDeleteRequest(BaseModel):
|
||
ids: List[int] = Field(..., description="要删除的财务记录 ID 列表")
|
||
|
||
|
||
class FinanceUploadResponse(BaseModel):
|
||
id: int
|
||
month: str
|
||
type: str
|
||
file_name: str
|
||
file_path: str
|
||
amount: Optional[float] = None
|
||
billing_date: Optional[date] = None
|
||
created_at: datetime
|
||
|
||
class Config:
|
||
from_attributes = True
|
||
|