提交
This commit is contained in:
1 parent
6d9354a194
commit
aff71d296b
2759 files changed
+860425
-13211
No files matched your search
@@ -0,0 +1,39 @@
|
||||
# PL 入库单 / 出库单 Implementation Plan
|
||||
|
||||
> **For agentic workers:** Execute task-by-task. Spec: `docs/superpowers/specs/2026-07-19-pl-inbound-outbound-order-design.md`
|
||||
|
||||
**Goal:** 安排运输后落 PL 入库/出库主从表;一单一链免登录填实际数量;管理端库存管理菜单列表编辑;作废计划作废单据;已安排计划冻结(无调整运输)。
|
||||
|
||||
**Architecture:** `pl_inbound_order`/`pl_outbound_order` + item;安排运输时创建(替代新 `pl_transport_site_link`);地磅数量仅预填;公共页 `/public/pl/inbound|outbound/{token}`。
|
||||
|
||||
**Tech Stack:** FastAPI + SQLAlchemy + Vue3/Element Plus;菜单 `sys_menu`;Fresh Mint UI。
|
||||
|
||||
---
|
||||
|
||||
## File map
|
||||
|
||||
| 职责 | 路径 |
|
||||
|------|------|
|
||||
| DDL 迁移 | `backend/scripts/migration_20260719_pl_inbound_outbound_order.sql` |
|
||||
| 模型 | `backend/app/models/pl_models.py` |
|
||||
| 服务 | `backend/app/services/pl_io_order_service.py` |
|
||||
| Schema | `backend/app/schemas/pl/io_order.py` |
|
||||
| 管理 API | `backend/app/api/pl/io_order.py` |
|
||||
| 公共 API | `backend/app/api/pl/public_io_order.py` |
|
||||
| 安排/作废接入 | `backend/app/api/pl/transport.py`, `plan.py` |
|
||||
| 路由注册 | `backend/app/api/pl/__init__.py`, `main.py` |
|
||||
| 菜单 | 同上 migration SQL;`web-admin/src/router/modules/pl.ts` |
|
||||
| 前端 API | `web-admin/src/api/pl/index.ts` |
|
||||
| 列表/弹窗 | `web-admin/src/views/pl/inbound/index.vue`, `outbound/index.vue` |
|
||||
| 公共页 | `web-admin/src/views/public/pl/inbound/index.vue`, `outbound/...` |
|
||||
| 计划冻结 UX | `web-admin/src/views/pl/plan/index.vue`, arrange dialog |
|
||||
|
||||
### Task 1: DDL + Models + Menu SQL
|
||||
### Task 2: pl_io_order_service + arrange/cancel wire + block rearrange
|
||||
### Task 3: Admin + Public APIs
|
||||
### Task 4: Frontend lists/dialogs/public/freeze/archive
|
||||
### Task 5: graphify update + smoke check
|
||||
|
||||
---
|
||||
|
||||
**执行方式:** 本会话 Inline 连续实现(用户已确认「继续」)。
|
||||
@@ -0,0 +1,360 @@
|
||||
# 运输计划 · 保存并安排运输 Implementation Plan
|
||||
|
||||
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
|
||||
|
||||
**Goal:** 在运输计划新增/编辑弹窗增加「创建/保存并安排运输」主按钮(前端串联打开安排弹窗),并在运输计划归档页隐藏编辑入口。
|
||||
|
||||
**Architecture:** 仅前端改动。`PlPlanFormDialog` 保存成功后通过 `success({ planId, openArrange })` 通知列表页;列表页刷新后按需打开现有 `PlPlanArrangeDialog`。危化品门禁复用 `buildMissingHazardCertReadyMessage`(保存后 `GET` 计划详情再判断)。无新后端 API。
|
||||
|
||||
**Tech Stack:** Vue 3 + Element Plus + TypeScript;`@/api/pl`、`@/utils/http/bx`(`pickBxData`)、`usePlToxicProductCertCheck`。
|
||||
|
||||
**Spec:** `docs/superpowers/specs/2026-07-19-pl-plan-save-and-arrange-design.md`
|
||||
|
||||
---
|
||||
|
||||
## File map
|
||||
|
||||
| 职责 | 路径 |
|
||||
|------|------|
|
||||
| 表单底栏 + 保存/保存并安排 | `web-admin/src/components/business/pl-plan-form-dialog/index.vue` |
|
||||
| 列表接事件并打开安排弹窗 | `web-admin/src/views/pl/plan/index.vue` |
|
||||
| 归档页隐藏编辑 | `web-admin/src/views/pl/plan-archive/index.vue` |
|
||||
| 设计文档(已完成) | `docs/superpowers/specs/2026-07-19-pl-plan-save-and-arrange-design.md` |
|
||||
|
||||
---
|
||||
|
||||
### Task 1: PlPlanFormDialog — 底栏显隐与双提交
|
||||
|
||||
**Files:**
|
||||
- Modify: `web-admin/src/components/business/pl-plan-form-dialog/index.vue`
|
||||
|
||||
- [ ] **Step 1: 扩展 emit 与编辑态运输状态**
|
||||
|
||||
在 `<script setup>` 中:
|
||||
|
||||
1. 将 `Van` 加入 `@element-plus/icons-vue` 的 import。
|
||||
2. 增加 import:
|
||||
|
||||
```ts
|
||||
import {
|
||||
enrichPlanProductsHazardFromCrm,
|
||||
buildMissingHazardCertReadyMessage
|
||||
} from '@/composables/usePlToxicProductCertCheck'
|
||||
import { pickBxData } from '@/utils/http/bx'
|
||||
```
|
||||
|
||||
(注意:文件已 import `enrichPlanProductsHazardFromCrm`,合并进同一条 import,勿重复。)
|
||||
|
||||
3. 将 emit 改为:
|
||||
|
||||
```ts
|
||||
const emit = defineEmits<{
|
||||
'update:visible': [value: boolean]
|
||||
success: [payload?: { planId: string; openArrange: boolean }]
|
||||
}>()
|
||||
```
|
||||
|
||||
4. 增加 ref,并在 `resetForm` 中清零;在 `loadPlanForEdit` 赋值:
|
||||
|
||||
```ts
|
||||
const loadedTransportStatus = ref('pending')
|
||||
const loadedHazardCertReady = ref(0)
|
||||
|
||||
// resetForm 内:
|
||||
loadedTransportStatus.value = 'pending'
|
||||
loadedHazardCertReady.value = 0
|
||||
|
||||
// loadPlanForEdit 在 Object.assign 之后:
|
||||
loadedTransportStatus.value = data.transportStatus || 'pending'
|
||||
loadedHazardCertReady.value = Number(data.hazardCertReady ?? 0)
|
||||
```
|
||||
|
||||
5. 增加计算属性:
|
||||
|
||||
```ts
|
||||
const showSaveAndArrange = computed(
|
||||
() => !isEdit.value || loadedTransportStatus.value === 'pending'
|
||||
)
|
||||
|
||||
const saveButtonLabel = computed(() => (isEdit.value ? '保存' : '创建'))
|
||||
|
||||
const saveAndArrangeLabel = computed(() =>
|
||||
isEdit.value ? '保存并安排运输' : '创建并安排运输'
|
||||
)
|
||||
```
|
||||
|
||||
- [ ] **Step 2: 改 template footer**
|
||||
|
||||
将现有 `#footer` 替换为:
|
||||
|
||||
```vue
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="innerVisible = false">
|
||||
<el-icon><Close /></el-icon>取消
|
||||
</el-button>
|
||||
<el-button
|
||||
:type="showSaveAndArrange ? 'default' : 'primary'"
|
||||
:class="showSaveAndArrange ? 'btn-ghost' : undefined"
|
||||
:loading="submitLoading"
|
||||
@click="handleSubmit('save')"
|
||||
>
|
||||
<el-icon><Check /></el-icon>{{ saveButtonLabel }}
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="showSaveAndArrange"
|
||||
type="primary"
|
||||
:loading="submitLoading"
|
||||
@click="handleSubmit('saveAndArrange')"
|
||||
>
|
||||
<el-icon><Van /></el-icon>{{ saveAndArrangeLabel }}
|
||||
</el-button>
|
||||
</div>
|
||||
</template>
|
||||
```
|
||||
|
||||
- [ ] **Step 3: 重写 `handleSubmit`**
|
||||
|
||||
用下列实现替换现有 `handleSubmit`(保留 `validateBusinessRules` 不变):
|
||||
|
||||
```ts
|
||||
async function handleSubmit(mode: 'save' | 'saveAndArrange' = 'save') {
|
||||
const valid = await basicFormRef.value?.validate().catch(() => false)
|
||||
if (!valid || !validateBusinessRules()) return
|
||||
|
||||
submitLoading.value = true
|
||||
try {
|
||||
const commonPayload = buildPlanCommonPayload({ allowClearTransport: isEdit.value })
|
||||
let planId = props.planId || ''
|
||||
|
||||
if (isEdit.value) {
|
||||
if (!props.planId) return
|
||||
await planApi.update(props.planId, commonPayload)
|
||||
planId = props.planId
|
||||
ElMessage.success('保存成功')
|
||||
} else {
|
||||
const res = await planApi.createFull({
|
||||
...commonPayload,
|
||||
contractId: formData.contractId
|
||||
} as Parameters<typeof planApi.createFull>[0])
|
||||
const created = pickBxData<Plan>(res)
|
||||
planId = String(created?.id || '')
|
||||
if (!planId) {
|
||||
ElMessage.error('创建成功但未返回计划 ID')
|
||||
return
|
||||
}
|
||||
ElMessage.success('创建成功')
|
||||
}
|
||||
|
||||
let openArrange = false
|
||||
if (mode === 'saveAndArrange' && planId) {
|
||||
const detailRes = await planApi.get(planId)
|
||||
const plan = pickBxData<Plan>(detailRes)
|
||||
const rawProducts = Array.isArray(plan?.products) ? plan.products : []
|
||||
const enrichedProducts = await enrichPlanProductsHazardFromCrm(rawProducts)
|
||||
const certMessage = buildMissingHazardCertReadyMessage(plan, enrichedProducts)
|
||||
if (certMessage) {
|
||||
await ElMessageBox.alert(
|
||||
`${certMessage},请至【危化品证上传】页面操作。`,
|
||||
'无法安排运输',
|
||||
{ type: 'warning' }
|
||||
)
|
||||
openArrange = false
|
||||
} else {
|
||||
openArrange = true
|
||||
}
|
||||
}
|
||||
|
||||
innerVisible.value = false
|
||||
emit('success', { planId, openArrange })
|
||||
} finally {
|
||||
submitLoading.value = false
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
说明:拦截文案与 `pl-plan-arrange-dialog` 保持一致;`loadedHazardCertReady` 供后续扩展,门禁以 `GET` 详情为准。
|
||||
|
||||
- [ ] **Step 4: 本地目视确认**
|
||||
|
||||
Run: 打开 `http://localhost:3006/#/pl/plan-module/plan`,点「新增计划」,确认底栏为「取消 · 创建 · 创建并安排运输」(后者主色)。
|
||||
|
||||
Expected: 双按钮布局正确;未点提交即可。
|
||||
|
||||
- [ ] **Step 5: Commit(若用户要求提交时再执行)**
|
||||
|
||||
```bash
|
||||
git add web-admin/src/components/business/pl-plan-form-dialog/index.vue
|
||||
git commit -m "$(cat <<'EOF'
|
||||
feat(pl): add save-and-arrange action on transport plan form dialog
|
||||
|
||||
EOF
|
||||
)"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 2: 运输计划列表 — 串联安排弹窗
|
||||
|
||||
**Files:**
|
||||
- Modify: `web-admin/src/views/pl/plan/index.vue`
|
||||
|
||||
- [ ] **Step 1: 扩展 `handlePlanMutationSuccess`**
|
||||
|
||||
将:
|
||||
|
||||
```ts
|
||||
async function handlePlanMutationSuccess() {
|
||||
await fetchData()
|
||||
await refreshViewIfOpen()
|
||||
}
|
||||
```
|
||||
|
||||
替换为:
|
||||
|
||||
```ts
|
||||
async function handlePlanMutationSuccess(payload?: { planId?: string; openArrange?: boolean }) {
|
||||
await fetchData()
|
||||
await refreshViewIfOpen()
|
||||
if (payload?.openArrange && payload.planId) {
|
||||
arrangePlanId.value = payload.planId
|
||||
arrangeDialogVisible.value = true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
说明:`PlPlanArrangeDialog` 的 `@success="handlePlanMutationSuccess"` 无 payload,行为仍为仅刷新,兼容不变。
|
||||
|
||||
- [ ] **Step 2: 手动验收(对照 spec V1–V5)**
|
||||
|
||||
| 用例 | 操作 | Expected |
|
||||
|------|------|----------|
|
||||
| V1 | 新增弹窗底栏 | 创建(描边)+ 创建并安排运输(主色) |
|
||||
| V3 | 普通品「创建并安排运输」 | 保存后自动打开安排运输弹窗 |
|
||||
| V5 | 安排弹窗点取消 | 列表有该计划,运输状态待安排 |
|
||||
| V4 | 含危化品且证书未齐 | 计划已保存;Alert 说明原因;不打开安排 |
|
||||
| V2 | 编辑已安排(直销若仍可编辑) | 无「保存并安排运输」,仅「保存」主色 |
|
||||
|
||||
- [ ] **Step 3: Commit(若用户要求提交时再执行)**
|
||||
|
||||
```bash
|
||||
git add web-admin/src/views/pl/plan/index.vue
|
||||
git commit -m "$(cat <<'EOF'
|
||||
feat(pl): open arrange dialog after plan save-and-arrange
|
||||
|
||||
EOF
|
||||
)"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 3: 运输计划归档 — 隐藏编辑
|
||||
|
||||
**Files:**
|
||||
- Modify: `web-admin/src/views/pl/plan-archive/index.vue`
|
||||
|
||||
- [ ] **Step 1: 去掉工具栏编辑按钮**
|
||||
|
||||
删除模板中约 99–106 行的编辑按钮块:
|
||||
|
||||
```vue
|
||||
<el-button
|
||||
v-if="selectedPlan && selectedPlan.followStatus !== 'cancelled'"
|
||||
class="btn-ghost"
|
||||
:disabled="selectedRows.length !== 1"
|
||||
@click="handleToolbarEdit"
|
||||
>
|
||||
<el-icon><Edit /></el-icon>编辑
|
||||
</el-button>
|
||||
```
|
||||
|
||||
- [ ] **Step 2: 去掉查看弹窗 hero「编辑」**
|
||||
|
||||
在 `PlPlanViewDialog` 的 `#hero-actions` 中删除编辑按钮(保留归档按钮),即删除:
|
||||
|
||||
```vue
|
||||
<el-button
|
||||
v-if="viewingPlan.followStatus !== 'cancelled'"
|
||||
class="btn-main"
|
||||
type="primary"
|
||||
@click="handleEdit(viewingPlan)"
|
||||
>
|
||||
<el-icon><Edit /></el-icon>编辑
|
||||
</el-button>
|
||||
```
|
||||
|
||||
若删除后 hero 仅剩归档按钮,将归档按钮改为 `type="primary"` / `class="btn-main"`(保持一行一个主色)。
|
||||
|
||||
- [ ] **Step 3: 移除闲置表单弹窗与相关代码**
|
||||
|
||||
删除:
|
||||
|
||||
1. 模板中的 `<PlPlanFormDialog ... />`
|
||||
2. `import PlPlanFormDialog ...`
|
||||
3. `import { Edit } from ...`(若已无其它引用)
|
||||
4. `formDialogVisible`、`editingPlanId`
|
||||
5. `handleEdit`、`handleToolbarEdit`
|
||||
6. `handlePlanMutationSuccess` 中若仅服务于表单,可改为只服务归档弹窗的 refresh(保留对 archive dialog `@success` 的刷新逻辑)
|
||||
|
||||
核对:归档弹窗、查看弹窗仍正常工作。
|
||||
|
||||
- [ ] **Step 4: 手动验收 V6**
|
||||
|
||||
Run: 打开 `http://localhost:3006/#/pl/plan-module/plan-archive`
|
||||
|
||||
Expected: 工具栏与查看弹窗均无「编辑」;归档/调整归档仍可用。
|
||||
|
||||
- [ ] **Step 5: Commit(若用户要求提交时再执行)**
|
||||
|
||||
```bash
|
||||
git add web-admin/src/views/pl/plan-archive/index.vue
|
||||
git commit -m "$(cat <<'EOF'
|
||||
fix(pl): hide edit transport plan on archive list page
|
||||
|
||||
EOF
|
||||
)"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 4: 收尾
|
||||
|
||||
**Files:**
|
||||
- 无新文件;按需更新知识图谱
|
||||
|
||||
- [ ] **Step 1: 对照 spec 勾选覆盖**
|
||||
|
||||
| Spec | Task |
|
||||
|------|------|
|
||||
| D1 底栏方案 A | Task 1 |
|
||||
| D2 前端串联 | Task 1–2 |
|
||||
| D3 证书未齐备仍保存 | Task 1 Step 3 |
|
||||
| D4 显隐 pending | Task 1 Step 1 |
|
||||
| D5 取消安排保留待安排 | Task 2(行为天然满足) |
|
||||
| D6 归档隐藏编辑 | Task 3 |
|
||||
| V1–V6 | Task 2 Step 2 + Task 3 Step 4 |
|
||||
|
||||
- [ ] **Step 2: 更新 graphify(仅改了 web-admin)**
|
||||
|
||||
```bash
|
||||
./scripts/update-graph.sh frontend
|
||||
```
|
||||
|
||||
Expected: 脚本成功结束,无报错。
|
||||
|
||||
- [ ] **Step 3: 将 design 状态改为已实现(实现完成后)**
|
||||
|
||||
在 `docs/superpowers/specs/2026-07-19-pl-plan-save-and-arrange-design.md` 将 `**状态:** 待实现` 改为 `**状态:** 已实现`。
|
||||
|
||||
---
|
||||
|
||||
## Spec coverage self-check
|
||||
|
||||
- D1–D6、V1–V6 均有对应 Task/步骤。
|
||||
- 无 TBD /「类似 Task N」占位。
|
||||
- `success` payload 形状在 Task 1 与 Task 2 一致:`{ planId, openArrange }`。
|
||||
- 归档页不再挂载表单,故无需处理归档页 `openArrange`。
|
||||
|
||||
## Out of scope(勿做)
|
||||
|
||||
- 后端合并接口、表单内嵌安排区、「保存并调整运输」、修改安排弹窗内部逻辑。
|
||||
@@ -0,0 +1,121 @@
|
||||
# 运输计划 · 保存并安排运输(设计)
|
||||
|
||||
**日期:** 2026-07-19
|
||||
**状态:** 已实现
|
||||
**范围:** `web-admin` 运输计划新增/编辑弹窗快捷入口;运输计划归档页隐藏编辑
|
||||
|
||||
## 背景
|
||||
|
||||
运输计划新增/编辑弹窗(`PlPlanFormDialog`)当前底栏仅有「取消」与「创建/保存」。创建计划与安排运输是两步:保存后需回列表再点「安排运输」。
|
||||
|
||||
当计划产品不含易制毒/易制爆(或证书已齐备)时,用户希望保存后立刻进入安排运输,减少往返。
|
||||
|
||||
后端 `create-full` 明确「不自动安排运输」;安排运输仍由独立弹窗与 API 完成。本需求不改变该边界,仅做前端串联。
|
||||
|
||||
## 目标
|
||||
|
||||
1. 在新增/编辑弹窗增加「创建/保存并安排运输」主按钮,保存成功后自动打开现有「安排运输」弹窗。
|
||||
2. 保留原「创建/保存」,供需补证书或稍后安排的场景。
|
||||
3. 运输计划归档页不再提供编辑运输计划入口。
|
||||
|
||||
## 非目标
|
||||
|
||||
- 不新增后端「创建并安排」合并接口
|
||||
- 不把安排运输表单内嵌进计划表单
|
||||
- 不提供「保存并调整运输」入口(已安排后不显示该快捷按钮)
|
||||
- 不修改安排运输弹窗内部逻辑、危化品证上传页逻辑
|
||||
|
||||
## 决策摘要
|
||||
|
||||
| 编号 | 决策 | 说明 |
|
||||
|------|------|------|
|
||||
| D1 | 底栏方案 A | 取消 · 创建/保存(描边)· 创建/保存并安排运输(主色) |
|
||||
| D2 | 实现路径 1 | 前端串联:保存 → 可选打开现有安排弹窗;无新 API |
|
||||
| D3 | 证书未齐备 | 仍保存计划,提示无法安排的原因,不打开安排弹窗 |
|
||||
| D4 | 显隐 | 新增始终显示「并安排」;编辑仅 `transportStatus === 'pending'` 时显示 |
|
||||
| D5 | 取消安排 | 计划已保存,状态仍为「待安排」,可稍后在列表再安排 |
|
||||
| D6 | 归档页 | 隐藏所有「编辑」入口,不打开计划表单弹窗 |
|
||||
|
||||
## 交互设计
|
||||
|
||||
### 底栏
|
||||
|
||||
| 场景 | 底栏按钮 |
|
||||
|------|----------|
|
||||
| 新增 | 取消 · 创建(描边)· **创建并安排运输**(主色) |
|
||||
| 编辑且未安排 | 取消 · 保存(描边)· **保存并安排运输**(主色) |
|
||||
| 编辑且已安排 | 取消 · **保存**(主色);不显示「并安排」 |
|
||||
|
||||
规则:
|
||||
|
||||
- 有「并安排」按钮时,它是唯一 `type="primary"`;「创建/保存」为中性描边。
|
||||
- 无「并安排」时,「保存」恢复为主色(与现网一致)。
|
||||
- 按钮须带 Element Plus 图标(与 OpenSpec UI 约定一致)。
|
||||
|
||||
### 「创建/保存并安排运输」流程
|
||||
|
||||
1. **校验**:与现有创建/保存相同(基础表单校验、已选合同、至少一条产品)。
|
||||
2. **保存**:调用现有 `POST /transport/plan/create-full` 或 `PUT /transport/plan/{id}`,取得 `planId`。
|
||||
3. **危化品门禁(前端)**:复用 `shouldBlockTransportForHazardCert` / `buildMissingHazardCertReadyMessage`(与安排弹窗一致)。
|
||||
- 需拦截:成功提示保存完成 + 说明无法安排的原因 → 关闭表单 → **不**打开安排弹窗。
|
||||
- 可通过:关闭表单 → 打开现有「安排运输」弹窗(`planId`)。
|
||||
4. **安排弹窗**:用户照常填写并提交;若取消,计划保留为「待安排」(D5)。
|
||||
|
||||
### 「创建/保存」
|
||||
|
||||
行为与现网一致:仅保存,关闭弹窗,不打开安排运输。
|
||||
|
||||
### 运输计划归档页
|
||||
|
||||
- 隐藏工具栏「编辑」与查看弹窗 hero「编辑」。
|
||||
- 可移除或闲置 `PlPlanFormDialog` 挂载(以实现时最小改动为准;至少保证无 UI 入口)。
|
||||
- 归档/查看流程不变。
|
||||
|
||||
## 组件与数据流
|
||||
|
||||
```
|
||||
PlPlanFormDialog
|
||||
handleSubmit(mode: 'save' | 'saveAndArrange')
|
||||
→ createFull / update
|
||||
→ emit('success', { planId, openArrange: boolean })
|
||||
|
||||
plan/index.vue
|
||||
handlePlanMutationSuccess(payload)
|
||||
→ 刷新列表
|
||||
→ if openArrange: 打开 PlPlanArrangeDialog(planId)
|
||||
```
|
||||
|
||||
事件约定:
|
||||
|
||||
- 仅保存:`{ planId, openArrange: false }`(或等价兼容:无 payload 时视为仅刷新)。
|
||||
- 保存并安排且通过门禁:`{ planId, openArrange: true }`。
|
||||
- 保存并安排但被门禁拦截:`{ planId, openArrange: false }`(计划已保存)。
|
||||
|
||||
`planId` 来源:新建取接口返回的 `id`;编辑用当前 `planId`。
|
||||
|
||||
## 错误处理
|
||||
|
||||
| 情况 | 行为 |
|
||||
|------|------|
|
||||
| 表单校验失败 | 不提交,与现网一致 |
|
||||
| 保存 API 失败 | 不关闭弹窗、不打开安排,展示错误 |
|
||||
| 证书未齐备 | 保存成功后提示原因,不打开安排 |
|
||||
| 安排弹窗内提交失败 | 由安排弹窗自行处理;计划仍为待安排或按安排 API 结果更新 |
|
||||
|
||||
## 验收要点
|
||||
|
||||
- V1:新增弹窗可见「创建」+「创建并安排运输」,主色在后者。
|
||||
- V2:编辑未安排计划可见「保存并安排运输」;已安排则不可见。
|
||||
- V3:普通品点「并安排」→ 保存成功 → 自动打开安排运输弹窗。
|
||||
- V4:含危化品且证书未齐备 → 计划已保存 → 提示原因 → 不打开安排。
|
||||
- V5:安排弹窗取消 → 列表中计划存在且为待安排。
|
||||
- V6:运输计划归档页无编辑入口。
|
||||
|
||||
## 参考代码
|
||||
|
||||
- 表单:`web-admin/src/components/business/pl-plan-form-dialog/index.vue`
|
||||
- 列表:`web-admin/src/views/pl/plan/index.vue`
|
||||
- 安排弹窗:`web-admin/src/components/business/pl-plan-arrange-dialog/index.vue`
|
||||
- 证书门禁:`web-admin/src/composables/usePlToxicProductCertCheck.ts`
|
||||
- 归档页:`web-admin/src/views/pl/plan-archive/index.vue`
|
||||
- 计划冻结(入库/出库已安排不可编辑):`isIoPlanFrozen`(列表既有逻辑,本需求不扩展调整运输)
|
||||
Reference in new issue
Block a user