Files
zkxw/docs/superpowers/specs/2026-07-30-oa-receive-account-design.md
T

9.4 KiB
Raw Blame History

OA 收款账户管理 +「收款账户」控件设计文档

日期: 2026-07-30
范围: backend 主数据表与 CRUD API;web-admin OA 菜单下收款账户管理页;FormCreate 自定义控件 receiveAccount(设计器 + 发起/详情/打印)
关联: docs/mockups/oa-receive-account-demo.html;docs/superpowers/specs/2026-07-27-oa-dept-select-design.md;docs/superpowers/specs/2026-07-30-oa-person-select-design.md;docs/web-admin-ui-spec-fresh-mint.md
状态: 已实现


1. 背景与目标

在「OA审批」菜单下增加 收款账户管理(租户级公共主数据),并在工作流表单设计器中增加 【收款账户】 组件,发起人可多选账户;审批单、详情、打印按类型 完整展示 所选账户全部字段。

1.1 产品结论(已确认)

项 结论
数据归属 租户级公共主数据;有菜单权限者均可看见并可 CRUD
账户类型 alipay 支付宝 / personal 个人银行卡 / corporate 对公银行账户
支付宝字段 户名、账号、备注
个人银行卡 / 对公 户名、账号、银行、省、市、银行支行、备注
启用/停用 不做;仅软删除;删除后控件不可再选
表单控件 本期同步做;固定 多选
存值 完整快照数组(含主数据 id + 全部业务字段);历史单据不受主数据后续修改/删除影响
展示 只读/详情/打印:完整展示全部字段(按类型省略支付宝不适用字段)
UI 模式 管理页 P01 标准列表;Demo:docs/mockups/oa-receive-account-demo.html

1.2 非目标

  • 启用/停用状态
  • 个人私有账户、数据权限按创建人过滤
  • 本控件参与流程条件分支(二期按需)
  • 本期小程序运行时渲染器(Schema/form_data 须可映射)
  • 账号在租户内唯一强制

2. 架构

[sys_menu] OA审批 → 收款账户管理
        ↓
[oa_receive_account] 租户主数据 CRUD
        ↓
[FormCreate DragRule type=receiveAccount]
        ↓
[OaReceiveAccountSelect] ← GET /receive-accounts/options
        ↓
form_data[field] = ReceiveAccountSnapshot[]
        ↓
[详情 / 打印] formatReceiveAccountDisplay(完整字段文本,多条换行)

FormCreate 四层扩展(对齐 person / dept / money):

层 内容
Runtime OaReceiveAccountSelect.vue
组件注册 formCreate.component('receiveAccount', …)
DragRule menu: 'main';label: '收款账户';props.multiple 固定 true
双侧注册 main.ts + oa-fc-host/main.ts 均调用 setupOaReceiveAccountSelect

3. 数据模型

3.1 表 oa_receive_account

字段 类型 说明
id VARCHAR(64) UUID 主键
account_type VARCHAR(16) alipay / personal / corporate
account_name VARCHAR(128) 户名,必填
account_no VARCHAR(128) 账号,必填
bank_name VARCHAR(128) 银行;支付宝为空
bank_province VARCHAR(64) 省;支付宝为空
bank_city VARCHAR(64) 市;支付宝为空
bank_branch VARCHAR(256) 支行;支付宝为空
tenant_no … 租户编号(公共字段)
order_num … 排序号
remark VARCHAR(512) 备注
create_by / create_dept_id / create_time / update_by / update_time / del_flag 公共字段

索引:idx_ora_tenant (tenant_no, del_flag);可选 idx_ora_type (tenant_no, account_type, del_flag)。

字段顺序:id → 业务字段 → 公共字段(符合 database-conventions)。

3.2 按类型校验(后端强制)

类型 必填 银行相关字段
alipay account_name、account_no 写入时清空为空串 / NULL
personal / corporate 户名、账号、银行、省、市、支行 均必填

3.3 表单快照值(ReceiveAccountSnapshot)

多选恒为数组;空选为 []。

[
  {
    "id": "主数据ID",
    "accountType": "personal",
    "accountName": "李四",
    "accountNo": "6222…",
    "bankName": "中国工商银行",
    "bankProvince": "安徽省",
    "bankCity": "合肥市",
    "bankBranch": "工行合肥长江中路支行",
    "remark": ""
  }
]

选择瞬间从主数据行拷贝上述字段;之后仅读快照展示,不再回查主数据。


4. API 与菜单

4.1 菜单

父菜单:OA审批(OA000000000000000000000000000001)

项 值
menu_name 收款账户管理
path receive-accounts
component /oa-approval/receive-accounts/index
perms oa:receive-accounts:list
menu_type C
visible / status 1
order_num 10(现有可见子菜单之后)

