Files
shanxia2.0/docs/superpowers/plans/2026-09-04-pl-plan-arranged-tab.md
T
2026-09-06 20:44:56 +08:00

8.3 KiB
Raw Blame History

运输计划列表「已安排」Tab 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 (- [x]) syntax for tracking.

Goal: 在运输计划列表「待安排」之后增加「已安排」Tab,筛选跟进状态为 arranged 的计划。

Architecture: 沿用「待安排 / 草稿中」跟进状态 Tab 模式:扩展 PL_PLAN_LIST_TABS 与 plPlanListTabToFilters,列表页切换 Tab 时同步 searchForm.followStatus。后端已支持 followStatus=arranged,无需改接口。

Tech Stack: Vue 3 + TypeScript;node:test + pnpm exec tsx --test

Spec: docs/superpowers/specs/2026-09-04-pl-plan-arranged-tab-design.md

注意: 工作区可能有无关未提交改动。只改本计划列出的文件,提交时勿夹带无关 diff。


文件结构

操作 文件 职责
Create web-admin/src/utils/pl-plan-list-tabs.test.ts Tab 顺序 / filter / 跟进状态 Tab 判定单测
Modify web-admin/src/utils/pl-display.ts PlPlanListTab、PL_PLAN_LIST_TABS、isPlPlanFollowStatusListTab、plPlanListTabToFilters
Modify web-admin/src/views/pl/plan/index.vue handlePlanTypeTabChange 切到 arranged 时同步筛选

Task 1: Tab 工具函数单测 + 实现

Files:

  • Create: web-admin/src/utils/pl-plan-list-tabs.test.ts

  • Modify: web-admin/src/utils/pl-display.ts

  • Step 1: 写失败单测

创建 web-admin/src/utils/pl-plan-list-tabs.test.ts:

import assert from 'node:assert/strict'
import { describe, it } from 'node:test'
import {
  PL_PLAN_LIST_TABS,
  isPlPlanFollowStatusListTab,
  plPlanListTabToFilters
} from './pl-display'

describe('PL_PLAN_LIST_TABS', () => {
  it('places arranged immediately after pending_arrange', () => {
    const names = PL_PLAN_LIST_TABS.map((t) => t.name)
    assert.deepEqual(names.slice(0, 3), ['pending_arrange', 'arranged', 'drafting'])
    assert.equal(
      PL_PLAN_LIST_TABS.find((t) => t.name === 'arranged')?.label,
      '已安排'
    )
  })
})

describe('isPlPlanFollowStatusListTab', () => {
  it('recognizes pending_arrange, arranged, drafting', () => {
    assert.equal(isPlPlanFollowStatusListTab('pending_arrange'), true)
    assert.equal(isPlPlanFollowStatusListTab('arranged'), true)
    assert.equal(isPlPlanFollowStatusListTab('drafting'), true)
    assert.equal(isPlPlanFollowStatusListTab('all'), false)
    assert.equal(isPlPlanFollowStatusListTab('inbound'), false)
  })
})

describe('plPlanListTabToFilters', () => {
  it('maps arranged to followStatus arranged with empty planType', () => {
    assert.deepEqual(plPlanListTabToFilters('arranged'), {
      planType: '',
      followStatus: 'arranged'
    })
  })

  it('keeps pending_arrange and drafting behavior', () => {
    assert.deepEqual(plPlanListTabToFilters('pending_arrange'), {
      planType: '',
      followStatus: 'pending_arrange'
    })
    assert.deepEqual(plPlanListTabToFilters('drafting'), {
      planType: '',
      followStatus: 'drafting'
    })
  })

  it('maps type tabs without followStatus', () => {
    assert.deepEqual(plPlanListTabToFilters('all'), { planType: '' })
    assert.deepEqual(plPlanListTabToFilters('inbound'), { planType: 'inbound' })
  })
})
  • Step 2: 跑测确认失败
cd web-admin && pnpm exec tsx --test src/utils/pl-plan-list-tabs.test.ts

Expected: FAIL(arranged 尚未进入 PL_PLAN_LIST_TABS / filter)

  • Step 3: 最小实现

在 web-admin/src/utils/pl-display.ts 中:

  1. 更新类型与注释:
/** 运输计划列表 Tab(单据类型前增加「待安排」「已安排」「草稿中」) */
export type PlPlanListTab = PlPlanTypeTab | 'pending_arrange' | 'arranged' | 'drafting'
  1. 更新 Tab 列表(「待安排」后插入「已安排」):
export const PL_PLAN_LIST_TABS: { label: string; name: PlPlanListTab }[] = [
  { label: '待安排', name: 'pending_arrange' },
  { label: '已安排', name: 'arranged' },
  { label: '草稿中', name: 'drafting' },
  ...PL_PLAN_TYPE_TABS
]
  1. 更新跟进状态 Tab 判定:
