tboss-oa-design.md 31 KB

TBOSS OA 模块 — 全量 UI 设计

版本: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。


一、普通员工 (Employee) 角色视图

普通员工拥有 26 个基础页面的完整闭环:发起申请、查看个人流水、编辑草稿、撤回。

1. 框架与导航页(4 页)

页面 1:Appshell 底部导航 (/)

页面组件内容

  • 底部 TDTabBar:消息、工作台、我的
  • 主内容区:GoRouter + IndexedStack 视图容器

微观组件交互

  • 点击 Tab → 路由切换,图标变 #00ABF3
  • 重复点击当前 Tab → 列表页 ScrollToTop,非列表无行为
  • 消息 Tab 角标:未读消息数,进入时拉取 + 30s 轮询或宿主 Push 刷新,数据来源 .NET 消息模块 API

页面 2:消息通知聚合页 (/messages)

页面组件内容

  • TDNavbar 标题"消息通知",右侧"全部已读"按钮(仅未读>0 时显示)
  • TDListView:消息图标(审批待办/审批结果/系统公告)、标题、发送人、发送时间(MM-DD HH:mm)、摘要文本、未读红点 TDBadge

微观组件交互

  • 左滑卡片 → [标记已读](蓝) + [删除](红);已读消息不可左滑(无操作按钮)
  • [标记已读] → 调 .NET 消息 API → 成功则红点淡出+透明度↓0.6;失败 Toast"操作失败,请重试"
  • [删除] → TDDialog"确认删除?删除后不可恢复。"→ 确认则卡片收起+调 .NET 消息 API 删除
  • 下拉刷新(page=1)/ 上拉加载(page++)
  • 点击"公告通知"卡片 → /announcement/detail/:id
  • 点击"审批待办"卡片 → 按 bizType 路由至对应详情页,底部展审批操作栏
  • 点击"审批结果"卡片 → 按 bizType 路由至对应详情页

数据来源:.NET 消息模块 API(非本地 Message 表)


页面 3:工作台 (/home)

角色判定(决定工作台变体,查 OaUserPermission):

  • oa.admin.* → 管理员版
  • 无 admin 但有 oa.expense.mark_paid → 财务版
  • 无上述但有 oa.*.approveoa.*.view_dept → 经理版
  • 其余 → 员工版

员工版组件

  • TDRotation 轮播图(3s 切换,点击有 LinkUrl→跳转,无→全屏预览双指缩放)。数据来源 SysBanner(OA 本地)
  • 金刚区(TDGrid 4 列):
    • 第一行(发起):事前申请→/expense-apply/apply、费用报销→/expense/apply、用车申请→/vehicle/apply、加班申请→/overtime/apply
    • 第二行(记录):申请记录→/expense-apply/list、报销记录→/expense/list、外勤日志→/outing-log/list、公司公告→/announcement/list
  • 快捷看板:本月累计报销(大字)、本月已提单据总数、待处理单据总数。数据由 .NET 服务端预计算(缓存 5min),下拉强制穿透缓存
    • 点击"已提单据"→/expense-apply/list
    • 点击"本月报销"→/report/expense-detail
    • 点击"待处理"→/messages(筛选 approval_notice)

经理版增量

  • 金刚区上方插【待我处理的审批】卡片,红色角标显示待办数(GET /api/oa/approval/pending-count),点击→/messages(筛选 approval_notice)

财务版增量

  • 顶部替换为全公司财务看盘(已支付流水/待付款总额/异常退回数),数据来源 .NET 服务端全公司聚合查询

页面 3.1:个人中心 (/profile)

页面组件内容

  • 头像(TDAvatar,点击更换)、姓名、部门、岗位。数据来源 GET /api/user/{erpUserId}
  • 功能列表:我的审批历史、我的报表、关于 TBOSS OA

微观组件交互

  • 头像 → 唤起相册/相机 → 裁剪(1:1,≤2MB) → PUT /api/user/avatar → 全局刷新;失败 Toast"头像上传失败"
  • 登录态:宿主 App 统一管理。OA 监听宿主登出事件→清本地缓存;API 401→MethodChannel 通知宿主重登录