权限语义:有菜单即可增删改查(不另拆按钮权限,除非实现时对齐工程其它页习惯补 add/edit/remove)。

4.2 API

前缀:现有 APIRouter(prefix="/web/admin/oa-approval")。

方法 路径 说明
GET /receive-accounts 分页列表:keyword、accountType、page、pageSize;默认 create_time DESC
GET /receive-accounts/options 未删除选项列表(控件用,可不分页或大 pageSize)
GET /receive-accounts/{id} 详情
POST /receive-accounts 新增
PUT /receive-accounts/{id} 更新
DELETE /receive-accounts/{id} 软删
DELETE /receive-accounts 或批量接口 批量软删(对齐项目现有批量删除风格)

一律按当前用户 tenant_no 过滤/写入;del_flag=1 默认排除。

发布白名单:form_schema 允许的 type 集合增加 receiveAccount(与 person/dept/money 同位置)。

发起校验:receiveAccount 字段值须为快照对象数组(或空数组);必填时非空。


5. 管理页 UI

  • 路径:web-admin/src/views/oa-approval/receive-accounts/index.vue
  • 对齐:roles/index.vue、system/unit/index.vue;规范 Fresh Mint
  • 筛选:关键词(户名/账号/银行)、账户类型
  • 工具栏:已选 N 项 → 新增(唯一 primary)→ 批量删除(描边)
  • 表格列:类型 Tag、户名、账号、银行、开户地/支行、备注、操作(查看/编辑/删除,fixed="right")
  • 类型 Tag:alipay→success 系、personal→primary、corporate→warning(或 info),语义清晰即可
  • 弹窗:dialog-form-layout + form-grid-2;类型切换显隐银行字段;省/市优先用 fetchChinaRegionTree 取到市级(文本存储省名、市名)
  • App.vue panelTitleBarTextRules 注册「收款账户管理」

6. FormCreate 控件

6.1 规则形态

{
  "type": "receiveAccount",
  "field": "Fxxxx",
  "title": "收款账户",
  "info": "",
  "$required": false,
  "props": {
    "multiple": true
  }
}

本期不提供单选开关;multiple 恒 true。

6.2 交互

  • 可编辑:PC el-select multiple(选项 label:类型 · 户名 · 账号);窄屏对齐 person/dept 抽屉多选
  • 选项源:GET .../receive-accounts/options(仅未删除)
  • 选中时写入完整快照;取消选中从数组移除
  • 只读:完整字段展示,多条换行;支付宝不显示银行/省/市/支行

6.3 完整展示格式(建议)

每条一行(字段有值才拼接,用 · 连接):

  • 支付宝:支付宝 · {户名} · {账号} · {备注?}
  • 个人银行卡:个人银行卡 · {户名} · {账号} · {银行} · {省} / {市} · {支行} · {备注?}
  • 对公:对公银行账户 · …(同银行卡字段)

打印:oa-approval-print.ts 增加 receiveAccount 分支,使用同一 format 函数。

6.4 文件清单(前端)

文件 职责
components/oa-approval/OaReceiveAccountSelect.vue 控件
utils/oa-receive-account-value.ts 类型、normalize、format
utils/oa-receive-account-rule.ts DragRule
utils/oa-form-create-receive-account.ts setup 注册
api 模块补充 receive-accounts 接口 列表/选项/CRUD
main.ts / oa-fc-host/main.ts 调用 setup
views/oa-approval/receive-accounts/index.vue 管理页

7. 错误处理与边界

  • 主数据已删:控件选项不再出现;历史实例仍靠快照展示
  • 选项加载失败:控件空态 + ElMessage 提示
  • 类型切换(管理弹窗):清空不适用银行字段,避免脏数据提交
  • 同租户允许相同账号多条(靠备注/户名区分)

8. 测试要点

  • CRUD:三类账户字段校验与显隐正确;软删后列表与 options 不可见
  • 菜单:OA 下可见;无菜单角色不可进
  • 设计器可拖入「收款账户」;发布含该 type 不报错
  • 发起多选写入快照数组;改主数据后详情仍显示旧快照
  • 删除主数据后历史审批仍完整展示
  • 打印输出完整字段文本
  • 字段一致性:_row_to_dict ↔ Create/Update ↔ 前端 formData

9. 实现顺序建议

  1. SQL + model + CRUD + API
  2. 菜单 SQL / 脚本
  3. 管理页
  4. 值工具 + FormCreate 控件注册 + 打印
  5. 联调发起/详情/打印

10. 决策记录

决策 选择
实现路径 单表 + FormCreate 自定义控件
权限 有菜单即可管
存值 完整快照数组
多选 固定多选
展示 完整字段
状态 仅软删,无启用停用