# 供水财务结算中心 2026-09-17:接续 09-16 草稿,完成独立 `/water-finance` 页面及收款看板、筛选、详情、对账导出和收款登记。参考图位于 `references/water-finance-reference-20260916.png`。 ## 09-17 新增提现展示测试 - 用户要求增加几个待审核测试申请,新增独立 `sa_water_withdrawal_demo`,通过 Eloquent `WaterWithdrawalDemo` 与 `finance/WithdrawalDemo` 读取。该表只有展示夹具,不能作为可提现余额或支付指令;此前无数据库迁移的说明仅指收款看板。 - 执行并幂等复跑 `php -d extension=mbstring scripts/migrate_water_withdrawal_demo.php --apply` 和 `php -d extension=mbstring scripts/seed_water_withdrawal_demo.php --apply --http`,固定批次 `TEST-WATER-WITHDRAWAL-20260917`。4条待审核模拟申请:星澜商务5760元、青禾推广用户860元、云帆企业服务3280元、森屿商贸2460元,共12360元;ID1–4,日期09-17,名称均加【提现测试】,渠道为模拟微信/银行账户,不保存实际收款账号。 - 看板新增独立 `withdrawal_demo: {list,total,amount_cents}`,默认展示最新20条(本批仅4条),按月份及当前时间截止;all/demo包含、regular排除,流水关键词/分页不影响。可选测试表不存在时返回空列表,不阻断原收款看板。 - 页面待审核区展示姓名、金额、渠道、日期及“待审核(测试)”,顶部卡片显示“待提现审核(测试)”与模拟总额;真实 `summary.pending_withdrawal_cents` 仍null,`withdrawals`仍空,`capabilities.withdrawals`仍false,审核按钮继续禁用。测试申请不进入收款趋势或对账导出。 - 首次写入比较原收款/权益/库存/配送/代理完整快照及原看板字段均不变,只追加一条 `demo_seed` 审计;复跑 `replayed=true`,不重复插入或覆盖已有行。PHP lint、筛选/时间/快照检查、4组真实HTTP与98项财务回归通过。 - 本轮前端ESLint、Prettier、Stylelint、vue-tsc和Vite生产构建通过,dist更新。浏览器工具的既有认证故障未解除,本轮不声称实际点击或截图验收。 ## 业务口径 - 金额来自供水 `WaterOrder` 的已登记线下购水订单,以整数分汇总。展示登记时间,不推断银行到账日期;不接入旧租赁押金或分润数据。 - 今日卡片固定为上海时间当天零点至当前时间;所选月汇总、趋势与流水取月初至月末,当月截止当前时间,排除未来记录。缺少记录的日期补零;搜索与分页只影响流水。 - 数据范围:`all` 全部、`regular` 排除已标记测试、`demo` 仅已标记测试。凭据以 `TEST-` 开头或订单套餐快照名称含“测试”识别为测试。该识别依据现有种子约定,不保证发现未标记模拟数据;`regular` 不等于银行已对账。 - 退款、现金推广奖励、提现尚无业务规则或账本,相关金额及净收率为 `null`,能力开关为 `false`。新成交购水订单佣金按直接归属代理等级和后台当前比例计提(默认一级10%、二级5%、三级2%),财务看板的 `pending_commission_cents` 为全量待结算余额;提现审核仍不可用。 - 收款登记继续调用原 `WaterBusiness::purchase()`:核实凭据后登记订单、发放套餐权益,凭据全局唯一且重试幂等,不创建实物库存。页面展示套餐金额与权益,变更企业、套餐、凭据后须重新勾选核对。只读账号没有收款按钮。 ## 分层与接口 - `controller/water/WaterController.php` 只做权限、请求和响应转换。 - `service/WaterFinanceDashboard.php` 负责查询与导出,`service/finance/FinanceFilters.php` 统一校验月份、范围、关键词及分页。 - `model/water/WaterOrder.php` 的 `financePeriod/financeSource/financeDetails` scopes 通过 Eloquent 访问数据;没有新增表或迁移。 - `GET /core/water/finance/dashboard` 与 `POST /core/water/finance/export` 均需 `water:finance:read`,路由在 `plugin/saiadmin/config/route.php`,在通用模块路由之前。 - 入参:`month`(`YYYY-MM`,2000-01 至本月,默认上海本月)、`source`(默认 `all`)、`keyword`(最长120字,企业/凭据/套餐)、`page`(默认1)、`limit`(默认8,最大100)。非法月份,包括空字节、溢出月份和未来月份,返回业务错误。 - 看板返回 `summary/trend/list/period/capabilities/withdrawals/updated_at`。流水按登记时间、ID倒序,金额为分,包含订单快照、流水号、企业、测试标记。 - XLSX 导出使用已查询的月份/范围/关键词,忽略分页,最多50,000条;超过上限明确拒绝。金额为元数值,企业/凭据/套餐的公式前缀转义,临时文件生成后清理。前端复用 `waterDownload`,拒绝将接口错误作为工作簿下载。 - `POST /core/water/finance`,`action=purchase`,继续要求 `water:finance:write`;企业与套餐选项通过原 finance/options 获取。 ## 前端 - `src/api/water/finance.ts` 定义接口契约与金额展示。 - `src/views/water/finance/index.vue`:四张卡片、月份与数据范围、按日趋势、月汇总、未开通提现区、搜索分页、详情、导出、错误重试。共享 `WaterMetricCards/WaterChart`;窄屏改为单列。 - `ReceiptDialog.vue`:企业/套餐远程搜索、金额及权益预览、凭据校验、核对勾选、提交锁、失败保留输入与幂等重试提示。 - 异步查询使用序号忽略过期结果;刷新期间独立保留分页总数,避免清空数据时被分页组件重置为第一页。 ## 验证 在 server 中: ```powershell php -d extension=mbstring tests/water_finance_dashboard_test.php --http php -d extension=mbstring tests/water_business_test.php ``` - 财务98项通过:月份/闰年/上海时区/当天截止、范围和关键词、补零、汇总对账、稳定分页、空状态、全量XLSX与公式注入、超过50,000条、权限、JSON控制器、收款及权益幂等、真实HTTP看板和导出。测试在事务内插入夹具,结束全部回滚;HTTP只读。 - 原供水业务69项回归通过;本轮相关PHP文件全部通过 `php -l`。 - 前端 `vue-tsc --noEmit`、相关ESLint/Prettier/Stylelint、Vite生产构建通过(3323 modules),`dist` 已更新。仅有既有 system/menu 组件动静态导入提示。 - 本地4173预览响应200;按UTF-8核对首页与构建完全一致,财务资源经SHA256核对一致,确认预览已提供本次产物。 - 2026-09-17 浏览器验收工具再次返回 `unsupported Codex auth method: apikey`;无法进行实际点击、截图及窄屏视觉验收。这是工具认证阻塞,不能据此判断项目登录异常,也不能声称已完成视觉验收。 后续开通退款、佣金结算、现金推广奖励、提现前仍需确定业务规则及付款渠道,另建可审计账本和权限闭环,不可直接启用占位按钮。 ## 2026-10-19 推广赠水 财务页面新增“推广赠水奖励”入口,沿用财务读写权限,可配置活动、查询邀请、审核发放或驳回。赠水只增加供水权益,与收款收入、现金提现分别记账;capabilities.rewards报告赠水活动开关。配置默认关闭,详见 [WATER_PROMOTION.md](WATER_PROMOTION.md)。