子页面:我的审批历史

  • 按时间倒序展示本人发起的所有单据审批流水,按单据分组
  • 每组卡片:单据编号(可点击跳详情页)、类型标签(事前申请/报销/加班/用车)、审批时间线摘要
  • 数据来源:GET /api/oa/approval/my-history?userId={erpUserId}&page=1(.NET 服务端汇总各 ERP 审批记录)
  • 下拉刷新 / 上拉加载;空数据 TDEmpty"暂无审批记录"

子页面:我的报表聚合页

  • 顶部 TDTabBar 五 Tab:事前申请/费用报销/加班明细/用车明细/外勤日志
  • 切换渲染页面 21~25 个人报表视图

2. 费用控制与报销模块(10 页)

页面 4.0:借款/备用金表单 (/loan/apply)

页面组件内容

  • 借款类型 TDPicker(备用金/差旅借款)
  • 借款金额 TDInput(纯数字)
  • 借款事由 TDTextarea
  • 同其他审批表单:存草稿+提交审批,调 POST /api/oa/loan/submit

页面 4.0a:借款列表 (/loan/list)

同标准列表:TDChip(全部/草稿/审批中/已通过/已拒绝/已撤回)+ 还款状态标签(未还/部分已还/已还清)

页面 4.0b:借款详情 (/loan/detail/:id)

展示借款信息+审批时间线。已通过且未还清的借款展示还款记录列表。


页面 4:事前申请表单 (/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 纯数字)、明细说明
  • 提交时 .NET 调 ERP StandardService 校验费用标准,超标行标红+触发特批
  • FormSection 支撑材料上传:TDImageGrid 最大 6 张,图片≤10MB/PDF≤20MB。点击[+]唤起相册/相机/文件;满 6 隐藏[+];点击缩略图→黑底全屏预览(双指缩放 0.5x~3x);PDF→原生查看器;缩略图⊖→气泡确认删除。存入 Attachment (BizType='expense_apply')
  • 底部操作栏:编辑草稿时 [重置]+[存为草稿]+[提交审批];新建时仅后两者

微观组件交互

  • [重置]→确认弹窗→清空至初始状态
  • 预算余额展示:项目+科目选定后异步加载"当前可用预算余额:¥XXXX.xx"。数据来源 .NET 转发 ERP(或 OA 自建 SysProjectBudget)
  • 预估金额合计 > 可用余额 → 汇总区变红 + 警告"您的申请金额已超支,提交后将自动触发高管特批流程"
  • 明细 [+]/✕ 增删动画
  • 返回(有未保存修改)→TDDialog"是否退出?"

页间流转

  • [存为草稿] → 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"已提交,等待审批" → 跳列表

页面 5:费用报销表单 (/expense/apply)

页面组件内容

  • 顶部【导入已通过的事前申请】蓝色高亮快捷链。支持导入多张申请,每张填导入金额
  • 对公/对私切换 TDSwitch:对私(默认)→ 收款人账户;对公 → 供应商名称+对公账户
  • 基本信息:报销事由、关联成本中心(TDPicker,.NET → ERP CostCenterService,可空)、报销总金额(只读,明细累加上浮动画)。项目和科目从导入的申请自动带入
  • 收款账户(对私):开户行(TDInput+下拉联想,GET /api/dict/banks)、户名(默认当前用户)、账号(校验 16-19 位)
  • 供应商(对公):供应商名称 TDInput、对公银行账户
  • 动态报销明细:发生日期、费用类别(TDPicker,SysCostCategory)、币种(TDPicker,默认 CNY,选外币自动从 ERP 填汇率)、原币金额→自动算本币、发票类型/号码/代码/税率。标准校验超标行标红+触发特批
  • 费用分摊:明细行可指定分摊比例+目标部门/项目(如 60%→DeptA,40%→DeptB),不分摊时留空
  • 发票上传:TDImageGrid 最大 9 张,≤10MB。存入 Attachment (BizType='expense'),可绑定明细行
  • 若员工有未还借款,提交时自动匹配冲销:报销金额先抵借款,余款退/补

