From 6d3bd3b5c733ea2a170b46bf09c744a6ee76471c Mon Sep 17 00:00:00 2001 From: xiaosi <2652281683@qq.com> Date: Tue, 1 Sep 2026 14:29:15 +0800 Subject: [PATCH] =?UTF-8?q?docs:=20=E8=88=AA=E7=BA=BF=E5=BA=93=E7=BC=96?= =?UTF-8?q?=E8=BE=91=E5=88=A0=E9=99=A4=E8=AE=BE=E8=AE=A1=E8=A7=84=E6=A0=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 补齐 RouteCard 编辑/删除与复用现有编辑器的前端设计,后端 CRUD 已具备仅接线。 --- ...-09-01-route-library-edit-delete-design.md | 201 ++++++++++++++++++ 1 file changed, 201 insertions(+) create mode 100644 docs/superpowers/specs/2026-09-01-route-library-edit-delete-design.md diff --git a/docs/superpowers/specs/2026-09-01-route-library-edit-delete-design.md b/docs/superpowers/specs/2026-09-01-route-library-edit-delete-design.md new file mode 100644 index 0000000..7131bf9 --- /dev/null +++ b/docs/superpowers/specs/2026-09-01-route-library-edit-delete-design.md @@ -0,0 +1,201 @@ +# 航线库编辑 / 删除设计 + +日期:2026-09-01 +状态:已批准(对话确认) +范围:`laic-frontend` 航线库前端能力补齐 + +## 背景 + +任务管理 → 航线库当前仅支持: + +- 列表展示与搜索 +- 新建航线(地图点选航点 → `POST /v1/routes`) + +卡片 `RouteCard` 为纯展示,无编辑 / 删除入口。 +后端已具备完整 CRUD: + +| 能力 | 接口 | +|------|------| +| 列表 | `GET /v1/routes` | +| 详情 | `GET /v1/routes/:id` | +| 新建 | `POST /v1/routes` | +| 更新 | `PUT /v1/routes/:id`(`waypoints` 有值则整体替换) | +| 删除 | `DELETE /v1/routes/:id` | + +缺口仅在前端接线。 + +## 目标 + +1. 航线卡片提供 **编辑**、**删除** 操作。 +2. 编辑复用现有航线编辑器(地图 + 航点侧栏),不新建第二套 UI。 +3. 删除需二次确认。 +4. 新建路径行为保持不变。 + +## 非目标 + +- 航线复制、导入 / 导出、只读详情页 +- 任务占用拦截(后端未暴露占用校验时前端不做) +- 管理端特殊权限 UI(沿用接口 401/403) +- 后端改动 +- `description` 字段(当前新建流程也未采集) + +## 交互 + +### 列表卡片 + +- 每张 `RouteCard` 增加操作区:**编辑**、**删除** +- 布局:卡片内容下方操作条(对齐设备 / 任务 `.row-actions` 文字按钮风格) +- 删除使用危险色(`theme="danger"`) +- 不采用「整卡点击进编辑」;操作显式按钮,避免误触 + +### 编辑 + +1. 点击「编辑」 +2. 请求 `GET /v1/routes/:id` +3. 成功后打开现有 `route-editor`: + - 标题:`编辑航线` + - 主按钮:`保存修改`(保存中:`保存中…`) +4. 回填: + - 航线名称 + - 航点列表与地图轨迹 + - 默认高度 / 速度:取首航点;无航点时回退 `50` / `10` + - `turnMode`:`holdSec > 0` → `stop`,否则 `auto` +5. 编辑器内仍可增删改航点、撤销、清空、应用到全部航点(与新建相同) +6. 保存校验与新建一致: + - 名称必填 + - 至少 2 个航点 +7. 提交 `PUT /v1/routes/:id`,body: + ```json + { + "name": "...", + "waypoints": [ + { "longitude": 0, "latitude": 0, "altitude": 0, "speed": 0, "yaw": 0, "holdSec": 0 } + ] + } + ``` +8. 成功:toast「航线已更新」→ 关闭编辑器 → 刷新列表 +9. 失败:编辑器内 `routeFormError` 展示错误,不关闭 + +### 删除 + +1. 点击「删除」 +2. `ui.confirm`: + - 标题:`确认删除航线「{name}」?` + - 说明:删除后不可恢复;已绑定该航线的任务需自行处理(简短文案即可) +3. 确认后 `DELETE /v1/routes/:id` +4. 成功:toast「航线已删除」→ 刷新列表 +5. 失败:toast 错误信息 +6. 删除入口仅在卡片;编辑器内不放删除(按已选交互) + +### 新建(不变) + +- `editingRouteId = null` +- 标题仍为「新建航线」 +- 主按钮仍为「保存航线」 +- 仍 `POST /v1/routes` + +## 数据流与状态 + +### URL + +`src/config/urls.js` 增补: + +```js +export const ROUTES = '/v1/routes' +export const ROUTE = (id) => `/v1/routes/${id}` +``` + +### 视图状态(TasksView) + +| 状态 | 含义 | +|------|------| +| `editingRouteId` | `null` = 新建;非空 = 正在编辑的航线 id | +| `routeEditorOpen` | 编辑器显隐(已有) | +| `routeForm` / `routePoints` | 已有表单与航点 | +| `routeSaving` | 保存中禁用(已有) | + +生命周期: + +- `openRouteEditor()`:reset → `editingRouteId=null` → open(新建) +- `openRouteEditorForEdit(route)`:reset → GET 详情 → 填表 → `editingRouteId=id` → open +- `closeRouteEditor()`:teardown map → close → `editingRouteId=null` + reset +- `submitRoute()`:按 `editingRouteId` 分支 POST / PUT +- `deleteRoute(route)`:confirm → DELETE → reload + +### 航点映射 + +``` +API → UI: + longitude/latitude/altitude/speed 原样 Number + turnMode = holdSec > 0 ? 'stop' : 'auto' + +UI → API: + yaw = 0 + holdSec = turnMode === 'stop' ? 1 : 0 +``` + +与现有 `submitRoute` 映射保持一致。 +`PUT` **始终**携带全量 `waypoints`,触发后端整体替换。 + +### 列表映射注意 + +当前列表用分页 records 映射卡片;列表项可能不含完整 waypoints(取决于后端 page 是否 embed)。 + +- 列表展示:继续用现有 fields(name、waypoints 计数、distance、collectedAt) +- 编辑回填:**必须以详情接口为准**,不信任列表里的精简数据 +- 若列表无 waypoints 导致 distance/`waypoints` 计数为 0,属既有问题,本需求不强制修 page API;编辑保存后 `load()` 刷新 + +## 组件改动 + +### `RouteCard.vue` + +Props 保持展示字段;新增: + +- emit:`edit`、`delete` +- 模板底部操作条:编辑(primary text)、删除(danger text) +- 点击操作 `@click.stop`,避免未来卡片可点时冒泡 + +### `TasksView.vue` + +- 绑定 `@edit` / `@delete` +- 实现上述 open/submit/delete 逻辑 +- 编辑器 header 文案随 `editingRouteId` 切换 + +### `prototype.css`(或 RouteCard 局部样式) + +- `.route-card-actions`:flex、间距、与卡片底部分隔 +- 对齐现有 `.row-actions` 观感,不引入新视觉体系 + +## 错误处理 + +| 场景 | 行为 | +|------|------| +| 详情加载失败 | toast,不打开编辑器 | +| 保存校验失败 | editor 内错误文案 | +| 保存接口失败 | editor 内错误文案,保持编辑态 | +| 删除取消 | 无副作用 | +| 删除接口失败 | toast | +| 401/403 | 走现有 axios 拦截器 | + +## 验收标准 + +1. 航线库卡片可见「编辑」「删除」。 +2. 编辑:名称与航点回填正确,地图显示轨迹。 +3. 修改后保存:列表名称 / 航点数更新。 +4. 删除确认后卡片从列表消失。 +5. 新建航线流程与文案不受影响。 +6. 保存中按钮禁用,防止重复提交。 + +## 测试建议 + +- 手工:本地 / 远端各走一遍新建、编辑、删除。 +- 无需新增自动化测试套件(项目现无前端单测约定);若后续有 component test 基建再补。 + +## 实现顺序建议 + +1. `urls.ROUTE` +2. `RouteCard` 操作 UI + emit +3. TasksView:delete +4. TasksView:edit open + submit 分支 +5. 样式微调 +6. 手工验收