Files
qiji/docs/superpowers/specs/2026-07-12-mini-business-logs-design.md
T

131 lines
4.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 商机跟单优化 — 跟进记录子表 — 设计文档
> 日期:2026-07-12 | 状态:已确认
## 一、需求概述
当前商机跟单只有一条静态记录(产品+金额+跟进内容文本+状态),缺少"持续跟进"的时间线感。新增跟进记录子表,将每个商机从"快照"变为"持续跟单"。
## 二、核心决策
| 决策项 | 结论 |
|--------|------|
| 方案 | 新增 `mini_business_logs` 子表 |
| 跟进方式 | 电话/微信/上门/邮件/其他(chip 按钮选择) |
| 原 follow_up_detail | 保留,含义改为"商机概述/背景" |
| 状态 | 不变(跟进中/已签约/已流失) |
## 三、新增表 `mini_business_logs`
```sql
CREATE TABLE mini_business_logs (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
business_id UUID NOT NULL REFERENCES mini_business(id) ON DELETE CASCADE,
log_date DATE NOT NULL,
method VARCHAR(20) NOT NULL DEFAULT '电话',
content TEXT NOT NULL DEFAULT '',
created_by UUID NOT NULL REFERENCES users(id),
created_at TIMESTAMPTZ DEFAULT now()
);
CREATE INDEX idx_mbl_business_id ON mini_business_logs(business_id);
CREATE INDEX idx_mbl_log_date ON mini_business_logs(log_date);
```
### SQLAlchemy 模型
```python
class MiniBusinessLog(Base):
__tablename__ = "mini_business_logs"
id: Mapped[uuid.UUID] = mapped_column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
business_id: Mapped[uuid.UUID] = mapped_column(UUID(as_uuid=True), ForeignKey("mini_business.id", ondelete="CASCADE"), index=True)
log_date: Mapped[date] = mapped_column(Date)
method: Mapped[str] = mapped_column(String(20), default="电话")
content: Mapped[str] = mapped_column(Text, default="")
created_by: Mapped[uuid.UUID] = mapped_column(UUID(as_uuid=True), ForeignKey("users.id"))
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now())
```
### MiniBusiness 模型添加 relationship
```python
logs: Mapped[list["MiniBusinessLog"]] = relationship(back_populates="business", cascade="all, delete-orphan")
```
## 四、商机主体字段调整
| 字段 | 变更 | 前端 label |
|------|------|-----------|
| `follow_up_detail` | 保留,含义改为商机概述 | "商机概述" |
| 其他字段 | 不变 | |
## 五、API
### 子路由
| 方法 | 路径 | 说明 | 权限 |
|------|------|------|------|
| `GET` | `/mini-business/{id}/logs` | 获取跟进记录列表(date DESC) | 经理仅看自己 |
| `POST` | `/mini-business/{id}/logs` | 新增跟进记录 | 经理本人或支局长/领导 |
| `PUT` | `/mini-business/logs/{log_id}` | 编辑跟进记录 | 创建人或支局长/领导 |
| `DELETE` | `/mini-business/logs/{log_id}` | 删除跟进记录 | 创建人或支局长/领导 |
### 请求体 (POST/PUT)
```json
{
"log_date": "2026-07-12",
"method": "电话",
"content": "客户反馈价格偏高,需进一步沟通方案"
}
```
### 跟进方式枚举
`["电话", "微信", "上门", "邮件", "其他"]`
## 六、前端
### PC 端 — 商机列表页增强
- 表格新增「最近跟进」列(最近一次跟进日期 + 跟进次数 badge)
- 点击客户名打开详情弹窗(替代直接编辑)
- 详情弹窗:上部=商机基本信息(客户/产品/金额/状态/概述)+ 编辑按钮,下部=跟进时间线 + 新增跟进入口
### PC 端 — 跟进时间线组件
```
📞 07-10 电话 — 客户反馈价格偏高,需进一步沟通 [编辑] [删除]
🏢 07-05 上门 — 现场演示产品功能,客户初步认可 [编辑] [删除]
📧 07-01 邮件 — 发送报价方案 [编辑] [删除]
```
- 按日期倒序,最新在上
- 每条显示:方式图标 + 日期 + 内容 + 操作按钮
- 底部「新增跟进」按钮展开内联表单(日期+方式 chip+内容 textarea
### 移动端 — 商机表单页改为详情页
- 现有新建表单保留
- 新增商机详情页(路由 `/m/mini-biz/:id`
- 上部:商机信息卡片(可点击编辑)
- 下部:跟进时间线 + 底部固定「新增跟进」按钮
### 移动端 — 首页入口
- Home.vue 的「商机跟单」chip 改为跳转商机列表(需新增 `/m/mini-biz` 路由)
## 七、文件变更
| 类型 | 文件 | 说明 |
|------|------|------|
| 新增 | `models/mini_business_log.py` | Log 模型 |
| 新增 | `schemas/mini_business_log.py` | Log Schema |
| 新增 | `api/mini_business_logs.py` | Log CRUD API |
| 修改 | `models/mini_business.py` | 添加 logs relationship |
| 修改 | `models/__init__.py` | 注册新模型 |
| 修改 | `main.py` | lifespan 自动建表 |
| 修改 | `MiniBusiness.vue` (PC) | 详情弹窗 + 时间线 |
| 修改 | `MiniBusinessForm.vue` (mobile) | 改为详情页模式 |
| 新增 | `frontend/src/api/miniBusiness.ts` | 追加 logs API |
| 新增 | 移动端商机列表页 | `/m/mini-biz` |