TBOSS OA 模块 — 全量 UI 设计
版本:v1.0 | 日期:2026-06-04 | 基于 PRD / Database / Strategy 文档
架构前提:用户/组织/客户数据来自 ERP(通过 .NET API)、审批引擎复用 ERP、消息复用 .NET 服务端、OA 权限独立 ACL。
页面中标注「经理」「财务」「管理员」的区块为对应角色专属增量功能,基础内容对所有角色可见。
0. 页面跳转关系总图
┌─────────────────────────────────────────────────────────────────────────────┐
│ Appshell — 底部三 Tab │
│ / → IndexedStack + GoRouter │
└─────────────────────────────────────────────────────────────────────────────┘
│ │ │
▼ ▼ ▼
┌─────────┐ ┌─────────┐ ┌─────────────┐
│ /messages │ │ /home │ │ /profile │
│ 消息通知 │ │ 工作台 │ │ 个人中心 │
└────┬─────┘ └────┬─────┘ └──────┬──────┘
│ │ │
│ 点击消息卡片 │ 轮播图点击 │ 语言设置 / 关于
│ 按 BizType 路由 │ → 公告详情/外部链接 │
▼ │ │
┌─────────────────┐ │ 金刚区·发起 │
│ 审批待办 → 详情页 │ │ → /expense-apply/apply │
│ 审批结果 → 详情页 │ │ → /expense/apply │
│ 撤回通知 → 消息列表│ │ → /vehicle/apply │
│ 系统公告 → 公告详情│ │ → /overtime/apply │
│ 过期提醒 → 详情页 │ │ → /announcement/create│
└─────────────────┘ │ (管理员额外) │
│ │
│ 金刚区·记录 │
│ → /expense-apply/list │
│ → /expense/list │
│ → /overtime/list │
│ → /vehicle/list │
│ → /outing-log/list │
│ → /announcement/list │
│ │
│ 金刚区·报表 │
│ → /report/expense-apply │
│ → /report/expense │
│ → /report/overtime │
│ → /report/vehicle │
│ → /report/outing-log │
│ │
│ 看板卡片 │
│ → 对应列表/报表/消息 │
└────────────────────────┘
┌──────────────────────────────────────────────────────────────────────────────┐
│ 表单 → 列表 → 详情 主链路 │
│ │
│ ┌────────────┐ 存草稿/提交 ┌────────────┐ 点击卡片 ┌──────────┐ │
│ │ 表单页 │ ───────────────→ │ 列表页 │ ────────────→ │ 详情页 │ │
│ │ (apply/ │ │ (list) │ │ (detail/ │ │
│ │ create) │ ←─────────────── │ │ ←──────────── │ :id) │ │
│ └────────────┘ 左滑编辑/删除 └────────────┘ 返回 └──────────┘ │
│ ↑ ↑ │ │ │
│ │ │ │ 经理: 左滑一键同意 │ │
│ │ │ │ 用车: 左滑确认还车 │ │
│ │ │ │ │ │
│ │ rejected 重新编辑 ───┘ draft → 编辑跳表单 │
│ │ pending → 撤回申请 │
│ └── draft 编辑回填 ──────────────────────→ approved → 还车/核销 │
│ │
│ 事前申请: /expense-apply/apply → /expense-apply/list → /expense-apply/detail │
│ 费用报销: /expense/apply → /expense/list → /expense/detail │
│ 加班申请: /overtime/apply → /overtime/list → /overtime/detail │
│ 用车申请: /vehicle/apply → /vehicle/list → /vehicle/detail │
│ 外勤日志: /outing-log/create → /outing-log/list → /outing-log/detail │
│ │
│ 特殊链路: │
│ · 报销表单可「导入事前申请」→ 半屏多选已通过的申请 → 自动带入项目/科目 │
│ · 用车 approved 后 → 详情页底部「还车登记」→ Status=returned │
│ · 报销 approved+unpaid → 财务进详情页 → 三字查验 → 打款归档 │
└──────────────────────────────────────────────────────────────────────────────┘
┌──────────────────────────────────────────────────────────────────────────────┐
│ 公告 & 权限 独立链路 │
│ │
│ 管理员: │
│ /home 金刚区 → /announcement/create → 存草稿/预览/发布 │
│ /profile → /admin/permissions → 搜索员工 → 抽屉编辑权限 → 保存+审计日志 │
│ │
│ 全员: │
│ /announcement/list ──点击──→ /announcement/detail/:id │
│ ↑ │ │
│ │ ├ 停留≥2s → 自动标记已读 │
│ │ ├ 管理员: 已读/未读统计 + DING 催办 │
│ └──── 返回列表(红点消失) ───┘ │
└──────────────────────────────────────────────────────────────────────────────┘
┌──────────────────────────────────────────────────────────────────────────────┐
│ 报表 独立链路 │
│ │
│ /home 金刚区·报表 ─┬─ /report/expense-apply-detail 事前申请明细报表 │
│ ├─ /report/expense-detail 费用报销明细报表 │
│ ├─ /report/overtime-detail 加班明细报表 │
│ ├─ /report/vehicle-detail 用车明细报表 │
│ └─ /report/outing-log-detail 外勤日志明细报表 │
│ │
│ 每页: 时间筛选 + 专属筛选 → 数值卡片 + fl_chart 趋势图 │
│ 经理: 柱状图点击 → 下方明细列表联动过滤 → 可穿透跳详情页 │
│ 财务/管理员: 底部明细列表 + Excel 导出 │
└──────────────────────────────────────────────────────────────────────────────┘
角色路由速查:
员工 → 轮播图 + 金刚区 + 个人快捷看板(本月报销+本月单据)
经理 → 员工版 + 待审批红色角标 + 快捷看板升级为部门范围 + 下属审批切换
财务 → 员工版 + 财务看盘(全公司:已支付/待付款/异常退回) + 核销入口
管理员 → 员工版 + 金刚区额外「发布公告」+ 全公司财务看盘 + 权限管理入口
1. 框架、导航及权限模块(5 页)
页面 1:Appshell 底部导航 (/)
| 区域 |
组件 |
说明 |
| 底部导航 |
TDTabBar |
三个 Tab:消息、工作台、我的 |
| 主内容区 |
IndexedStack + GoRouter |
路由驱动的视图容器,保持各 Tab 页面状态 |
| 消息角标 |
TDBadge |
未读消息数,进入时拉取 + 30s 轮询或 Push 刷新。数据来源 .NET 消息模块 API |
| 交互 |
行为 |
| 点击 Tab |
路由切换,图标变 #00ABF3 |
| 重复点击当前 Tab |
列表页 ScrollToTop,非列表无行为 |
页面 2:消息通知聚合页 (/messages)
页面结构
| 区域 |
组件 |
说明 |
| 导航栏 |
TDNavbar |
标题"消息通知",右侧"全部已读"按钮(仅未读>0 时显示) |
| 列表 |
TDListView |
下拉刷新 / 上拉加载 |
| 数据来源 |
— |
.NET 消息模块 API(非本地 Message 表) |
消息类型
| 类型 |
图标 |
示例标题 |
点击行为 |
| 审批待办 |
📋 |
"张三提交了差旅报销,待审批" |
进入详情页,底部展审批操作栏 |
| 审批结果 |
✅/❌ |
"您的差旅报销已通过" / "已被拒绝" |
进入详情页查看结果 |
| 撤回通知 |
↩ |
"张三撤回了差旅报销" |
消息列表(单据已不可审批) |
| 系统公告 |
📢 |
"【通知公告】2026年端午放假安排" |
进入公告详情页 |
| 过期提醒 |
⏰ |
"您的差旅申请已过期,预算已释放" |
进入对应详情页 |
消息卡片
| 元素 |
组件 |
说明 |
| 图标 |
Icon |
按消息类型展示不同图标 |
| 标题 |
Text |
消息大标题 |
| 摘要 |
Text |
摘要文本,单行截断 |
| 时间 |
Text |
发送时间,格式 MM-DD HH:mm |
| 未读标记 |
TDBadge |
未读消息显示红点 |
卡片交互
| 操作 |
组件 |
行为 |
| 左滑 |
TDSwipeAction |
[标记已读](蓝)+ [删除](红)。已读消息不可左滑 |
| 标记已读 |
— |
调 .NET 消息 API,成功→红点淡出+卡片透明度↓ |
| 删除 |
TDDialog |
确认弹窗→卡片收起+调 API 删除 |
推送通道
| 消息类别 |
通道 |
| 审批类 |
App Push + 站内消息 |
| 公告类 |
站内消息 |
| DING 催办 |
App Push(高优先级,无视免打扰) |
页面 3:工作台 (/home)
角色判定
| 权限 |
工作台版本 |
优先级 |
有 oa.admin.* |
管理员版 |
1 |
无 admin,有 oa.expense.mark_paid |
财务版 |
2 |
无上述,有 oa.*.approve 或 oa.*.view_dept |
经理版 |
3 |
| 其他 |
员工版 |
4 |
高优先级叠加低优先级的基础区块。权限数据来源:OaUserPermission 本地表。
所有角色共有
| 区域 |
组件 |
说明 |
| 轮播图 |
TDesign Swiper |
3s 自动切换,循环播放。点击有 LinkUrl→跳转,无→全屏预览双指缩放。数据来源 SysBanner(OA 本地) |
| 金刚区 |
TDGrid(4 列) |
三区域:发起 事前申请/费用报销/用车申请/加班申请;记录 申请记录/报销记录/加班记录/用车记录 + 外勤日志/公司公告;报表 事前申请报表/费用报销报表/加班报表/用车报表 + 外勤日志报表 |
员工版
| 区域 |
组件 |
说明 |
| 快捷看板-卡片1 |
TDCard |
本月累计报销(本人已付款总额 ¥),点击→报销记录列表 |
| 快捷看板-卡片2 |
TDCard |
本月已提单据(本人提交总数 笔),点击→申请记录列表 |
| 数据来源 |
— |
.NET 服务端预计算,缓存 5min,下拉强制刷新 |
经理/老板版
| 区域 |
组件 |
说明 |
| 待审批卡片 |
TDCard + TDBadge |
红色角标显示待办数,数据来源 .NET → ERP,点击→消息列表 |
| 快捷看板升级 |
TDCard ×3 |
数据范围升级为本部门:本月累计报销(部门) / 本月已提单据(部门) / 部门在途单据 |
财务版
| 区域 |
组件 |
说明 |
| 财务看盘 |
TDCard ×3 |
替代快捷看板,全公司数据:本月已支付总额 / 待付款总额 / 本周异常退回 |
| 数据来源 |
— |
.NET 全公司聚合查询,缓存 5min |
管理员版
| 区域 |
组件 |
说明 |
| 金刚区增量 |
TDGrid |
发起区域额外显示"发布公告"入口 |
| 快捷看板 |
TDCard ×3 |
与财务版相同,全公司数据 |
页面 3.1:个人中心 (/profile)
页面结构
| 区域 |
组件 |
说明 |
| 头像 |
TDAvatar |
点击更换,数据来源 GET /api/user/{erpUserId} |
| 用户信息 |
Text |
姓名 / 部门 / 岗位,同上 |
| 功能列表 |
TDListView |
分组样式 |
功能列表
| 功能 |
行为 |
| 语言设置 |
底部弹出 TDActionSheet:简体中文 / 繁體中文 / English。选择后立即生效,写入本地存储,下次启动保持 |
| 关于 |
版本号 / 用户协议 / 隐私政策 |
交互
| 操作 |
行为 |
| 点击头像 |
唤起相册/相机 → 裁剪(1:1,≤2MB) → PUT /api/user/avatar → 全局刷新。失败 Toast"头像上传失败" |
| 登录态 |
宿主 App 统一管理。监听宿主登出→清本地缓存。API 401→MethodChannel 通知宿主重登录 |
页面 3.2:权限管理 (/admin/permissions)【管理员专属】
| 区域 |
组件 |
说明 |
| 搜索栏 |
TDSearchBar |
按姓名/工号模糊搜索,300ms 防抖,来源 GET /api/user/search |
| 员工列表 |
TDListView |
每页 20 条,默认按部门+姓名排序。每张卡片展示:头像、姓名、工号、部门、当前权限标签(TDTag) |
抽屉内容(TDDrawer,点击员工卡片右侧滑出):
| 区域 |
组件 |
说明 |
| 快捷套餐 |
TDButton ×4 |
员工(apply+view_own+create)/ 审批人(员工权限+approve+view_dept+comment)/ 财务(view_all+mark_paid+export)/ 管理员(全部)。点击后自动勾选对应权限点 |
| 权限点列表 |
TDCheckbox 分组 |
按模块分组(报销/事前/加班/用车/外勤/公告/报表/管理),逐项勾选。无角色用户默认等同"员工" |
| 确认保存 |
TDButton |
PUT /api/oa/user-permissions → 写入 OaPermissionChangeLog(Before/After 快照 JSON)→ Toast"权限已更新"。失败→Toast 红 |
| 变更记录 |
折叠区 |
TDTimeline 展示最近 20 条 OaPermissionChangeLog:操作时间、操作人、变更摘要(如"添加了财务人员角色") |
| 自保护 |
— |
无法取消自己的 admin 角色→Toast;至少保留一名管理员→后端拒绝 |
2. 费用控制与报销模块(6 页)
页面 4:事前申请表单 (/expense-apply/apply)
基本信息区
| 字段 |
组件 |
说明 |
| 申请人 |
TDInput(只读) |
当前登录用户姓名,GET /api/user/{erpUserId} |
| 所属部门 |
TDInput(只读) |
同上 |
| 申请日期 |
TDInput(只读) |
当前日期 DateTime.now(),格式 YYYY-MM-DD |
| 紧急程度 |
TDRadioGroup |
普通 / 紧急 / 特急,默认普通 |
| 费用类型 |
TDCheckboxGroup(多选) |
至少勾选一项,如"差旅费"+"办公费",对应 DB ExpenseTypes 逗号分隔存储 |
| 预估含税 |
TDSwitch |
默认关,对应 DB IsTaxIncluded |
| 费用事由 |
TDTextarea |
必填,≤200 字,对应 DB Purpose |
| 有效期至 |
TDDatePicker |
可选,不填则永不过期,对应 DB ValidUntil |
关联管控区
| 字段 |
组件 |
说明 |
| 关联项目 |
TDCascader |
.NET → ERP ProjectService,选定后加载科目 |
| 预算科目 |
TDPicker |
.NET → ERP SubjectService,选定后加载余额 |
| 可用余额 |
只读文本 |
项目+科目选定后异步展示"¥XXXX.xx"。超预算时金额变红+警告,不阻止提交 |
| 关联合同号 |
TDInput |
选填,对应 DB ReferenceNo |
费用类型专用字段(按 ExpenseTypes 动态展示)
| 勾选类型 |
显示字段 |
| 差旅费 |
预计开始日期 / 预计结束日期 / 是否过夜(TDSwitch)/ 交通工具(TDPicker:飞机/高铁/火车/自驾) |
| 招待费 |
招待对象单位 / 招待层级(TDPicker:普通/重要/VIP)/ 外部人数 / 内部陪同人数 / 地点。校验:陪同人数 ≤ 外部人数 |
| 会议费 |
预计开始日期 / 预计结束日期 / 会议地点 |
| 其他类型 |
无专用字段,通用字段已覆盖 |
以上字段数据库全部 NULL 允许,应用层按 ExpenseTypes 动态校验必填。
预估明细区
| 字段 |
组件 |
说明 |
| 费用类别 |
TDPicker |
SysCostCategory 叶子节点,下拉受 ExpenseTypes 联动过滤 |
| 数量 |
TDInput(数字) |
>0 |
| 单位 |
TDPicker |
张 / 间 / 人 / 天 / 套 / 个,默认"张" |
| 单价 |
TDInput(数字) |
>0 |
| 单项金额 |
只读 |
自动计算 = 数量 × 单价 |
| 明细说明 |
TDInput |
选填 |
| [+ 添加] |
按钮 |
平滑展开新明细卡片 |
| ✕ 删除 |
图标按钮 |
气泡确认→折叠消失 |
| — |
— |
— |
| 预估总金额 |
只读(大字) |
所有明细行单项金额自动汇总为"¥XX,XXX.XX",对应 DB EstimatedAmount。若超预算→金额变红 + 警告"您的申请金额已超支,提交后将自动触发高管特批流程" |
附件上传区
| 属性 |
说明 |
| 组件 |
TDesign TDUpload |
| 数量 |
最多 9 张,满 9 隐藏上传入口 |
| 类型 |
图片 ≤10MB / PDF ≤20MB |
| 来源 |
相册 / 相机 / 文件选择器 |
| 展示 |
网格缩略图,右上角删除按钮 |
| 预览 |
点击缩略图→黑底全屏(双指缩放 0.5x~3x),PDF→原生查看器 |
| 存储 |
Attachment (BizType='expense_apply') |
底部操作栏
| 按钮 |
颜色 |
可见条件 |
行为 |
[重置] |
灰 |
编辑已有草稿时 |
确认弹窗→清空至初始状态 |
[存为草稿] |
浅蓝 |
始终 |
不校验,保存所有已填内容(含空字段) |
[提交审批] |
#00ABF3 |
始终 |
触发全局校验,失败不提交,超预算不阻止 |
校验规则
| 校验项 |
规则 |
| 费用类型 |
至少勾选一项 |
| 费用事由 |
必填,≤200 字 |
| 项目 / 科目 |
必选(ERP 有数据时) |
| 预估明细 |
至少一行(数量>0,单价>0) |
| 差旅类 |
开始/结束日期必填,结束≥开始 |
| 招待类 |
单位/层级/外部人数必填,陪同≤外部人数 |
| 会议类 |
开始/结束日期必填,地点必填 |
不通过时 ScrollTo 报错字段(300ms)+ 红闪 2s + TDMessage 红色横幅。
页间流转
| 操作 |
API |
成功 |
失败 |
| 存草稿 |
PUT /api/oa/expense-apply/draft |
Toast 绿"已保存为草稿" → 跳列表(激活"草稿"Tab) |
Toast 红"保存失败,请稍后重试" |
| 提交审批 |
POST /api/oa/expense-apply/submit |
.NET 创建 ERP 审批实例 → 返回 ApprovalInstanceId → Toast"已提交,等待审批" → 跳列表 |
同上 |
| 返回(有修改) |
— |
TDDialog"当前内容尚未保存,是否退出?"→ 继续编辑 / 放弃并退出 |
— |
页面 5:费用报销表单 (/expense/apply)
新建方式
| 方式 |
操作 |
说明 |
| 导入申请 |
点击顶部蓝色快捷链「导入已通过的事前申请」 |
半屏抽屉多选 approved+有额度的申请,每条填导入金额。项目/科目/成本中心自动带入,额度实时校验。空→TDEmpty |
| 直接新建 |
不导入,手动填写 |
手动选择项目→科目→查预算,链式操作与页面 4 相同 |
基本信息区
| 字段 |
组件 |
说明 |
| 报销事由 |
TDTextarea |
必填,对应 DB Purpose |
| 成本中心 |
TDPicker |
.NET → ERP CostCenterService,可选。ERP 无数据时隐藏 |
| 报销总金额 |
只读 |
明细累加上浮动画显示,对应 DB TotalAmount |
| 项目 / 科目 |
只读或手动 |
导入时自动带入;直接新建时手动选择(TDCascader,同页面 4) |
收款账户区
| 字段 |
组件 |
说明 |
| 开户行 |
TDInput+下拉联想 |
GET /api/dict/banks,可自由输入 |
| 户名 |
TDInput |
默认当前用户姓名,可修改 |
| 账号 |
TDInput |
校验 16-19 位数字 |
报销明细区
| 字段 |
组件 |
说明 |
| 发生日期 |
TDDatePicker |
年月日,对应 DB ExpenseDate |
| 费用类别 |
TDPicker |
SysCostCategory 叶子节点,对应 DB ExpenseType |
| 费用描述 |
TDInput |
摘要说明,对应 DB ExpenseDesc |
| 币种 |
TDPicker |
默认 CNY。选外币时自动从 .NET→ERP ExchangeRateService 填汇率 |
| 原币金额 |
TDInput(数字) |
不含税金额,对应 DB Amount |
| 税额 |
TDInput(数字) |
进项税额,对应 DB TaxAmount |
| 价税合计 |
只读 |
自动计算 = 金额+税额,对应 DB TotalAmount |
| 本币金额 |
只读 |
自动计算 = 价税合计×汇率,对应 DB BaseAmount |
| 发票类型 |
TDPicker |
增值税专票(special) / 普票(general) / 无发票(none) |
| 发票号码 |
TDInput |
专票/普票时必填,无发票时可空 |
| 发票代码 |
TDInput |
同上 |
| 税率 |
TDPicker |
6% / 9% / 13%,对应 DB TaxRate |
| [+ 添加] |
按钮 |
平滑展开新明细卡片 |
| ✕ 删除 |
图标按钮 |
气泡确认→折叠消失 |
无发票场景:单笔≤200 元小额零星可选 none,此时发票号和代码可空。明细金额自动汇总至主表 TotalAmount。
附件上传区
| 属性 |
说明 |
| 组件 |
TDesign TDUpload |
| 数量 |
最多 9 张 |
| 大小 |
≤10MB |
| 绑定 |
可绑定到具体明细行(Attachment.DetailId) |
| 存储 |
Attachment (BizType='expense') |
| 交互 |
同页面 4 |
底部操作栏
| 按钮 |
颜色 |
可见条件 |
行为 |
[重置] |
灰 |
编辑已有草稿时 |
确认弹窗→清空至初始状态 |
[存为草稿] |
浅蓝 |
始终 |
不校验,保存已填内容 |
[提交审批] |
#00ABF3 |
始终 |
触发全局校验,失败不提交,超预算不阻止 |
校验规则
| 校验项 |
规则 |
| 报销事由 |
必填 |
| 项目 / 科目 |
直接新建时必选(ERP 有数据时) |
| 导入金额 |
每条>0,∑≤对应申请剩余可报额度 |
| 收款银行/户名/账号 |
必填,账号 16-19 位数字 |
| 报销明细 |
至少一行(金额>0,费用类别必选) |
| 发票信息 |
发票类型必选,专票/普票时发票号必填 |
不通过时 ScrollTo 报错字段+红闪+TDMessage。
页间流转
| 操作 |
API |
成功 |
失败 |
| 存草稿 |
PUT /api/oa/expense/draft |
Toast 绿"已保存为草稿" → 跳列表(激活"草稿"Tab) |
Toast 红 |
| 提交审批 |
POST /api/oa/expense/submit |
.NET 创建 ERP 审批实例 + 冻结预算 + 写入 ExpenseApplicationMapping → Toast"已提交" → 跳列表 |
Toast 红 |
| 返回(有修改) |
— |
TDDialog"是否退出?"→ 继续编辑 / 放弃 |
— |
页面 6:事前申请列表 (/expense-apply/list)
页面结构
| 区域 |
组件 |
说明 |
| 导航栏 |
TDNavbar |
标题"申请记录" |
| 状态筛选 |
TDTabBar |
Tab:全部 / 草稿 / 审批中 / 已通过 / 已拒绝 / 已撤回。默认选中"全部" |
| 列表 |
TDListView |
下拉刷新(page=1)/ 上拉加载(page++)。数据来源 OA 本地 ExpenseApplication 表,审批状态通过 .NET→ERP 实时查询 |
| 空状态 |
TDEmpty |
文案随 Tab 变化:"暂无草稿""暂无审批中的单据"等 |
列表卡片
| 元素 |
组件 |
说明 |
| 编号 |
Text |
单据编号 BXSQ-YYYYMMDD-XXX |
| 摘要 |
Text |
事由摘要,单行截断 |
| 金额 |
Text |
预估金额,粗体高亮 |
| 日期 |
Text |
提单日期 YYYY-MM-DD |
| 类型标签 |
TDTag |
费用类型标签(如"差旅"+"办公") |
| 状态 |
StatusTag |
灰-草稿 / 橙-审批中 / 绿-已通过 / 红-已拒绝 / 灰-已撤回 |
卡片交互
| 状态/角色 |
操作 |
行为 |
| 任意 |
点击 |
→ 详情页 /expense-apply/detail/:id |
| 本人 draft |
左滑 |
[编辑](TDSwipeAction 蓝)+ [删除](红)。编辑→跳表单回填;删除→TDDialog 确认→软删除 |
| 本人 rejected |
左滑 |
[编辑](TDSwipeAction 蓝),跳表单回填 |
| 他人/其他 |
左滑无反应 |
— |
经理增量
| 区域 |
组件 |
说明 |
| 范围切换 |
TDChip ×2 |
TDTabBar 上方:我的发起 / 下属审批,选中高亮 #00ABF3 |
| 下属卡片-申请人 |
Text |
额外显示"申请人姓名 — 部门" |
| 下属 pending |
TDSwipeAction |
左滑 [一键同意](绿),就地审批 |
数据来源:GET /api/oa/approval/subordinates → OA 业务表 JOIN ERP 审批状态。
页面 7:费用报销列表 (/expense/list)
页面结构
| 区域 |
组件 |
说明 |
| 导航栏 |
TDNavbar |
标题"报销记录" |
| 状态筛选 |
TDTabBar |
Tab:全部 / 草稿 / 审批中 / 已通过 / 待付款 / 已付款 / 已拒绝 / 已撤回 |
| 列表 |
TDListView |
同页面 6。数据来源 OA 本地 Expense 表 |
| 空状态 |
TDEmpty |
同页面 6 |
列表卡片
| 元素 |
组件 |
说明 |
| 编号 |
Text |
单据编号 BX-YYYYMMDD-XXX |
| 摘要 |
Text |
事由摘要 |
| 金额 |
Text |
报销金额,粗体高亮 |
| 日期 |
Text |
提单日期 |
| 状态 |
StatusTag |
同页面 6 |
| 付款状态 |
TDTag |
黄-待付款 / 蓝-已付款 |
卡片交互同页面 6(左滑编辑/删除规则一致)。
财务增量
| 区域 |
组件 |
说明 |
| 数据范围 |
— |
默认全公司(不限制 ApplicantId) |
| 核销入口 |
— |
点击卡片→详情页完成核销。列表页不提供快捷付款 |
经理增量
与页面 6 相同:TDTabBar 上方 TDChip 范围切换 + TDSwipeAction 一键同意。
页面 8:事前申请详情 (/expense-apply/detail/:id)
| 区域 |
组件 |
说明 |
| 状态横幅 |
StatusBanner |
审批中(⏳ 橙,显示当前审批人)/ 已通过(✅ 绿)/ 已拒绝(❌ 红)/ 已撤回(↩ 灰)。审批状态通过 ERP 实时查询 |
| 基本信息 |
TDDescription |
key-value 双栏:申请人 / 部门 / 日期 / 紧急程度 / 费用类型(TDTag 多选标签)/ 含税标记 / 有效期至 / 关联合同号 |
| 使用状态 |
TDTag |
未使用(绿)/ 部分使用(黄)/ 已用完(灰),对应 DB UsageStatus |
| 关联项目 |
TDDescription |
项目名称 / 预算科目 / 预估总金额(¥) |
| 明细列表 |
TDTable |
每行:类别 / 数量×单价 / 单位 / 单项金额 / 说明。>5 行默认折叠,[展开全部] 按钮展开 |
| 附件 |
TDUpload |
支撑材料宫格,点击缩略图→全屏预览(双指缩放)。来源于 Attachment (BizType='expense_apply') |
| 审批时间线 |
TDTimeline |
纵向时间线,首节点"发起人已提交"(拼装 CreateTime+申请人),后续节点来自 .NET→ERP。若 withdrawn→末尾追加灰色撤回节点 |
| 底部 |
见下方操作表 |
员工/经理/管理员角色操作 |
页面 8 操作表
员工
| 状态 |
按钮 |
行为 |
| draft |
[编辑] [提交审批] |
编辑→跳表单回填;提交→校验→调 ERP |
| pending |
[撤回申请] |
TDDialog→POST /api/oa/approval/withdraw→Status='withdrawn' |
| rejected |
[重新编辑并发起] |
跳表单编辑态,提交后更新原记录 |
| approved |
无 |
等待报销引用 |
| withdrawn |
无 |
仅查看 |
经理(pending+当前审批人=该经理):[同意](主色)/ [拒绝](白底红字,≥5字理由)。风控看板:申请人同类单据数+预算进度条。
管理员(所有状态):[强制终止](红底白字)+ [查看审批链](含旧实例)。
通用交互:时间线节点点击→当前用户待审批可弹出审批操作。审批人头像/姓名点击→TDDialog。
页面 9:费用报销详情 (/expense/detail/:id)
| 区域 |
组件 |
说明 |
| 状态横幅 |
StatusBanner |
审批状态(同页面 8)+ 付款状态 TDTag:待付款(黄)/ 已付款(蓝) |
| 基本信息 |
TDDescription |
申请人 / 部门 / 日期 / 事由 / 成本中心 / 项目 / 科目 / 报销总金额(¥) |
| 收款信息 |
TDDescription |
开户行 / 户名 / 账号(详情页完整展示,列表页脱敏展示后 4 位 ****0123) |
| 申请来源 |
TDList |
若导入:列出关联申请编号 + 每张导入金额;若直接新建:不展示 |
| 明细列表 |
TDTable |
每行:日期 / 类别 / 描述 / 原币金额+币种 / 税额 / 价税合计 / 本币金额+汇率 / 发票类型/号/码/税率。>5 行折叠 |
| 附件 |
TDUpload |
发票影像宫格,可绑定明细行。来源于 Attachment (BizType='expense') |
| 审批时间线 |
TDTimeline |
同页面 8 |
| 财务查验区 |
TDCheckbox ×3 |
仅财务可见:验真 / 税号一致 / 类目合规。全勾→解锁打款按钮。对应 DB IsInvoiceVerified/IsTaxIdMatched/IsCategoryCompliant |
| 底部 |
见本页下方操作表 |
员工/经理/管理员/财务角色 |
页面 9 操作表
员工
| 状态 |
按钮 |
行为 |
| draft |
[编辑] [提交审批] |
编辑→跳表单回填;提交→校验→调 ERP |
| pending |
[撤回申请] |
TDDialog→POST /api/oa/approval/withdraw→Status='withdrawn' |
| rejected |
[重新编辑并发起] |
跳表单编辑态,提交后更新原记录 |
| approved |
无 |
等待财务打款 |
| withdrawn |
无 |
仅查看 |
经理(pending+当前审批人=该经理):[同意](主色)/ [拒绝](白底红字,≥5字理由)。风控看板:申请人同类单据数+预算进度条。
管理员(所有状态):[强制终止](红底白字)+ [查看审批链](含旧实例)。
通用交互:时间线节点点击→当前用户待审批可弹出审批操作。审批人头像/姓名点击→TDDialog。
财务(Status=approved + PaymentStatus=unpaid)
| 操作 |
行为 |
| 三项合规复选框 |
验真 / 税号一致 / 类目合规。未全勾→[确认打款] 灰色锁定 |
[确认打款并归档] |
全勾后激活→滑出凭证表单(电汇流水号+记账凭证号必填)→PaymentStatus='paid' |
[退回修改] |
选择退回节点(员工重填/经理重审)→状态倒流 |
| 归档后 |
按钮替换为 [下一笔待付款];无则 Toast"全部待付款单据已处理完毕" |
3. 勤务考勤、用车调度与外勤外务模块(9 页)
页面 10:加班申请表单 (/overtime/apply)
基本信息区
| 字段 |
组件 |
说明 |
| 加班类型 |
TDPicker |
工作日 / 休息日 / 法定节假日,默认"工作日"。节假日标注费率(300%) |
| 补偿方式 |
TDRadio |
转调休 / 结算加班费 / 混合模式。默认"转调休" |
| 混合比例 |
TDSlider |
10%~90%,步长 10%,仅补偿方式=混合时显示。右侧实时文字:"30% 转调休 + 70% 结算加班费" |
| 开始时间 |
TDDatePicker |
年月日时分,必填 |
| 结束时间 |
TDDatePicker |
年月日时分,必填。校验:必须晚于开始时间 |
| 净工时 |
只读大字卡片 |
自动计算 = (结束-开始) - 午餐(12:00-13:00) - 晚餐(18:00-18:30)。≤0→变红+提交按钮置灰 |
| 加班原因 |
TDTextarea |
必填 |
底部操作栏
| 按钮 |
行为 |
[存为草稿] |
不校验,保存已填内容 |
[提交审批] |
触发校验(必填项+净工时>0),通过后 POST /api/oa/overtime/submit → ERP 创建审批实例 |
校验规则
| 校验项 |
规则 |
| 开始/结束时间 |
必填,结束>开始 |
| 净工时 |
必须>0 |
| 加班原因 |
必填 |
不通过时 ScrollTo+红闪+TDMessage。
页面 11:加班申请列表 (/overtime/list)
| 区域 |
组件 |
说明 |
| 导航栏 |
TDNavbar |
标题"加班记录" |
| 状态筛选 |
TDTabBar |
全部 / 草稿 / 审批中 / 已通过 / 已拒绝 / 已撤回 |
| 列表 |
TDListView |
下拉刷新/上拉加载,数据来源 OA 本地 Overtime 表,审批状态通过 ERP 实时查询 |
列表卡片
| 元素 |
组件 |
说明 |
| 编号 |
Text |
JB-YYYYMMDD-XXX |
| 类型标签 |
TDTag |
工作日/休息日/节假日 |
| 净工时 |
Text |
粗体高亮 X.Xh |
| 补偿方式 |
Text |
加班费 / 转调休 / "X%调休+Y%结算" |
| 日期 |
Text |
提单日期 |
| 状态 |
StatusTag |
同页面 6 |
卡片交互
| 状态/角色 |
操作 |
行为 |
| 任意 |
点击 |
→ 详情页 /overtime/detail/:id |
| 本人 draft |
左滑 |
[编辑] [删除](同页面 6) |
| 本人 rejected |
左滑 |
[编辑] |
| 他人/其他 |
左滑无反应 |
— |
经理增量:TDChip 范围切换(我的发起 / 下属审批)+ TDSwipeAction [一键同意]。同页面 6。
页面 12:加班申请详情 (/overtime/detail/:id)
| 区域 |
组件 |
说明 |
| 状态横幅 |
StatusBanner |
同页面 8 |
| 基本信息 |
TDDescription |
申请人/部门/加班类型/补偿方式/混合比例/开始时间/结束时间/净工时/原因 |
| 审批时间线 |
TDTimeline |
同页面 8 |
| 底部操作栏 |
同页面 8 |
员工端各状态操作。经理端(pending 审批人=本人):同意/拒绝。管理员端:强制终止+查看审批链 |
页面 13:用车申请表单 (/vehicle/apply)
基本信息区
| 字段 |
组件 |
说明 |
| 车牌号 |
TDPicker |
OA 本地 SysVehicle 车池(仅显示空闲+使用中车辆)。冲突车辆标红,无可用→TDEmpty |
| 用车事由 |
TDInput |
必填 |
| 用车目的 |
TDPicker |
客户接待 / 商务出行 / 公务 |
| 始发地 |
TDInput |
原生定位自动填入,可修改 |
| 目的地 |
TDInput + 地图图标 |
点击地图图标→MethodChannel 唤醒原生地图选点,回填地址+经纬度 |
| 出车时间 |
TDDatePicker |
年月日时分,必填 |
| 还车时间 |
TDDatePicker |
年月日时分,必填。校验:必须晚于出车时间 |
| 同行人数 |
TDInput(数字) |
默认 1,输入 0 自动调整为 1 |
| 同行人 |
TDChip + MethodChannel |
点击[+]→原生通讯录多选→胶囊标签展示,x 剔除 |
排期冲突检测
| 触发条件 |
行为 |
| 车牌+出车/还车时间选定后 |
异步调 .NET → OA 本地 Vehicle 表校验时段重叠 |
| 冲突 |
红色警告"该时段车辆已被预订",提交按钮锁死。提示"请选择其他车辆或调整时间" |
| 无冲突 |
可正常提交 |
底部操作栏
与页面 4 相同:[存为草稿] + [提交审批],提交调 POST /api/oa/vehicle/submit。
校验规则
| 校验项 |
规则 |
| 车牌号 |
必选 |
| 事由/目的 |
必填 |
| 出车/还车时间 |
必填,还车>出车 |
| 排期冲突 |
无冲突方可提交 |
页面 14:用车申请列表 (/vehicle/list)
| 区域 |
组件 |
说明 |
| 导航栏 |
TDNavbar |
标题"用车记录" |
| 状态筛选 |
TDTabBar |
全部 / 草稿 / 审批中 / 已通过 / 已拒绝 / 已撤回 / 已还车 |
| 列表 |
TDListView |
数据来源 OA 本地 Vehicle 表 |
列表卡片
| 元素 |
组件 |
说明 |
| 编号 |
Text |
YC-YYYYMMDD-XXX |
| 车牌 |
Text |
粗体高亮 |
| 行程 |
Text |
始发地 → 目的地 |
| 时间 |
Text |
出车时间 MM-DD HH:mm |
| 用途标签 |
TDTag |
接待/商务/公务 |
| 状态 |
StatusTag |
同页面 6,额外含 returned(已还车-蓝) |
卡片交互
| 状态/角色 |
操作 |
行为 |
| 任意 |
点击 |
→ 详情页 /vehicle/detail/:id |
| 本人 draft/rejected |
左滑 |
[编辑] [删除](同页面 6) |
| 本人 approved |
左滑 |
[确认还车],拉起半屏核销抽屉 |
| 已还车 |
左滑无反应 |
— |
经理增量:TDChip 范围切换 + TDSwipeAction 一键同意(同页面 6)。
页面 15:用车申请详情 (/vehicle/detail/:id)
| 区域 |
组件 |
说明 |
| 状态横幅 |
StatusBanner |
同页面 8,额外含 returned(已还车-蓝) |
| 基本信息 |
TDDescription |
申请人/部门/车牌/目的/事由/始发地→目的地/出车时间/还车时间/同行人数/同行人列表 |
| 地图 |
静态地图 |
始发地+目的地标记,点击→MethodChannel 唤醒原生地图导航 |
| 审批时间线 |
TDTimeline |
同页面 8 |
| 底部操作栏 |
同页面 8 |
员工端各状态操作 |
还车登记(仅 approved 状态)
| 字段 |
组件 |
说明 |
| 实还时间 |
TDDatePicker |
年月日时分。若早于 EndTime→灰字提示"提前还车";若晚于→红字"已超出原计划还车时间" |
| 出车前里程 |
TDInput(数字) |
必填 |
| 还车后里程 |
TDInput(数字) |
必填,校验≥出车前里程。不通过→红色提示+提交按钮置灰 |
| 实际费用金额 |
TDInput(数字) |
路桥费/停车费等实际费用总额(元),对应 DB ActualCost |
| 费用备注 |
TDInput |
费用明细补充说明,对应 DB CostRemark |
| 确认提交 |
按钮 |
TDDialog"提交后里程和费用不可再修改"→确认→Status='returned'→页面刷新+底部灰字"已还车归档于 YYYY-MM-DD HH:mm" |
经理端(pending 审批人=本人):详情页底部同意/拒绝操作栏。管理员端:强制终止+查看审批链。
页面 16:外勤日志创建 (/outing-log/create)
页面结构
| 区域 |
组件 |
说明 |
| GPS 定位区 |
MethodChannel → 只读文本 |
页面初始化强制请求高精度 GPS,逆地理编码地址只读不可修改。绿色盾牌安全图标。精度>100m→黄色警告。失败→TDEmpty"无法获取当前位置"+提交按钮置灰 |
| 客户名称 |
TDInput + 联想 |
GET /api/customer/search?q= 联想匹配 ERP 客户池。无匹配→自由文本,提交时 .NET 自动创建 ERP 客户 |
| 客户联系人 |
TDPicker |
选填,选定客户后加载该客户的联系人列表(来源 ERP 客户主数据),对应 DB ContactId |
| 工作总结 |
TDTextarea |
必填 |
| 后续计划 |
TDInput |
选填 |
现场拍照
| 属性 |
说明 |
| 方式 |
跳过相册,MethodChannel 直接唤起原生相机 |
| 水印 |
服务器授时 + GPS 经纬度,自动渲染 |
| 数量 |
最少 1 张,最多 9 张 |
| 存储 |
Attachment (BizType='outing_log'),FileType='sign_in_photo' |
| 校验 |
<1 张→提交按钮置灰+红提示"请至少拍摄一张现场照片"。相机权限被拒→TDDialog+前往设置 |
底部操作栏
| 按钮 |
行为 |
[存为草稿] |
GPS/CustomerId 可为空,保存已填内容 |
[提交] |
校验 GPS 已定位 + 客户名已填 + 照片≥1。提交调 PUT /api/oa/outing-log/submit |
页面 17:外勤日志列表 (/outing-log/list)
| 区域 |
组件 |
说明 |
| 导航栏 |
TDNavbar |
标题"外勤记录" |
| 筛选 |
TDTabBar |
全部 / 草稿 / 已完成 |
| 列表 |
TDListView |
按 CreateTime 倒序,数据来源 OA 本地 OutingLog 表 |
列表卡片
| 元素 |
组件 |
说明 |
| 编号 |
Text |
VST-YYYYMMDD-XXX |
| 客户名 |
Text |
粗体高亮 |
| 地址 |
Text |
签到地址截断一行 |
| 摘要 |
Text |
工作总结截取 50 字 |
| 日期 |
Text |
YYYY-MM-DD |
| 状态 |
StatusTag |
草稿(灰)/ 已完成(绿) |
| 新点评标记 |
TDBadge |
橙色,条件:Comment.CreateTime > COALESCE(LastViewedTime,'1900-01-01') 且评论者≠本人 |
卡片交互
| 状态/角色 |
操作 |
行为 |
| 任意 |
点击 |
→ 详情页 /outing-log/detail/:id |
| 本人 draft |
左滑 |
[编辑] [删除] |
| completed |
左滑无反应 |
— |
经理增量:TDChip 范围切换(同页面 6),卡片追加业务员姓名。
页面 18:外勤日志详情 (/outing-log/detail/:id)
| 区域 |
组件 |
说明 |
| 微缩地图 |
静态地图 |
点击→MethodChannel 唤醒原生导航 |
| 基本信息 |
TDDescription |
业务员/部门/客户名/签到地址/签到时间 |
| 工作总结 |
Text |
完整正文 |
| 后续计划 |
Text |
后续推进计划 |
| 照片墙 |
TDUpload |
带防伪水印照片,点击全屏预览 |
| 点评区 |
TDList |
按时间升序气泡样式展示。员工端只读 |
| 底部(经理) |
TDRate + TDInput |
星级评分 1-5 星 + 文字点评 + 发送按钮 |
页面交互
| 操作 |
行为 |
| 进入详情 |
无感 PUT /api/oa/outing-log/:id/view,更新 LastViewedTime,列表"新点评"红点消失 |
| 经理点评 |
【经理专属】点选星级+输入文字→发送→气泡追加。写入 OutingLogComment,同步更新 OutingLog.UpdateTime |
4. 行政公告模块(3 页)
页面 19:公告列表 (/announcement/list)
页面结构
| 区域 |
组件 |
说明 |
| 导航栏 |
TDNavbar |
标题"公司公告" |
| 类型筛选 |
TDTabBar |
全部 / 通知公告 / 人事与制度 / 放假与活动。管理员额外显示"我的草稿"Tab |
| 列表 |
TDListView |
排序:置顶优先→未过期按发布时间倒序→已过期置灰。数据来源 OA 本地 Announcement 表 |
| 空状态 |
TDEmpty |
"暂无行政公告" |
列表卡片
| 元素 |
组件 |
说明 |
| 标题 |
Text |
粗体 |
| 类型标签 |
TDTag |
通知/制度/活动 |
| 部门 |
Text |
发布部门(调 GET /api/user/{publisherId}) |
| 时间 |
Text |
MM-DD HH:mm |
| 未读标记 |
TDBadge |
红点,AnnouncementReadLog.IsRead=0 时显示 |
| 已过期 |
Text |
卡片整体置灰 + 标题末尾标注"已过期" |
不支持搜索。点击卡片→详情页。返回列表后红点消失。
页面 20:公告详情 (/announcement/detail/:id)
页面结构
| 区域 |
组件 |
说明 |
| 标题 |
Text |
大标题,红头文件样式 |
| 发布信息 |
Text |
发布部门 / 发布时间 |
| 正文 |
WebView |
HTML/Markdown 渲染 |
| 附件 |
TDList |
点击→原生下载管理器打开。空→整区隐藏。来源 Attachment (BizType='announcement') |
| 已过期横幅 |
TDBanner |
红色"该公告已于 YYYY-MM-DD HH:mm 过期" |
页面交互
| 操作 |
行为 |
| 停留≥2s |
无感 POST /api/oa/announcement/:id/read,AnnouncementReadLog.IsRead=1 |
| <2s 返回 |
不发送已读请求,红点保留 |
| 返回列表 |
已读公告红点消失 |
管理员增量
| 区域 |
组件 |
说明 |
| 已读/未读统计 |
TDChip ×2 |
[已读 N 人](绿)/ [未读 N 人](灰)。点击展开员工列表(头像+部门) |
| DING 催办 |
TDButton |
点击→震动反馈→封装未读 UserIds→MethodChannel 强推 Push。Toast"已向 N 名未读员工发送催办通知"。更新 IsUrged=1 |
页面 21:公告发布 (/announcement/create)【管理员专属】
| 区域 |
组件 |
说明 |
| 导航栏 |
TDNavbar |
标题"发布公告",右侧 [预览] 按钮 |
| 标题 |
TDInput |
必填 |
| 分类 |
TDPicker |
notice(通知)/policy(制度)/activity(活动) |
| 正文 |
TDRichText |
加粗/斜体/下划线/列表/图片/链接/字号 H1-H3 |
| 附件 |
TDUpload |
最多 5 个,PDF/图片/Word/Excel,单文件≤20MB |
| 置顶 |
TDSwitch |
默认关闭,对应 DB IsTop |
| 有效期 |
TDDatePicker |
可选,不填永不过期,对应 DB ExpiryDate |
| 接收范围 |
TDDrawer |
点击→右侧滑出:①全员(默认)②按部门(部门树多选,TDCheckbox)③按指定用户(员工搜索多选)。底部实时统计覆盖人数。对应 DB PrivateLevel + AnnouncementTarget |
| 按钮 |
行为 |
[存为草稿] |
Status='draft',仅创建者+管理员可见 |
[预览] |
TDDialog 全屏模拟详情页效果 |
[发布] |
TDDialog 确认→Status='published'→异步写入 AnnouncementReadLog→Toast |
5. 报表模块(5 页)
入口:工作台金刚区报表区域(5 个独立入口)。每个报表独立页面,独立路由,独立加载数据。筛选条件在页面顶部,下方为数值卡片 + 趋势图(fl_chart)。角色数据范围:员工=本人、经理=本部门、财务/管理员=全公司。预置时间段缓存 5min,自定义时间段实时查询。
页面 22:事前申请明细报表 (/report/expense-apply-detail)
页面结构
| 区域 |
组件 |
说明 |
| 时间筛选 |
TDChip + TDDatePicker |
快捷按钮(本月/本季/本年)+ 自定义起止日期 |
| 状态筛选 |
TDPicker |
全部 / 已通过 / 已拒绝 / 已撤回 |
| 数值卡片 |
TDCard ×4 |
累计申请总额(年初至今)/ 当月笔数 / 已通过笔数 / 已通过金额。仅展示不可点击,空→¥0.00 |
| 趋势图 |
fl_chart 双折线 |
近 12 月申请金额 vs 已通过金额对比。长按→tooltip(日期+数值),水平滑动 |
| 数据来源 |
— |
OA 本地 ExpenseApplication 表,.NET 按角色+时间聚合 |
角色差异
| 角色 |
图表类型 |
明细列表 |
导出 |
| 员工 |
个人双折线 |
❌ |
❌ |
| 经理 |
部门横向对比柱状图(每人两根柱:申请/已通过) |
✅ |
❌ |
| 财务/管理员 |
全公司趋势图 |
✅ |
✅ Excel |
页面 23:费用报销明细报表 (/report/expense-detail)
页面结构
| 区域 |
组件 |
说明 |
| 时间筛选 |
TDChip + TDDatePicker |
同页面 22 |
| 状态筛选 |
TDPicker ×2 |
审批状态(全部/已通过/已拒绝)+ 付款状态(全部/待付款/已付款) |
| 数值卡片 |
TDCard ×4 |
累计核销总额(年初至今)/ 当月笔数 / 待审批笔数 / 待付款笔数 |
| 趋势图 |
fl_chart 双折线 |
近 12 月报销金额 vs 审批通过金额对比 |
| 数据来源 |
— |
OA 本地 Expense 表,审批状态通过 ERP 实时查询 |
角色差异
| 角色 |
图表类型 |
明细列表 |
导出 |
| 员工 |
个人双折线 |
❌ |
❌ |
| 经理 |
部门横向对比柱状图 |
✅ |
❌ |
| 财务/管理员 |
全公司趋势图 |
✅ |
✅ Excel |
页面 24:加班明细报表 (/report/overtime-detail)
页面结构
| 区域 |
组件 |
说明 |
| 时间筛选 |
TDChip + TDDatePicker |
同页面 22 |
| 加班类型 |
TDPicker |
全部 / 工作日 / 休息日 / 节假日 |
| 数值卡片 |
TDCard ×4 |
当月净工时(h)/ 当月次数 / 累计调休小时 / 加班费结算次数 |
| 趋势图 |
fl_chart 堆叠柱状图 |
近 12 月加班工时,按类型(工作日/休息日/节假日)分色堆叠 |
| 数据来源 |
— |
OA 本地 Overtime 表 |
角色差异
| 角色 |
图表类型 |
明细列表 |
导出 |
| 员工 |
个人堆叠柱状图 |
❌ |
❌ |
| 经理 |
部门横向对比柱状图(每人汇总工时) |
✅ |
❌ |
| 财务/管理员 |
全公司趋势图 |
✅ |
✅ Excel |
页面 25:用车明细报表 (/report/vehicle-detail)
页面结构
| 区域 |
组件 |
说明 |
| 时间筛选 |
TDChip + TDDatePicker |
同页面 22 |
| 车辆筛选 |
TDPicker |
全部 / 按车牌筛选 |
| 用途筛选 |
TDPicker |
全部 / 接待 / 商务 / 公务 |
| 数值卡片 |
TDCard ×4 |
当月次数 / 累计里程(km)/ 路桥停车费 / 未还车数量 |
| 趋势图 |
fl_chart 双轴折线 |
近 12 月用车次数(左轴)vs 累计费用(右轴) |
| 数据来源 |
— |
OA 本地 Vehicle 表 |
角色差异
| 角色 |
图表类型 |
明细列表 |
导出 |
| 员工 |
个人双轴折线 |
❌ |
❌ |
| 经理 |
部门横向对比柱状图(每人次数/费用) |
✅ |
❌ |
| 财务/管理员 |
全公司双轴折线 |
✅ |
✅ Excel |
页面 26:外勤日志明细报表 (/report/outing-log-detail)
页面结构
| 区域 |
组件 |
说明 |
| 时间筛选 |
TDChip + TDDatePicker |
同页面 22 |
| 客户筛选 |
TDSearchBar |
输入客户名模糊搜索 |
| 数值卡片 |
TDCard ×4 |
当月拜访次数 / 拜访客户数(去重)/ 平均评分(⭐)/ 未点评日志数 |
| 趋势图 |
fl_chart 双轴折线 |
近 12 月拜访次数(左轴)vs 平均评分(右轴) |
| 数据来源 |
— |
OA 本地 OutingLog 表 LEFT JOIN OutingLogComment |
角色差异
| 角色 |
图表类型 |
明细列表 |
导出 |
| 员工 |
个人双轴折线 |
❌ |
❌ |
| 经理 |
部门横向对比柱状图(每人次数/评分) |
✅ |
❌ |
| 财务/管理员 |
全公司双轴折线 |
✅ |
✅ Excel |
经理版交互增强:点击柱状图柱体→下方列表联动过滤该员工本月单据→可穿透跳转对应详情页。适用于页面 22~26 所有报表。
6. 全局设计规范
6.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 |
草稿/已撤回/已过期 |
--bg-disabled |
#EEEEEE |
禁用按钮/输入框背景 |
--text-disabled |
#BFBFBF |
禁用态文字(复用 --text-placeholder) |
6.2 字号层级
| Token |
字号 |
行高 |
用途 |
--fs-title |
18sp |
26px |
导航栏标题/详情大标题 |
--fs-subtitle |
16sp |
24px |
卡片标题/表单分组/金额大字/按钮 |
--fs-body |
14sp |
22px |
正文/列表摘要/输入框/Chip |
--fs-caption |
12sp |
18px |
辅助说明/时间戳/状态标签/红点数 |
6.3 间距系统
| Token |
值 |
用途 |
--space-xs |
4px |
图标与文字间距/Chip 内边距 |
--space-sm |
8px |
列表项内 padding/表单行间距 |
--space-md |
16px |
卡片内边距/页面左右边距 |
--space-lg |
24px |
表单分组间距/卡片间距 |
--space-xl |
32px |
页面顶部/底部留白 |
6.4 空状态
| 场景 |
文案 |
| 消息列表为空 |
"暂无消息通知" |
| 申请列表为空 |
"暂无记录,点击下方按钮发起申请" |
| 审批列表为空 |
"暂无待审批单据" |
| 报销明细为空 |
"暂无报销明细,请先添加费用明细" |
| 照片墙为空 |
"暂无附件" |
| 搜索无结果 |
"未找到匹配的员工,试试其他关键词" |
| 公告列表为空 |
"暂无行政公告" |
| 报表无数据 |
"所选时间范围内暂无数据" |
| 导入事前申请为空 |
"暂无可用的事前申请,请确认已有审批通过的申请" |
| 下属审批为空 |
"暂无下属提交的审批单据" |
| 附件上传已满 |
"上传数量已达上限" |
| 车辆池为空 |
"暂无可用车辆,请联系管理员添加" |
6.5 加载态
| 场景 |
方式 |
| 页面首次加载 |
TDSkeleton 骨架屏(最长 8s 超时转网络异常态) |
| 下拉刷新 |
RefreshIndicator |
| 上拉加载更多 |
底部菊花 + "加载中..." |
| 按钮提交中 |
按钮替换为 TDLoading 小菊花 + 禁用态 |
| 附件上传中 |
缩略图叠加半透明蒙层 + 中心菊花 |
| 一键导出中 |
圆形悬浮按钮旋转 + "导出中..." |
6.6 网络异常态
| 场景 |
处理 |
| 列表加载失败 |
TDEmpty + 断网图标 + [点击重试] |
| 提交失败 |
TDToast(红)"提交失败,请稍后重试" |
| 接口超时(>15s) |
TDEmpty + 时钟图标 + [点击重试]"请求超时" |
| 服务端 500 |
TDToast"服务器繁忙,请稍后重试" |
| 401 未授权 |
静默触发宿主登录流程 |
6.7 并发冲突
| 场景 |
处理 |
| 编辑草稿时单据已被他人提交 |
CONCURRENCY_CONFLICT→TDDialog"已被修改或删除"→返回列表刷新 |
| 审批时单据已被他人处理 |
APPROVAL_CONFLICT→详情页自动刷新+Toast"状态已更新" |
6.8 全局交互
- 横竖屏:仅支持竖屏
- 键盘:聚焦时页面上移;金额类弹数字键盘;文本类弹默认键盘
- 返回手势:iOS 边缘右滑;Android 系统返回键;表单有未保存修改时拦截确认
- Deep Link:
tboss://oa/{path} → GoRouter 路由
- 字体缩放:sp 单位,最小 11sp,导航栏标题不溢出
- 下拉刷新:列表页顶部下拉触发
RefreshIndicator,重置 page=1 重新加载,刷新完成后短暂展示"已更新"提示
6.9 圆角规范
| Token |
值 |
用途 |
--radius-sm |
4px |
Chip / Tag / 小按钮 / 输入框 |
--radius-md |
8px |
卡片 / 大按钮 / 列表项 |
--radius-lg |
12px |
对话框 / 抽屉 / 底部弹出面板 |
--radius-round |
999px |
胶囊按钮 / 头像 / 状态圆点 |
6.10 阴影层级
| Token |
值 |
用途 |
--shadow-none |
none |
平面/无阴影 |
--shadow-card |
0 2px 8px rgba(0,0,0,0.08) |
卡片/列表项 |
--shadow-fab |
0 4px 16px rgba(0,0,0,0.12) |
悬浮按钮/底部操作栏/导航栏 |
--shadow-drawer |
-4px 0 20px rgba(0,0,0,0.15) |
右侧抽屉/半屏面板 |
6.11 动画时间规范
| Token |
值 |
用途 |
--duration-fast |
150ms |
按压反馈/hover 响应/Tag 关闭 |
--duration-normal |
300ms |
页面过渡/图表数据刷新/ScrollTo 滚动/红闪消失 |
--duration-slow |
500ms |
抽屉滑出/卡片展开收起/淡入淡出 |
--easing-standard |
cubic-bezier(0.4, 0, 0.2, 1) |
标准缓动曲线,用于所有过渡动画 |
应用示例:图表刷新间隔统一用 --duration-normal(300ms);表单校验失败红闪 2s 后淡出用 --duration-slow;按钮按下态用 --duration-fast;骨架屏超时阈值 8s(见 §6.5)。
6.12 导航栏标题清单
| 页面 |
路由 |
标题 |
| 1 |
/ |
—(Appshell) |
| 2 |
/messages |
"消息通知" |
| 3 |
/home |
"工作台" |
| 3.1 |
/profile |
"我的" |
| 3.2 |
/admin/permissions |
"权限管理" |
| 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 |
/announcement/create |
"发布公告" |
| 22 |
/report/expense-apply-detail |
"事前申请明细报表" |
| 23 |
/report/expense-detail |
"费用报销明细报表" |
| 24 |
/report/overtime-detail |
"加班明细报表" |
| 25 |
/report/vehicle-detail |
"用车明细报表" |
| 26 |
/report/outing-log-detail |
"外勤日志明细报表" |
文档版本:v1.0 | 日期:2026-06-04