feat(business): 业务管理接口(编号生成/明细/状态机/归属留痕/毛利润视图)
- 编号 YW{日期}-{序号}:MAX+FOR UPDATE 并发安全 + 1062 兜底重试(no_generator 三单据共用)
- 明细全量替换重算五项汇总冗余;销售额服务层按数量×单价固化不信任前端
- 状态机终态拦截、终止必填原因、创建写首条留痕;归属变更同事务留痕防旁路
- 毛利润视图按行实时计算(不含运费 #2),阈值按 asOf 取 M1 快照,率输出
Fraction 分数字符串同 M1 预览口径;成本缺失行标注无法计算
- 入参契约统一为蛇形直出(撤回 customer/business 的驼峰 alias,与前端
businessRoles.ts 模式对齐)
Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
1 parent
1625907380
commit
0cdc6246c4
7 files changed
+1565
-18
No files matched your search
@@ -35,11 +35,11 @@ class CustomerCreateIn(BaseModel):
|
||||
|
||||
owner_personnel_id 为**初始归属**,可空(客户先建档、后派归属也合法);
|
||||
归属的后续调整不走本模型,统一走 ``PUT /{id}/ownership``(见
|
||||
``CustomerUpdateIn`` 的说明)。camelCase 别名与蛇形字段名均可绑定,
|
||||
兼容前端两种拼写。
|
||||
``CustomerUpdateIn`` 的说明)。字段名蛇形直出(M1 契约:前端 api 封装
|
||||
与 schema 同名对应,仅分页信封 list/pageNum 驼峰)。
|
||||
"""
|
||||
|
||||
model_config = ConfigDict(str_strip_whitespace=True, populate_by_name=True)
|
||||
model_config = ConfigDict(str_strip_whitespace=True)
|
||||
|
||||
company_name: str = Field(min_length=1, max_length=128, description="公司名称")
|
||||
owner_name: str = Field(
|
||||
@@ -59,7 +59,6 @@ class CustomerCreateIn(BaseModel):
|
||||
owner_personnel_id: int | None = Field(
|
||||
default=None,
|
||||
ge=1,
|
||||
alias="ownerPersonnelId",
|
||||
description="归属负责营销人员ID(初始归属,可空)",
|
||||
)
|
||||
remark: str | None = Field(default=None, max_length=255, description="备注")
|
||||
@@ -91,21 +90,13 @@ class CustomerUpdateIn(BaseModel):
|
||||
|
||||
|
||||
class CustomerQuery(PageQuery):
|
||||
"""客户列表查询条件。
|
||||
|
||||
customer_type / owner_personnel_id 同时接受蛇形(项目既有契约,见前端
|
||||
`types.ts` 的说明)与驼峰别名,两种拼写不并存即可。
|
||||
"""
|
||||
"""客户列表查询条件(字段名蛇形直出,与前端 api 封装同名对应)。"""
|
||||
|
||||
keyword: str | None = Field(
|
||||
default=None, max_length=64, description="公司名称或客户负责人,模糊匹配"
|
||||
)
|
||||
customer_type: str | None = Field(
|
||||
default=None, max_length=32, alias="customerType", description="客户分类筛选"
|
||||
)
|
||||
owner_personnel_id: int | None = Field(
|
||||
default=None, ge=1, alias="ownerPersonnelId", description="归属人员ID筛选"
|
||||
)
|
||||
customer_type: str | None = Field(default=None, max_length=32, description="客户分类筛选")
|
||||
owner_personnel_id: int | None = Field(default=None, ge=1, description="归属人员ID筛选")
|
||||
|
||||
|
||||
class CustomerOwnershipIn(BaseModel):
|
||||
@@ -114,12 +105,9 @@ class CustomerOwnershipIn(BaseModel):
|
||||
new_owner_personnel_id 可空:null 表示清空归属(客户暂无负责人也合法)。
|
||||
"""
|
||||
|
||||
model_config = ConfigDict(populate_by_name=True)
|
||||
|
||||
new_owner_personnel_id: int | None = Field(
|
||||
default=None,
|
||||
ge=1,
|
||||
alias="newOwnerPersonnelId",
|
||||
description="变更后归属人员ID,null=清空归属",
|
||||
)
|
||||
reason: str | None = Field(default=None, max_length=255, description="变更原因")
|
||||
|
||||
Reference in new issue
Block a user