export function isPlPlanFollowStatusListTab(
  tab: PlPlanListTab | string
): tab is 'pending_arrange' | 'arranged' | 'drafting' {
  return tab === 'pending_arrange' || tab === 'arranged' || tab === 'drafting'
}
  1. 在 plPlanListTabToFilters 中增加 arranged 分支(放在 pending_arrange 之后、drafting 之前):
export function plPlanListTabToFilters(tab: PlPlanListTab): {
  planType: string
  followStatus?: string
} {
  if (tab === 'pending_arrange') {
    return { planType: '', followStatus: 'pending_arrange' }
  }
  if (tab === 'arranged') {
    return { planType: '', followStatus: 'arranged' }
  }
  if (tab === 'drafting') {
    return { planType: '', followStatus: 'drafting' }
  }
  return { planType: plPlanTypeTabToFilter(tab) }
}
  • Step 4: 跑测确认通过
cd web-admin && pnpm exec tsx --test src/utils/pl-plan-list-tabs.test.ts

Expected: PASS(全部用例通过)

  • Step 5: Commit
git add web-admin/src/utils/pl-display.ts web-admin/src/utils/pl-plan-list-tabs.test.ts
git commit -m "$(cat <<'EOF'
feat(web-admin): add arranged tab to transport plan list filters

Insert「已安排」after「待安排」in PL_PLAN_LIST_TABS and map it to followStatus=arranged.
EOF
)"

Task 2: 列表页 Tab 切换同步筛选

Files:

  • Modify: web-admin/src/views/pl/plan/index.vue

  • Step 1: 更新 handlePlanTypeTabChange

在 handlePlanTypeTabChange 中,于 pending_arrange 分支后增加 arranged 分支(isPlPlanFollowStatusListTab 已含 arranged,从跟进状态 Tab 切回类型 Tab 时会自动恢复默认筛选,无需额外改动):

function handlePlanTypeTabChange(tab: PlPlanListTab | string) {
  const nextTab = tab as PlPlanListTab
  const prevTab = activePlanTypeTab.value
  activePlanTypeTab.value = nextTab
  const filters = plPlanListTabToFilters(nextTab)
  searchForm.planType = filters.planType
  if (nextTab === 'pending_arrange') {
    searchForm.followStatus = ['pending_arrange']
  } else if (nextTab === 'arranged') {
    searchForm.followStatus = ['arranged']
  } else if (nextTab === 'drafting') {
    searchForm.followStatus = ['drafting']
  } else if (isPlPlanFollowStatusListTab(prevTab) && !isPlPlanFollowStatusListTab(nextTab)) {
    searchForm.followStatus = [...PL_PLAN_DEFAULT_FOLLOW_STATUSES]
  }
  pagination.page = 1
  fetchData()
}

说明:

  • fetchData / 导出已通过 plPlanListTabToFilters(activePlanTypeTab.value) 取 followStatus,无需再改

  • handleReset 仍默认「待安排」,保持不变

  • 工具栏与行操作不改

  • Step 2: 手动验收清单(开发机)

打开 http://localhost:3006/#/pl/plan-module/plan:

  1. Tab 顺序为:待安排 → 已安排 → 草稿中 → 全部 → 入库单 → 出库单 → 直销单
  2. 点「已安排」:列表仅跟进状态为「已安排」;筛选区跟进状态仅勾选「已安排」
  3. 点「全部」:跟进状态恢复默认勾选(不含已取消)
  4. 点「重置」:回到「待安排」
  5. 工具栏/行操作与其他 Tab 一致(无额外隐藏)
  • Step 3: Commit
git add web-admin/src/views/pl/plan/index.vue
git commit -m "$(cat <<'EOF'
feat(web-admin): sync followStatus when switching to arranged plan tab

Mirror pending_arrange behavior so the arranged tab forces followStatus filter to arranged.
EOF
)"
  • Step 4: 更新知识图谱(若本会话改过代码)
./scripts/update-graph.sh frontend

或:

cd web-admin && graphify update .

Spec 覆盖自检

Spec 要求 Task
Tab 顺序:待安排 → 已安排 → 草稿中 → … Task 1
筛选 followStatus=arranged Task 1 + Task 2
切回类型 Tab 恢复默认跟进状态 Task 1(isPlPlanFollowStatusListTab)+ Task 2
列表/工具栏不改 Task 2(刻意不改)
默认落地仍为待安排 Task 2(handleReset 不动)
后端不改 无对应 Task

无 TBD / 占位;类型名 arranged 前后一致。