# 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.*.approve` 或 `oa.*.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 Link**:`tboss://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