微观组件交互

  • [导入事前申请] → 半屏抽屉多选:罗列 approved 且尚有额度的申请,每条填导入金额。空→TDEmpty。可追加多条,已选列表可移除
  • 借款匹配:提交时 .NET 自动查未还借款 → 弹窗展示冲销明细("报销 ¥8000 → 抵借款 ¥5000 → 实退 ¥3000"),用户确认后提交
  • 发票金额输入→底部总金额上浮动画累加
  • 明细增删、附件预览同页面 4
  • 银行账号前端校验 16-19 位

页间流转:同页面 4,API 为 POST /api/oa/expense/submit


页面 6/7:事前申请/费用报销列表页

页面组件内容

  • TDNavbar 标题"申请记录"/"报销记录"
  • TDChip 筛选:全部/草稿/审批中/已通过/已拒绝/已撤回
  • TDListView 流水卡片:单据编号、事由摘要、金额(粗体高亮)、提单日期、StatusTag(灰-草稿/橙-审批中/绿-已通过/红-已拒绝/灰-已撤回)

微观组件交互

  • 首次加载默认"全部"Chip
  • Chip 切换→高亮 #00ABF3→列表淡入淡出刷新;无数据→TDEmpty(文案随 Chip 变化)
  • 下拉刷新(page=1)/ 上拉加载(page++)。列表数据来源 OA 本地 ApprovalStatus 缓存,后台静默从 .NET→ERP 刷新
  • draft/rejected 卡片左滑→[编辑](蓝)+[删除](红);其他状态左滑无反应
  • [删除]→TDDialog"确认删除?不可恢复。"→卡片收起+软删除
  • 点击卡片→对应详情页

