版本:v1.0 | 日期:2026-06-03 基于
tboss-oa-product-strategy.md/tboss-oa-prd.md/tboss-oa-architecture.md/tboss-oa-database.md/tboss-oa-api.md架构前提:用户/组织/客户数据来自 ERP(通过 .NET API)、审批引擎复用 ERP、消息复用 .NET 服务端、OA 权限独立 ACL。
普通员工拥有 26 个基础页面的完整闭环:发起申请、查看个人流水、编辑草稿、撤回。
/)页面组件内容:
TDTabBar:消息、工作台、我的GoRouter + IndexedStack 视图容器微观组件交互:
#00ABF3/messages)页面组件内容:
TDNavbar 标题"消息通知",右侧"全部已读"按钮(仅未读>0 时显示)TDListView:消息图标(审批待办/审批结果/系统公告)、标题、发送人、发送时间(MM-DD HH:mm)、摘要文本、未读红点 TDBadge微观组件交互:
[标记已读](蓝) + [删除](红);已读消息不可左滑(无操作按钮)[标记已读] → 调 .NET 消息 API → 成功则红点淡出+透明度↓0.6;失败 Toast"操作失败,请重试"[删除] → TDDialog"确认删除?删除后不可恢复。"→ 确认则卡片收起+调 .NET 消息 API 删除/announcement/detail/:idbizType 路由至对应详情页,底部展审批操作栏bizType 路由至对应详情页数据来源:.NET 消息模块 API(非本地 Message 表)
/home)角色判定(决定工作台变体,查 OaUserPermission):
oa.admin.* → 管理员版oa.expense.mark_paid → 财务版oa.*.approve 或 oa.*.view_dept → 经理版员工版组件:
TDRotation 轮播图(3s 切换,点击有 LinkUrl→跳转,无→全屏预览双指缩放)。数据来源 SysBanner(OA 本地)/expense-apply/apply、费用报销→/expense/apply、用车申请→/vehicle/apply、加班申请→/overtime/apply/expense-apply/list、报销记录→/expense/list、外勤日志→/outing-log/list、公司公告→/announcement/list/expense-apply/list/report/expense-detail/messages(筛选 approval_notice)经理版增量:
GET /api/oa/approval/pending-count),点击→/messages(筛选 approval_notice)财务版增量:
/profile)页面组件内容:
GET /api/user/{erpUserId}微观组件交互:
PUT /api/user/avatar → 全局刷新;失败 Toast"头像上传失败"子页面:我的审批历史
GET /api/oa/approval/my-history?userId={erpUserId}&page=1(.NET 服务端汇总各 ERP 审批记录)子页面:我的报表聚合页
/loan/apply)页面组件内容:
POST /api/oa/loan/submit/loan/list)同标准列表:TDChip(全部/草稿/审批中/已通过/已拒绝/已撤回)+ 还款状态标签(未还/部分已还/已还清)
/loan/detail/:id)展示借款信息+审批时间线。已通过且未还清的借款展示还款记录列表。
/expense-apply/apply)页面组件内容:
FormSection 基本信息:申请人姓名(只读,GET /api/user/{erpUserId})、所属部门(只读,同上)、申请日期(只读,DateTime.now())、紧急程度(TDRadioGroup:普通/紧急/特急)、费用类型(TDCheckboxGroup 多选,至少一项,如"差旅费"+"办公费")、费用事由(TDTextarea,≤200 字)FormSection 关联管控:关联项目(TDPicker 级联,.NET → ERP ProjectService)、预算科目(.NET → ERP SubjectService)、可用余额(.NET → ERP BudgetService,ERP 无预算则隐藏此区块)FormSection 动态预估明细:[+ 添加费用明细],每项含费用类别、预估金额(TDInput 纯数字)、明细说明FormSection 支撑材料上传:TDImageGrid 最大 6 张,图片≤10MB/PDF≤20MB。点击[+]唤起相册/相机/文件;满 6 隐藏[+];点击缩略图→黑底全屏预览(双指缩放 0.5x~3x);PDF→原生查看器;缩略图⊖→气泡确认删除。存入 Attachment (BizType='expense_apply')[重置]+[存为草稿]+[提交审批];新建时仅后两者微观组件交互:
[重置]→确认弹窗→清空至初始状态页间流转:
[存为草稿] → Loading → PUT /api/oa/expense-apply/draft → Toast 绿"已保存为草稿" → 跳列表(激活"草稿"Chip);失败 Toast 红[提交审批] → 全局校验 → ScrollTo 报错字段(300ms)+红闪+TDMessage → Loading → POST /api/oa/expense-apply/submit → .NET 服务端创建 ERP 审批实例 → 返回 ApprovalInstanceId → 存 OA → Toast"已提交,等待审批" → 跳列表/expense/apply)页面组件内容:
GET /api/dict/banks)、户名(默认当前用户)、账号(校验 16-19 位)SysCostCategory)、币种(TDPicker,默认 CNY,选外币自动从 ERP 填汇率)、原币金额→自动算本币、发票类型/号码/代码/税率。标准校验超标行标红+触发特批Attachment (BizType='expense'),可绑定明细行微观组件交互:
页间流转:同页面 4,API 为 POST /api/oa/expense/submit
页面组件内容:
微观组件交互:
#00ABF3→列表淡入淡出刷新;无数据→TDEmpty(文案随 Chip 变化)ApprovalStatus 缓存,后台静默从 .NET→ERP 刷新[编辑](蓝)+[删除](红);其他状态左滑无反应[删除]→TDDialog"确认删除?不可恢复。"→卡片收起+软删除经理版增量:
[我的发起] / [下属审批] 范围标签[下属审批]→骨架屏→加载部门下属单据(GET /api/oa/approval/subordinates),卡片追加申请人姓名-部门[一键同意](绿),就地审批(POST /api/oa/approval/action)财务版增量(仅页面 7):
[待付款] Chip(筛选 Status='approved' AND PaymentStatus='unpaid')[线下已付款],标记 PaymentStatus='paid'页面组件内容:
--fs-caption 字号)GET /api/oa/approval/timeline?bizType=&bizId= → .NET → ERP。首节点"发起人已提交"(拼装 CreateTime+申请人)。若 withdrawn→末尾追加撤回节点微观组件交互:
[编辑]+[提交审批];提交校验失败→TDDialog"去编辑"/"取消"[撤回申请]→TDDialog 确认 → POST /api/oa/approval/withdraw → ApprovalStatus='withdrawn',旧 instanceId 追加到 PreviousInstanceIds → 页面刷新[重新编辑并发起]→跳表单编辑态,提交后更新原记录[变更申请] 按钮 → 弹出变更类型选择(追加金额/减少金额/新增明细/删除明细/延期)→ 填写变更事由 → 提交触发补充审批(存入 ExpenseApplicationChange,ApprovalInstanceId 关联 ERP 补充审批)。审批通过后 .NET 自动将 AfterSnapshot 写回主表和明细表GET /api/user/{approverId})经理版底部操作栏(pending 且当前审批人=该经理时展示):
┌──────────────────────────────────────────────────────────┐
│ [拒绝] (必填理由) │ [转交] (调原生通讯录) │ [同意] (下流转) │
└──────────────────────────────────────────────────────────┘
[拒绝]→TDDialog 输入理由,≥5 字解锁确定按钮 → POST /api/oa/approval/action {action:reject}[转交]→MethodChannel 通讯录单选 → POST /api/oa/approval/action {action:transfer, transferToUserId}[同意]→Loading → POST /api/oa/approval/action {action:approve} → 节点变绿流转管理员版底部操作栏:
[强制终止](红底白字)+ [查看审批链](含历史 instanceId 流程)。管理员不展示同意/拒绝/转交财务版增量(仅页面 9):
[退回修改]→选退回节点(员工重填/经理重审)→状态倒流[确认已线下打款并归档]→解锁后滑出凭证表单(电汇流水号+记账凭证号必填)→提交→PaymentStatus='paid'→归档[下一笔待付款]→跳转下一笔 approved+unpaid;无→"已无待付款单据"+Toast/overtime/apply)页面组件内容:
微观组件交互:
POST /api/oa/overtime/submit交互同页面 6/7 和 8/9。加班类型标签(工作日/休息日/节假日)、补偿方式展示(加班费/转调休/"X%调休+Y%结算")。员工端仅 [撤回]。
/vehicle/apply)页面组件内容:
SysVehicle 车池,冲突车辆标红"冲突";无可用→TDEmpty)POST /api/oa/vehicle/submit微观组件交互:
列表增量:
returned 状态)[确认还车],拉起核销抽屉详情-还车登记:
[确认还车并登记](提前还车标灰字提示;超时标红字提示)/outing-log/create)页面组件内容:
GET /api/customer/search?q=;无匹配→自由文本,提交时 .NET 自动创建 ERP 客户)微观组件交互:
[存为草稿]+[提交],提交调 PUT /api/oa/outing-log/submit列表:
OutingLogComment.CreateTime > COALESCE(LastViewedTime,'1900-01-01') 且评论者≠本人[编辑]+[删除];completed 左滑无反应详情:
PUT /api/oa/outing-log/:id/view,更新 LastViewedTime,列表红点消失经理版增量:
OutingLogComment,同步更新 OutingLog.UpdateTime/announcement/list)组件:
GET /api/user/{publisherId}→DeptName)、发布时间(MM-DD HH:mm)、未读红点(AnnouncementReadLog.IsRead=0)/announcement/detail/:id)组件:
Attachment (BizType='announcement'));空则整区隐藏。点击→原生浏览器/下载管理器;失败→Toast交互:
POST /api/oa/announcement/:id/read;<2s 返回不发。返回列表后红点消失管理员版增量:
[已读 N 人](绿)+[未读 N 人](灰)。点击展开员工列表(头像+部门,数据来源 AnnouncementReadLog + GET /api/user/{id})[一键 DING]→震动反馈→封装未读 UserIds→MethodChannel 强推 Push/短信→Toast"已向 N 名未读员工发送催办通知"统一框架:
各报表内容:
| 页面 | 报表 | 数值卡片 | 趋势图 |
|---|---|---|---|
| 21 | 事前申请明细 | 累计申请总额/本月笔数/已通过笔数/已通过金额 | 近 12 月申请金额 vs 已通过金额双折线 |
| 22 | 费用报销明细 | 累计已核销总额/本月笔数/待审批笔数/待付款笔数 | 近 12 月报销金额 vs 审批通过金额双折线 |
| 23 | 加班明细 | 本月累计净工时/本月次数/累计调休小时/加班费次数 | 近 12 月加班工时柱状图(按类型分色堆叠) |
| 24 | 用车明细 | 本月次数/累计里程/路桥停车费/未还车数 | 近 12 月用车次数 vs 费用双轴折线 |
| 25 | 外勤日志明细 | 本月拜访次数/拜访客户数(去重)/均分/未点评数 | 近 12 月拜访次数 vs 平均评分双轴折线 |
经理版增量:柱状图点击柱体→下方列表联动过滤该员工本月单据→可穿透跳详情页
财务版增量(仅页面 22):多维级联筛选(部门树+项目组)+ [数据流水一键导出]→Loading→.NET 生成 Excel→MethodChannel 唤起系统分享面板
审批人拥有与员工完全对称的 26 个页面路由体系,但通过 OA 权限判定自动发生 UI 变体。
OaUserPermission 判定工作台聚合优先级:Admin > Finance > Approver > Employee。高优先级角色专属区块逐层叠加。权限列表在 App 启动时一次性拉取并写入全局 Provider。
页面 3(经理版):金刚区上方插入【待我处理的审批】高规格动态卡片,红色角标待办数(GET /api/oa/approval/pending-count),点击→/messages(筛选 approval_notice)
页面 6/7/11/14/17(经理版):
[我的发起] / [下属审批] 范围标签[下属审批]→骨架屏加载部门下属单据(GET /api/oa/approval/subordinates),卡片追加申请人姓名-部门[一键同意](绿),就地审批页面 8/9/12/15(经理版):
[拒绝](白底红字,必填≥5字理由)+ [转交](灰底,MethodChannel 通讯录单选)+ [同意](#00ABF3,下流转)POST /api/oa/approval/action页面 18(经理版):底部【主管批示及打分专区】(TDRate 5 星 + 文字输入 + 发送按钮)
页面 21~25(经理版):数据范围自动升级为部门聚合。图表渲染部门内部员工横向对比柱状图。点击柱体→联动过滤+穿透跳详情页。
财务人员专注于发票查验、线下付款确认及凭证归档。
权限要求:oa.expense.mark_paid + oa.*.view_all + oa.report.export
页面 3(财务版):全公司级财务看盘(已支付流水/待付款总额/异常退回数)
页面 7(财务版):
[待付款] Chip[线下已付款]快捷标记页面 9(财务版-核心核销专区):
[退回修改]→选退回节点(员工重填/经理重审)→状态倒流[确认已线下打款并归档]→滑出凭证表单(电汇流水号+记账凭证号必填)→归档。按钮替换为 [下一笔待付款]→连续核销页面 22(财务版):多维级联筛选 + [数据流水一键导出]→Excel→系统分享面板
管理员拥有最高权限,独有 2 个管理专属页。
权限要求:oa.admin.*
页面 8/9/12/15(管理员版):底部 [强制终止](红底白字)+ [查看审批链](含所有历史 instanceId 流程)。不展示经理版同意/拒绝/转交。
页面 20(管理员版):公告底部【触达率审计追踪卡片】(已读/未读人数+员工列表+TDDialog 头像详情)。[一键 DING]→强推 Push/短信。
页面 26:公告发布 (/announcement/create):
[预览]→TDDialog 全屏模拟详情页[存为草稿](仅创建者+管理员可见)+ [预览] + [发布][发布]→确认弹窗"确认向 N 名员工发布?发布后不可撤回。"→写入 Announcement + 异步初始化 AnnouncementReadLog → Toast页面 27:权限管理 (/admin/permissions):
GET /api/user/search?q=[确认保存]→ PUT /api/oa/user-permissions → 写 OaPermissionChangeLogOaPermissionChangeLog)| Token | 值 | 用途 |
|---|---|---|
--primary |
#00ABF3 |
主按钮/激活态/高亮 Chip/链接 |
--primary-light |
#E6F7FD |
主色浅底 |
--primary-active |
#0089C4 |
主色按压态 |
--success |
#00A870 |
已通过/同意/金额正面 |
--warning |
#E37318 |
审批中/超支警告/排期冲突 |
--danger |
#D54941 |
已拒绝/拒绝/删除/强制终止 |
--text-primary |
#1A1A1A |
标题/关键金额 |
--text-secondary |
#666666 |
摘要/辅助说明/时间戳 |
--text-placeholder |
#BFBFBF |
占位符/禁用文字 |
--bg-page |
#F5F5F5 |
页面背景 |
--bg-card |
#FFFFFF |
卡片/表单底色 |
--border |
#E7E7E7 |
分割线/描边/输入框边框 |
--status-gray |
#999999 |
草稿/已撤回/已过期 |
| Token | 字号 | 行高 | 用途 |
|---|---|---|---|
--fs-title |
18sp | 26px | 导航栏标题/详情大标题 |
--fs-subtitle |
16sp | 24px | 卡片标题/表单分组/金额大字/按钮 |
--fs-body |
14sp | 22px | 正文/列表摘要/输入框/Chip |
--fs-caption |
12sp | 18px | 辅助说明/时间戳/状态标签/红点数 |
| Token | 值 | 用途 |
|---|---|---|
--space-xs |
4px | 图标与文字间距/Chip 内边距 |
--space-sm |
8px | 列表项内 padding/表单行间距 |
--space-md |
16px | 卡片内边距/页面左右边距 |
--space-lg |
24px | 表单分组间距/卡片间距 |
--space-xl |
32px | 页面顶部/底部留白 |
| 场景 | 文案 |
|---|---|
| 消息列表为空 | "暂无消息通知" |
| 申请列表为空 | "暂无记录,点击下方按钮发起申请" |
| 审批列表为空 | "暂无待审批单据" |
| 报销明细为空 | "暂无报销明细,请先添加费用明细" |
| 照片墙为空 | "暂无附件" |
| 搜索无结果 | "未找到匹配的员工,试试其他关键词" |
| 公告列表为空 | "暂无行政公告" |
| 报表无数据 | "所选时间范围内暂无数据" |
| 场景 | 方式 |
|---|---|
| 页面首次加载 | TDSkeleton 骨架屏(最长 8s 超时转网络异常态) |
| 下拉刷新 | RefreshIndicator |
| 上拉加载更多 | 底部菊花 + "加载中..." |
| 按钮提交中 | 按钮替换为 TDLoading 小菊花 + 禁用态 |
| 附件上传中 | 缩略图叠加半透明蒙层 + 中心菊花 |
| 一键导出中 | 圆形悬浮按钮旋转 + "导出中..." |
| 场景 | 处理 |
|---|---|
| 列表加载失败 | TDEmpty + 断网图标 + [点击重试] |
| 提交失败 | TDToast(红)"提交失败,请稍后重试" |
| 接口超时(>15s) | TDEmpty + 时钟图标 + [点击重试]"请求超时" |
| 服务端 500 | TDToast"服务器繁忙,请稍后重试" |
| 401 未授权 | 静默触发宿主登录流程 |
| 场景 | 处理 |
|---|---|
| 编辑草稿时单据已被他人提交 | CONCURRENCY_CONFLICT→TDDialog"已被修改或删除"→返回列表刷新 |
| 审批时单据已被他人处理 | APPROVAL_CONFLICT→详情页自动刷新+Toast"状态已更新" |
tboss://oa/{path} → GoRouter 路由| 页面 | 路由 | 标题 |
|---|---|---|
| 1 | / |
—(Appshell) |
| 2 | /messages |
"消息通知" |
| 3 | /home |
"TBOSS 工作台" |
| 3.1 | /profile |
"我的" |
| 4 | /expense-apply/apply |
"事前申请" |
| 5 | /expense/apply |
"费用报销" |
| 6 | /expense-apply/list |
"申请记录" |
| 7 | /expense/list |
"报销记录" |
| 8 | /expense-apply/detail/:id |
"申请详情" |
| 9 | /expense/detail/:id |
"报销详情" |
| 10 | /overtime/apply |
"加班申请" |
| 11 | /overtime/list |
"加班记录" |
| 12 | /overtime/detail/:id |
"加班详情" |
| 13 | /vehicle/apply |
"用车申请" |
| 14 | /vehicle/list |
"用车记录" |
| 15 | /vehicle/detail/:id |
"用车详情" |
| 16 | /outing-log/create |
"外勤日志" |
| 17 | /outing-log/list |
"外勤记录" |
| 18 | /outing-log/detail/:id |
"日志详情" |
| 19 | /announcement/list |
"公司公告" |
| 20 | /announcement/detail/:id |
"公告详情" |
| 21 | /report/expense-apply-detail |
"事前申请明细报表" |
| 22 | /report/expense-detail |
"费用报销明细报表" |
| 23 | /report/overtime-detail |
"加班明细报表" |
| 24 | /report/vehicle-detail |
"用车明细报表" |
| 25 | /report/outing-log-detail |
"外勤日志明细报表" |
| 26 | /announcement/create |
"发布公告" |
| 27 | /admin/permissions |
"权限管理" |
文档版本:v1.0 | 日期:2026-06-03