126 lines
4.6 KiB
Markdown
126 lines
4.6 KiB
Markdown
# 大纲管理功能实现计划
|
||
|
||
## 概述
|
||
为小说添加大纲管理功能,大纲属于小说的子资源,支持增删改查。前端采用**卷轴时间线**可视化展示,契合"墨韵书斋"设计风格。
|
||
|
||
## 视觉设计方向
|
||
不做传统列表,而是做一条**竖向卷轴时间线**:
|
||
- 中央一条细线作为"墨线",串联所有大纲节点
|
||
- 每个节点是一张展开的"纸笺"卡片,左右交替排列
|
||
- 卡片显示序号、一句话描述;hover展开详情
|
||
- 点击卡片可编辑、删除
|
||
- 底部有"添加新节点"按钮,点击弹出模态框
|
||
- 空状态:一卷未展开的空白卷轴动画
|
||
- 节点间可拖拽排序(用sort_order字段)
|
||
|
||
---
|
||
|
||
## 一、后端
|
||
|
||
### 1. 数据模型 (`backend/app/models.py`)
|
||
在现有Novel模型同文件新增Outline模型:
|
||
```python
|
||
class Outline(SQLModel, table=True):
|
||
id: Optional[int] = Field(default=None, primary_key=True)
|
||
novel_id: int = Field(foreign_key="novel.id", index=True)
|
||
sort_order: int = Field(default=0) # 排序序号
|
||
summary: str = Field(max_length=200) # 一句话描述
|
||
detail: str = Field(default="", max_length=1000) # 详情(100-300字)
|
||
created_at: datetime = Field(default_factory=_now_utc)
|
||
updated_at: datetime = Field(default_factory=_now_utc)
|
||
```
|
||
|
||
### 2. 请求/响应模式 (`backend/app/schemas.py`)
|
||
新增:
|
||
- `OutlineCreate` — summary(必填), detail(可选)
|
||
- `OutlineUpdate` — summary, detail, sort_order 均可选
|
||
- `OutlineRead` — 全字段
|
||
- `OutlineList` — items + total
|
||
- `OutlineReorder` — 接收排序后的id列表
|
||
|
||
### 3. API路由 (`backend/app/routers/outlines.py`)
|
||
新建路由文件,前缀 `/api/novels/{novel_id}/outlines`:
|
||
- `GET /` — 列出该小说所有大纲(按sort_order排序)
|
||
- `POST /` — 创建大纲(自动设置sort_order为最大值+1)
|
||
- `GET /{outline_id}` — 获取单个大纲
|
||
- `PATCH /{outline_id}` — 更新大纲
|
||
- `DELETE /{outline_id}` — 删除大纲
|
||
- `PUT /reorder` — 批量更新排序
|
||
|
||
### 4. 注册路由 (`backend/app/main.py`)
|
||
引入并挂载outlines_router。
|
||
|
||
---
|
||
|
||
## 二、前端
|
||
|
||
### 5. TypeScript类型 (`frontend/src/types/outline.ts`)
|
||
```typescript
|
||
export interface Outline {
|
||
id: number
|
||
novel_id: number
|
||
sort_order: number
|
||
summary: string
|
||
detail: string
|
||
created_at: string
|
||
updated_at: string
|
||
}
|
||
export interface OutlineCreate { summary: string; detail?: string }
|
||
export interface OutlineUpdate { summary?: string; detail?: string; sort_order?: number }
|
||
export interface OutlineList { items: Outline[]; total: number }
|
||
```
|
||
|
||
### 6. API调用 (`frontend/src/api/outlines.ts`)
|
||
跟随novels.ts的模式,所有请求挂在 `/novels/{novelId}/outlines` 下。
|
||
|
||
### 7. 路由 (`frontend/src/router/index.ts`)
|
||
新增路由:
|
||
- `/novels/:id/outlines` → OutlineView(大纲页面,从小说详情页进入)
|
||
|
||
### 8. 小说详情页更新 (`NovelDetailView.vue`)
|
||
添加"查看大纲"按钮/入口,链接到大纲页面。
|
||
|
||
### 9. 大纲视图页面 (`frontend/src/views/OutlineView.vue`)
|
||
主页面,包含:
|
||
- 返回小说详情的导航
|
||
- 小说标题显示
|
||
- 卷轴时间线组件
|
||
- 添加大纲的按钮
|
||
|
||
### 10. 卷轴时间线组件 (`frontend/src/components/outline/OutlineTimeline.vue`)
|
||
**核心可视化组件**,设计要点:
|
||
- 中央竖向墨线(2px,渐变从墨色到透明)
|
||
- 大纲节点左右交替排列(odd左even右)
|
||
- 每个节点通过横向短线连接到中央墨线
|
||
- 节点连接点有一个圆形墨点装饰
|
||
- 入场动画:依次从上到下淡入,配合墨线延伸
|
||
|
||
### 11. 大纲节点卡片 (`frontend/src/components/outline/OutlineNode.vue`)
|
||
单个大纲节点:
|
||
- 纸笺风格卡片(paper-50背景,细边框,微阴影)
|
||
- 顶部显示序号标记(朱砂红圆圈内数字)
|
||
- 一句话summary作为标题
|
||
- 默认折叠状态,hover或点击展开detail
|
||
- 展开状态下显示编辑/删除按钮
|
||
- hover微抬效果(与NovelCard一致的动效)
|
||
|
||
### 12. 大纲表单弹窗 (`frontend/src/components/outline/OutlineFormModal.vue`)
|
||
复用BaseModal + BaseInput + BaseTextarea:
|
||
- 新建/编辑共用一个组件
|
||
- summary输入框(单行,必填,max 200字)
|
||
- detail文本域(多行,100-300字建议)
|
||
- 字数统计提示
|
||
|
||
### 13. 大纲空状态 (`frontend/src/components/outline/OutlineEmptyState.vue`)
|
||
空白卷轴SVG动画 + "展开你的故事脉络"文案 + 创建按钮。
|
||
|
||
---
|
||
|
||
## 实施顺序
|
||
1. 后端模型 + schemas + API路由(步骤1-4)
|
||
2. 前端类型 + API层(步骤5-6)
|
||
3. 路由 + 详情页入口(步骤7-8)
|
||
4. 大纲视图页面 + 时间线组件 + 节点卡片(步骤9-11)
|
||
5. 表单弹窗 + 空状态(步骤12-13)
|
||
6. 启动后端+前端验证全流程
|