fujian_water_biz_doc/docs/superpowers/plans/2026-07-14-counter-charge-then-topup-continuation.md

6.0 KiB
Raw Blame History

Counter Charge Then Topup Continuation 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: 将单客户刚缴纳的账单保存为只读 history 展示行,并清空 selectedChargeRows。现有 noArrearsTopupMode 会忽略历史展示行并自动切换到预存提交路径;集收号路径不调整。

Tech Stack: Vue 3、TypeScript、Node.js node:test、现有柜台收费状态模型


File Structure

  • Modify: water-frontend/tests/operatingCharges/counterChargingPersistentTopup.test.mjs
    • 增加缴费后连续预存的状态契约测试。
  • Modify: water-frontend/src/views/operatingCharges/counterCharging/index.vue
    • 允许收讫账单使用历史展示状态,并在单客户缴费成功后清空选中行。
  • Create: water-docs/docs/evidence/bugfix/2026-07-14-counter-charge-then-topup-continuation.md
    • 记录根因、TDD 和回归验证结果。

Task 1: Reproduce the blocked continuation state

Files:

  • Modify: water-frontend/tests/operatingCharges/counterChargingPersistentTopup.test.mjs

  • Step 1: Add a failing test for single-customer post-payment state

test('single-customer payment keeps paid bills as history and clears the payable selection', () => {
  const submitStart = pageSource.indexOf('const confirmCharge = async')
  const submitEnd = pageSource.indexOf('const editCustomer =')
  const submitSection = pageSource.slice(submitStart, submitEnd)

  assert.match(
    submitSection,
    /setSettledChargeDisplayRows\(settledChargeRowsSnapshot,\s*'history'\)[\s\S]*selectedChargeRows\.value\s*=\s*\[\]/
  )
})
  • Step 2: Add a failing test for history-row semantics and unchanged hub behavior
test('paid bill history remains read-only while hub charging keeps its existing settled flow', () => {
  assert.match(
    pageSource,
    /const setSettledChargeDisplayRows = \([\s\S]*displayChargeState:\s*ChargeDisplayRowVO\['displayChargeState'\] = 'settled'[\s\S]*displayChargeState,[\s\S]*displayChargeType:\s*displayType/
  )
  assert.match(pageSource, /payState:\s*1,[\s\S]*payStateName:\s*'收讫'/)

  const submitStart = pageSource.indexOf('const confirmCharge = async')
  const submitEnd = pageSource.indexOf('const editCustomer =')
  const submitSection = pageSource.slice(submitStart, submitEnd)
  assert.match(
    submitSection,
    /if \(isHubChargeMode\.value\) \{[\s\S]*setSettledHubChargeDisplayRows\(settledChargeRowsSnapshot\)[\s\S]*selectedChargeRows\.value = \[\.\.\.settledChargeRowsSnapshot\]/
  )
})
  • Step 3: Run the focused test and verify RED

Run:

node --test tests/operatingCharges/counterChargingPersistentTopup.test.mjs

Expected: 9 个测试中原有 7 个通过,新增 2 个因缺少历史状态参数和选中行清理而失败。

  • Step 4: Commit the RED test
git add tests/operatingCharges/counterChargingPersistentTopup.test.mjs
git commit -m "test: reproduce blocked charge then topup flow"

Task 2: Convert paid bills to non-blocking history rows

Files:

  • Modify: water-frontend/src/views/operatingCharges/counterCharging/index.vue

  • Step 1: Parameterize the paid-bill display state

setSettledChargeDisplayRows 改为:

const setSettledChargeDisplayRows = (
  rows: CounterChargingChargeVO[],
  displayChargeState: ChargeDisplayRowVO['displayChargeState'] = 'settled',
  displayType: ChargeDisplayRowVO['displayChargeType'] = 'bill'
) => {
  settledChargeDisplayRows.value = rows.map((row) => ({
    ...row,
    payState: 1,
    payStateName: '收讫',
    displayChargeState,
    displayChargeType: displayType
  }))
}
  • Step 2: Change only the single-customer successful payment branch

将普通账单收费成功分支改为:

} else {
  setSettledChargeDisplayRows(settledChargeRowsSnapshot, 'history')
  selectedChargeRows.value = []
}
syncActualAmountFromSelection()

集收号分支继续保留:

setSettledHubChargeDisplayRows(settledChargeRowsSnapshot)
selectedChargeRows.value = [...settledChargeRowsSnapshot]
  • Step 3: Run the focused test and verify GREEN

Run:

node --test tests/operatingCharges/counterChargingPersistentTopup.test.mjs

Expected: 9/9 通过。

  • Step 4: Run the existing counter-charging regression test

Run:

pnpm test:counter-charging

Expected: 4/4 通过。

  • Step 5: Commit the implementation
git add src/views/operatingCharges/counterCharging/index.vue
git commit -m "fix: allow topup after counter payment"

Task 3: Verify and record evidence

Files:

  • Create: water-docs/docs/evidence/bugfix/2026-07-14-counter-charge-then-topup-continuation.md

  • Step 1: Run the combined focused tests

Run:

node --test tests/operatingCharges/counterChargingPersistentTopup.test.mjs tests/operatingCharges/counterChargingInventory.test.mjs

Expected: 13/13 通过。

  • Step 2: Run the frontend build

Run:

NODE_OPTIONS=--max-old-space-size=8192 pnpm build:dev

Expected: 退出码 0,输出 Build successful. Please see dist directory

不得运行 vue-tscpnpm ts:check 或任何会调用 vue-tsc 的命令。

  • Step 3: Check the final diff

Run:

git diff --check develop...HEAD
git status --short

Expected: 无空白错误,前端 worktree 干净。

  • Step 4: Record exact evidence

证据文档记录阻塞根因、RED 结果 7 通过/2 失败、GREEN 结果 9/9、组合测试 13/13、构建成功、集收号路径未调整以及未运行 vue-tsc

  • Step 5: Commit evidence
git add docs/evidence/bugfix/2026-07-14-counter-charge-then-topup-continuation.md
git commit -m "docs: record charge then topup verification"