9.4 KiB
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.vuepanelTitleBarTextRules注册「收款账户管理」
6. FormCreate 控件
6.1 规则形态
{
"type": "receiveAccount",
"field": "Fxxxx",
"title": "收款账户",
"info": "",
"$required": false,
"props": {
"multiple": true
}
}
本期不提供单选开关;multiple 恒 true。
6.2 交互
- 可编辑:PC
el-selectmultiple(选项 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. 实现顺序建议
- SQL + model + CRUD + API
- 菜单 SQL / 脚本
- 管理页
- 值工具 + FormCreate 控件注册 + 打印
- 联调发起/详情/打印
10. 决策记录
| 决策 | 选择 |
|---|---|
| 实现路径 | 单表 + FormCreate 自定义控件 |
| 权限 | 有菜单即可管 |
| 存值 | 完整快照数组 |
| 多选 | 固定多选 |
| 展示 | 完整字段 |
| 状态 | 仅软删,无启用停用 |