经理版增量

  • 导航栏下方 [我的发起] / [下属审批] 范围标签
  • 切换到 [下属审批]→骨架屏→加载部门下属单据(GET /api/oa/approval/subordinates),卡片追加申请人姓名-部门
  • pending 下属卡片左滑→[一键同意](绿),就地审批(POST /api/oa/approval/action

财务版增量(仅页面 7)

  • 独家 [待付款] Chip(筛选 Status='approved' AND PaymentStatus='unpaid')
  • 卡片左滑→[线下已付款],标记 PaymentStatus='paid'

页面 8/9:事前申请/费用报销详情页

页面组件内容

  • 状态大色块横幅:图标(⏳/✅/❌/↩)+状态中文+当前审批人姓名。已撤回底灰。审批人姓名从 .NET API 获取
  • 提交时间(CreateTime,--fs-caption 字号)
  • 单据信息+费用明细表(key-value 双栏;>5 行折叠+展开按钮)
  • 附件宫格(页面 8:支撑材料;页面 9:发票影像)
  • 审批时间线:GET /api/oa/approval/timeline?bizType=&bizId= → .NET → ERP。首节点"发起人已提交"(拼装 CreateTime+申请人)。若 withdrawn→末尾追加撤回节点
  • 底部悬浮操作栏(按状态动态变化)

微观组件交互

  • draft 底部:[编辑]+[提交审批];提交校验失败→TDDialog"去编辑"/"取消"
  • pending 底部:[撤回申请]→TDDialog 确认 → POST /api/oa/approval/withdraw → ApprovalStatus='withdrawn',旧 instanceId 追加到 PreviousInstanceIds → 页面刷新
  • rejected 底部:[重新编辑并发起]→跳表单编辑态,提交后更新原记录
  • approved/withdrawn 底部:隐藏
  • 申请变更/追加(approved 状态):详情页右上角 [变更申请] 按钮 → 弹出变更类型选择(追加金额/减少金额/新增明细/删除明细/延期)→ 填写变更事由 → 提交触发补充审批(存入 ExpenseApplicationChange,ApprovalInstanceId 关联 ERP 补充审批)。审批通过后 .NET 自动将 AfterSnapshot 写回主表和明细表
  • 时间线节点点击:当前用户待审批→弹出审批操作(经理版操作栏);否则→展开详情
  • 审批人姓名/头像点击 → TDDialog 展示基本信息卡片(调 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} → 节点变绿流转
  • 风控参考看板:申请人本月同类单据数 + 预算消耗进度条(本地查询+ .NET 转发 ERP)

管理员版底部操作栏

  • [强制终止](红底白字)+ [查看审批链](含历史 instanceId 流程)。管理员不展示同意/拒绝/转交

财务版增量(仅页面 9)

  • 发票合规查验区:三个 TDCheckbox(发票已验真/税号一致/类目合规)。全部勾选→解锁打款按钮
  • [退回修改]→选退回节点(员工重填/经理重审)→状态倒流
  • [确认已线下打款并归档]→解锁后滑出凭证表单(电汇流水号+记账凭证号必填)→提交→PaymentStatus='paid'→归档
  • 归档后自动替换为 [下一笔待付款]→跳转下一笔 approved+unpaid;无→"已无待付款单据"+Toast

3. 勤务考勤、用车调度与外勤外务模块(9 页)

页面 10:加班申请表单 (/overtime/apply)

页面组件内容

  • 加班类型 TDPicker(工作日/休息日/法定节假日,默认"工作日");节假日标注费率
  • 补偿方式 TDRadio(转调休/结算加班费/混合,默认"转调休")
  • 混合模式 TDSlider(10%~90%,步长 10%,右侧实时比例文案)
  • 开始/结束时间 TDDatePicker(年月日时分)
  • 净工时大字卡片(只读)
  • 加班原因 TDTextarea

微观组件交互

  • 结束时间确认→自动计算净工时(扣除 12:00-13:00/18:00-18:30 盲区),净工时≤0→变红+按钮置灰
  • 开始>结束→边框变红+提示+按钮置灰
  • 混合模式滑块:右侧实时"30% 转调休 + 70% 结算加班费"
  • 存草稿/提交审批复用页面 4 逻辑。提交调 POST /api/oa/overtime/submit

页面 11/12:加班列表/详情

交互同页面 6/7 和 8/9。加班类型标签(工作日/休息日/节假日)、补偿方式展示(加班费/转调休/"X%调休+Y%结算")。员工端仅 [撤回]


页面 13:用车申请表单 (/vehicle/apply)

页面组件内容

  • 车牌号 TDPicker(SysVehicle 车池,冲突车辆标红"冲突";无可用→TDEmpty)
  • 用车事由 TDInput
  • 始发地(原生定位匹配)+ 目的地(TDInput + 地图图标→MethodChannel 地图选点回填地址和经纬度)
  • 出车/还车时间 TDDatePicker
  • 同行总人数(纯数字,0→1)+ 随行同行人 [+](MethodChannel 通讯录多选→胶囊标签展示,x 剔除)
  • 存草稿/提交审批复用页面 4 逻辑。提交调 POST /api/oa/vehicle/submit

微观组件交互

  • 车牌+时间选定→异步排期冲突检测。冲突→红色"注意:当前时段该车存在排期冲突!"+锁死提交按钮
  • 还车时间>出车时间校验

页面 14/15:用车列表/详情

列表增量

  • TDChip 含"已还车"(returned 状态)
  • approved 卡片左滑→[确认还车],拉起核销抽屉
  • 已还车卡片左滑→无操作

详情-还车登记

  • approved 时底部展 [确认还车并登记](提前还车标灰字提示;超时标红字提示)
  • 点击→半屏核销抽屉:实还时间(TDDatePicker)、出车前里程(TDInput 纯数字)、还车后里程(校验≥出车前+红色提示)、路桥停车费备注
  • 确认提交→TDDialog"提交后里程和费用不可再修改。"→Status='returned'→页面刷新+底部灰色"已还车归档于 YYYY-MM-DD HH:mm"

页面 16:外勤日志创建 (/outing-log/create)

页面组件内容

  • GPS 定位区:页面初始化强制高精度 GPS → ReadOnly 展示逆地理编码地址(绿色盾牌安全图标)。精度>100m→黄色警告
  • 客户名称 TDInput(输入联想 GET /api/customer/search?q=;无匹配→自由文本,提交时 .NET 自动创建 ERP 客户)
  • 今日工作总结 TDTextarea
  • 后续推进计划 TDInput
  • 现场强制拍照:跳过相册,直接唤起相机;水印=服务器授时+GPS;最少 1 张最多 4 张

微观组件交互

  • GPS 失败/被拒→TDEmpty"无法获取当前位置"+提交按钮置灰
  • 相机权限被拒→TDDialog + "前往设置"
  • 照片<1→提交按钮置灰+红色提示;满 4 隐藏拍照入口
  • [存为草稿]+[提交],提交调 PUT /api/oa/outing-log/submit

页面 17/18:外勤日志列表/详情

列表

  • TDChip(全部/本月)
  • 卡片:拜访编号(VST-YYYYMMDD-XXX)、客户名(粗体)、拜访日期、签到地址(截断一行)、工作摘要(截取 50 字)、StatusTag。若有新点评→橙色 TDBadge"新点评"
  • 新点评判断:OutingLogComment.CreateTime > COALESCE(LastViewedTime,'1900-01-01') 且评论者≠本人
  • draft 卡片左滑→[编辑]+[删除];completed 左滑无反应

详情

  • 微缩静态地图(点击→MethodChannel 唤醒原生导航)
  • 带防伪水印照片墙(点击全屏预览)
  • 工作总结汇报正文
  • 点评历史流水区(OutingLogComment,按时间升序气泡样式)
  • 进入详情→无感 PUT /api/oa/outing-log/:id/view,更新 LastViewedTime,列表红点消失

经理版增量

  • 底部【主管批示及打分专区】:TDRate 5 星 + 文字输入框 + 发送按钮
  • 点选星级+输入点评→发送→气泡追加+动画。写入 OutingLogComment,同步更新 OutingLog.UpdateTime

4. 行政公告与报表模块(7 页)

页面 19:公告列表 (/announcement/list)

组件

  • TDChip 类型筛选:全部/通知公告/人事与制度/放假与活动/我的草稿(仅管理员可见)
  • 排序:置顶→未过期(PublishTime DESC)→已过期(PublishTime DESC)
  • 卡片:标题(粗体)、类型标签、发布部门(调 GET /api/user/{publisherId}→DeptName)、发布时间(MM-DD HH:mm)、未读红点(AnnouncementReadLog.IsRead=0
  • 已过期卡片整体置灰+标题末尾"已过期"
  • 不支持搜索

页面 20:公告详情 (/announcement/detail/:id)

组件

  • 红头文件样式:大标题、发布部门、红头线、正文 HTML/Markdown 渲染
  • 已过期→红色横幅"该公告已于 YYYY-MM-DD HH:mm 过期"
  • 附件下载专区(Attachment (BizType='announcement'));空则整区隐藏。点击→原生浏览器/下载管理器;失败→Toast

交互

  • 停留≥2s→无感 POST /api/oa/announcement/:id/read;<2s 返回不发。返回列表后红点消失

管理员版增量

  • 【全员触达率审计追踪卡片】:[已读 N 人](绿)+[未读 N 人](灰)。点击展开员工列表(头像+部门,数据来源 AnnouncementReadLog + GET /api/user/{id}
  • [一键 DING]→震动反馈→封装未读 UserIds→MethodChannel 强推 Push/短信→Toast"已向 N 名未读员工发送催办通知"

页面 21~25:五大明细报表

统一框架:

  • TDDropdownMenu 筛选(本月/本季/本年),不支持自定义日期
  • 数值卡片(只读,空→0/¥0.00)
  • fl_chart 趋势图(长按 tooltip、水平滑动)
  • 切换维度→300ms 渐变刷新
  • 空数据→TDEmpty"所选时间范围内暂无数据"

各报表内容:

页面 报表 数值卡片 趋势图
21 事前申请明细 累计申请总额/本月笔数/已通过笔数/已通过金额 近 12 月申请金额 vs 已通过金额双折线
22 费用报销明细 累计已核销总额/本月笔数/待审批笔数/待付款笔数 近 12 月报销金额 vs 审批通过金额双折线
23 加班明细 本月累计净工时/本月次数/累计调休小时/加班费次数 近 12 月加班工时柱状图(按类型分色堆叠)
24 用车明细 本月次数/累计里程/路桥停车费/未还车数 近 12 月用车次数 vs 费用双轴折线
25 外勤日志明细 本月拜访次数/拜访客户数(去重)/均分/未点评数 近 12 月拜访次数 vs 平均评分双轴折线

经理版增量:柱状图点击柱体→下方列表联动过滤该员工本月单据→可穿透跳详情页

财务版增量(仅页面 22):多维级联筛选(部门树+项目组)+ [数据流水一键导出]→Loading→.NET 生成 Excel→MethodChannel 唤起系统分享面板


二、审批人/经理 (Approver) 角色视图

审批人拥有与员工完全对称的 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),卡片追加申请人姓名-部门
  • pending 下属卡片左滑→[一键同意](绿),就地审批

审批详情页三元控制操作栏

页面 8/9/12/15(经理版)

  • 键值对信息区上方:风控参考看板(申请人本月同类单据数+预算消耗进度条)
  • 底部操作栏:[拒绝](白底红字,必填≥5字理由)+ [转交](灰底,MethodChannel 通讯录单选)+ [同意]#00ABF3,下流转)
  • 所有审批动作调 POST /api/oa/approval/action

页面 18(经理版):底部【主管批示及打分专区】(TDRate 5 星 + 文字输入 + 发送按钮)

页面 21~25(经理版):数据范围自动升级为部门聚合。图表渲染部门内部员工横向对比柱状图。点击柱体→联动过滤+穿透跳详情页。


三、财务人员 (Finance) 角色视图

财务人员专注于发票查验、线下付款确认及凭证归档。

权限要求oa.expense.mark_paid + oa.*.view_all + oa.report.export

页面 3(财务版):全公司级财务看盘(已支付流水/待付款总额/异常退回数)

页面 7(财务版)

  • 全公司检索权 + 独家 [待付款] Chip
  • 卡片左滑→[线下已付款]快捷标记
  • 其他列表(事前/加班/用车)为全公司只读访问,无专属操作

页面 9(财务版-核心核销专区)

  • 明细下方:发票合规查验区(三 TDCheckbox:发票已验真/税号一致/类目合规)
  • 全部勾选→解锁打款按钮;漏勾→持续锁定
  • [退回修改]→选退回节点(员工重填/经理重审)→状态倒流
  • [确认已线下打款并归档]→滑出凭证表单(电汇流水号+记账凭证号必填)→归档。按钮替换为 [下一笔待付款]→连续核销

页面 22(财务版):多维级联筛选 + [数据流水一键导出]→Excel→系统分享面板


四、系统管理员 (Admin) 角色视图

管理员拥有最高权限,独有 2 个管理专属页。

权限要求oa.admin.*

管理员专属操作栏

页面 8/9/12/15(管理员版):底部 [强制终止](红底白字)+ [查看审批链](含所有历史 instanceId 流程)。不展示经理版同意/拒绝/转交。

公告审计与发布

页面 20(管理员版):公告底部【触达率审计追踪卡片】(已读/未读人数+员工列表+TDDialog 头像详情)。[一键 DING]→强推 Push/短信。

页面 26:公告发布 (/announcement/create)

  • 标题 TDInput + 分类下拉(notice/policy/activity)
  • 富文本编辑域(加粗/斜体/下划线/列表/图片/链接/字号 H1-H3)
  • 附件上传 ≤5 个(PDF/图片/Word/Excel,≤20MB)
  • 置顶 TDSwitch + 有效期 TDDatePicker(可空=永不过期)
  • 接收范围选择器(右侧滑出部门树多选 Checkbox,默认全员;底部统计覆盖人数)
  • 右上角 [预览]→TDDialog 全屏模拟详情页
  • 底部:[存为草稿](仅创建者+管理员可见)+ [预览] + [发布]
  • [发布]→确认弹窗"确认向 N 名员工发布?发布后不可撤回。"→写入 Announcement + 异步初始化 AnnouncementReadLog → Toast

权限管理

页面 27:权限管理 (/admin/permissions)

  • TDSearchBar 防抖搜索(300ms)→ GET /api/user/search?q=
  • 员工列表(每页 20 条,默认按部门+姓名排序)
  • 点击员工卡片→右侧 TDDrawer 权限编辑抽屉:
    • 快捷套餐按钮 ×4(员工/审批人/财务/管理员)
    • 权限点复选框矩阵(~20 个权限点,按模块分组)
    • 启用/禁用 TDSwitch
  • [确认保存]PUT /api/oa/user-permissions → 写 OaPermissionChangeLog
  • 【变更记录】折叠区→TDTimeline 展示最近 20 条(OaPermissionChangeLog
  • 自保护:无法取消自己的 admin 权限 → Toast
  • 最后管理员保护:移除最后 admin→后端拒绝
  • 抽屉关闭(有未保存修改)→确认弹窗

五、全局设计规范

5.1 色彩体系

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 草稿/已撤回/已过期

5.2 字号层级

Token 字号 行高 用途
--fs-title 18sp 26px 导航栏标题/详情大标题
--fs-subtitle 16sp 24px 卡片标题/表单分组/金额大字/按钮
--fs-body 14sp 22px 正文/列表摘要/输入框/Chip
--fs-caption 12sp 18px 辅助说明/时间戳/状态标签/红点数

5.3 间距系统

Token 用途
--space-xs 4px 图标与文字间距/Chip 内边距
--space-sm 8px 列表项内 padding/表单行间距
--space-md 16px 卡片内边距/页面左右边距
--space-lg 24px 表单分组间距/卡片间距
--space-xl 32px 页面顶部/底部留白

5.4 空状态

场景 文案
消息列表为空 "暂无消息通知"
申请列表为空 "暂无记录,点击下方按钮发起申请"
审批列表为空 "暂无待审批单据"
报销明细为空 "暂无报销明细,请先添加费用明细"
照片墙为空 "暂无附件"
搜索无结果 "未找到匹配的员工,试试其他关键词"
公告列表为空 "暂无行政公告"
报表无数据 "所选时间范围内暂无数据"

5.5 加载态

场景 方式
页面首次加载 TDSkeleton 骨架屏(最长 8s 超时转网络异常态)
下拉刷新 RefreshIndicator
上拉加载更多 底部菊花 + "加载中..."
按钮提交中 按钮替换为 TDLoading 小菊花 + 禁用态
附件上传中 缩略图叠加半透明蒙层 + 中心菊花
一键导出中 圆形悬浮按钮旋转 + "导出中..."

5.6 网络异常态

场景 处理
列表加载失败 TDEmpty + 断网图标 + [点击重试]
提交失败 TDToast(红)"提交失败,请稍后重试"
接口超时(>15s) TDEmpty + 时钟图标 + [点击重试]"请求超时"
服务端 500 TDToast"服务器繁忙,请稍后重试"
401 未授权 静默触发宿主登录流程

5.7 并发冲突

场景 处理
编辑草稿时单据已被他人提交 CONCURRENCY_CONFLICT→TDDialog"已被修改或删除"→返回列表刷新
审批时单据已被他人处理 APPROVAL_CONFLICT→详情页自动刷新+Toast"状态已更新"

5.8 全局交互

  • 横竖屏:仅支持竖屏
  • 键盘:聚焦时页面上移;金额类弹数字键盘;文本类弹默认键盘
  • 返回手势:iOS 边缘右滑;Android 系统返回键;表单有未保存修改时拦截确认
  • Deep Linktboss://oa/{path} → GoRouter 路由
  • 字体缩放:sp 单位,最小 11sp,导航栏标题不溢出

5.9 导航栏标题清单

页面 路由 标题
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