tboss-oa-prd.md 45 KB

TBOSS OA 模块 — 产品需求文档

版本:v1.1 | 日期:2026-06-27 | 状态:待评审


1. 产品背景

1.1 业务背景

公司已有成熟的 ERP 系统(多套部署实例),支撑企业日常运营。ERP 覆盖了用户管理、组织架构、客户主数据、审批引擎、消息通知等核心能力。现有 Android/iOS App 已嵌入 ERP 相关功能。

当前痛点

  • OA 流程依赖 PC 或线下:费用报销、费用申请、加班、用车等审批流程缺乏统一的移动端入口
  • 外勤管理无数字化手段:业务员外出拜访缺少定位打卡和现场拍照核验机制
  • 公告触达不可追踪:行政通知发布后无法确认哪些员工已读、哪些未读
  • 数据孤岛:各业务单据分散在不同系统,缺少统一的个人/部门报表视图

1.2 产品目标

在已有 ERP App 内嵌入 OA 功能模块(Flutter 技术栈),为员工、审批人、财务人员、管理员提供移动端 OA 办公能力。

核心原则:不重复造轮子。ERP 已有的用户体系、审批引擎、消息推送、预算系统、项目主数据通过适配器复用。V1 聚焦于 8 个核心模块的"填单→审批→查看"闭环。

1.3 市场定位

通用平台(钉钉/企微) 专业 OA(蓝凌/泛微) TBOSS OA
定位 独立 SaaS 平台 独立 OA 产品 ERP 移动端外挂
优势 生态丰富 管控深度 无缝嵌入已有系统
劣势 不可定制 移动端体验弱 依赖 ERP 能力边界

TBOSS OA 的核心差异化:不是独立产品,而是 ERP 的移动 OA 外挂——用户无需切换 App、无需维护两套账号、直接调用原生能力(相机/通讯录/地图/GPS)。

1.4 成功指标

指标 目标值 衡量方式
报销全流程耗时 从填单到付款到账 ≤3 个工作日 系统记录 CreateTime → PaymentStatus=paid 时间差
移动端 OA 覆盖率 80% 以上 OA 单据通过移动端发起 移动端提交量 / 总提交量
公告触达率 发布后 24h 内 ≥85% 员工已读 AnnouncementReadLog.IsRead=1 / 应达总人数(发布时固定快照)
财务核销效率 单笔核销操作 ≤2 分钟 详情页打开 → 归档完成时间差
系统可用性 99.5%(月度) 监控平台

1.5 明确不做的事(V1 边界)

以下功能有意识排除,避免范围蔓延:

不做 理由
审批链可视化配置 审批链在 ERP 端维护,OA 只消费
自定义表单模板 V1 固定表单字段
在线支付 / 银企直连 财务线下打款后录入流水号
OA 端创建用户 / 部门 用户和组织架构由 ERP 管理
独立的消息推送通道 复用 .NET 服务端已有推送
电子签章
PC Web 端 V1 仅移动端(Flutter)
预付/借款冲抵 V1 暂不支持(OffsetAmount 字段保留为 0)
跨部门费用承担 V1 费用承担部门自动等于申请人所属部门

2. 用户画像

2.1 普通员工(Employee)

属性 描述
身份 公司基层员工,归属某个部门
日常场景 出差前提交费用申请(可含多费用类型,关联项目+预算)→ 审批通过 → 回来提交费用报销(支持外币折算)→ 加班/用车/外勤日志
核心诉求 快速填单、拍发票、随时查看审批进度、草稿暂存
使用频率 每周 2-5 次
移动端偏好 表单简洁、支持拍照上传、操作反馈及时(撤回/编辑/查看状态)

2.2 审批人 / 部门经理(Approver)

属性 描述
身份 部门主管/有审批职责的人员,通常直接管理 5-20 名下属
日常场景 收到审批待办通知 → 查看单据详情 + 风控参考 → 同意/拒绝;查看部门报表;在外勤日志下点评打分
核心诉求 快速了解单据全貌(申请人历史、预算消耗)、批量处理待办、移动端审批操作流畅
使用频率 每天 3-10 次
移动端偏好 待办红点醒目、卡片信息密度高、支持左滑快捷操作、拒绝时要求填写原因

2.3 财务人员(Finance)

属性 描述
身份 财务核销专员,负责发票合规查验和线下打款确认
日常场景 查看全公司已通过待付款的报销单 → 核验发票影像 → 手动勾选三项合规检查 → 线下打款 → 录入电汇流水号和记账凭证号归档
核心诉求 发票影像清晰可查验、合规检查项手动确认、连续核销不退回列表、数据可导出
使用频率 每天 5-20 笔核销
移动端偏好 发票大图预览、合规复选框联动锁定、一键全部通过、凭证归档表单、导出 Excel

2.4 系统管理员(Admin)

属性 描述
身份 IT 管理员 / HR 管理员
日常场景 为员工分配 OA 权限角色;发布/管理公司公告;DING 催办未读员工;查看公告触达率
核心诉求 权限配置灵活(套餐 + 单点调整)、公告富文本编辑、触达审计可视化
使用频率 每周 2-5 次
移动端偏好 搜索员工快捷、权限勾选直观、公告发布有预览

3. 核心功能列表

3.1 功能模块总览

模块              子功能                       角色
─────────────────────────────────────────────────────
📋 费用申请    │  表单/列表/详情              │ 全员
💰 费用报销    │  表单/列表/详情/财务核销     │ 全员 + 财务
⏰ 加班申请    │  表单/列表/详情              │ 全员
🚗 用车申请    │  表单/列表/详情/还车登记     │ 全员
📍 外勤日志    │  创建/列表/详情/点评         │ 业务员 + 经理
📢 公告管理    │  列表/详情/发布/触达审计     │ 全员 + 管理员
📊 数据报表    │  5 大明细报表               │ 全员(按角色范围)
🔧 权限管理    │  用户权限配置                │ 管理员
🏠 工作台      │  首页/金刚区/报表/消息/个人中心 │ 全员

3.2 工作台(Home)

工作台是登录后的默认首页,内容按角色权限动态变化。权限判定依据 OaUserPermission,优先级 Admin > Finance > Approver > Employee,高优先级角色叠加低优先级角色的基础区块。

所有角色共有

区块 说明
轮播图 顶部 Banner 轮播(3s 自动切换),数据来源 OA 本地 SysBanner 表。管理员可在后台维护。点击有链接则跳转,无链接则全屏预览
功能金刚区 4 列宫格,分三个区域。【发起】第一行:费用申请/费用报销/用车申请/加班申请。有 oa.announcement.publish 权限的用户额外显示:发布公告。【记录】第二行:申请记录/报销记录/加班记录/用车记录,第三行:外勤日志/公司公告。【报表】第四行:费用申请报表/费用报销报表/加班报表/用车报表,第五行:外勤日志报表。每个报表点击直接进入对应报表页

员工版

在共有基础上增加快捷看板,两张数据卡片仅展示本人数据:

卡片 内容 点击跳转 数据来源
本月累计报销 本月本人已付款报销总额(¥) 报销记录列表 .NET 预计算:SUM(Expense.BaseAmount WHERE ApplicantId=本人 AND PaymentStatus=paid)
本月已提单据 本月本人提交的全部单据数(笔) 申请记录列表 .NET 预计算:COUNT(所有业务表 WHERE ApplicantId=本人 AND 本月)

数据缓存 5 分钟,下拉强制刷新。

经理/老板版

在员工版基础上叠加两个区块:

待审批卡片:金刚区下方醒目的红色角标卡片,展示本人待审批单据数量和最新摘要。数据来源 .NET → ERP 审批引擎。点击跳转消息列表(筛选审批待办)。

快捷看板升级:三张卡片的数据范围从"本人"升级为本部门汇总:

卡片 内容 点击跳转 数据来源
本月累计报销 本部门已付款报销总额(¥) 报销记录列表(部门视图) .NET 预计算:SUM(Expense.BaseAmount WHERE DeptId=本部门 AND PaymentStatus=paid)
本月已提单据 本部门全部单据数(笔) 申请记录列表(部门视图) .NET 预计算:COUNT(所有业务表 WHERE DeptId=本部门 AND 本月)
部门在途单据 本部门审批中的单据数(笔) 申请记录列表(部门视图,筛选审批中) .NET → ERP 审批引擎:COUNT(pending WHERE DeptId=本部门)

如果用户同时拥有经理和员工权限,显示经理版(高优先级叠加)。

财务版

在员工版基础上,将快捷看板替换为财务看盘,三张大数字卡片展示全公司数据:

卡片 内容 数据来源
本月已支付总额 全公司本月 PaymentStatus=paid 的报销总额(¥) .NET 预计算:SUM(Expense.BaseAmount WHERE PaymentStatus=paid AND 本月)
待付款总额 全公司当前已通过但未付款的报销总额(¥) .NET 预计算:SUM(Expense.BaseAmount WHERE Status=approved AND PaymentStatus=unpaid)
本周异常退回 本周财务退回修改的报销单数量(笔) .NET 预计算:COUNT(Expense WHERE 本周被退回)

数据缓存 5 分钟,下拉强制刷新。财务看盘替代快捷看板,财务不展示个人快捷看板。

管理员版

在员工版基础上叠加:金刚区发起区域有 oa.announcement.publish 权限的用户额外显示"发布公告"入口。快捷看板展示全公司数据(与财务版相同,三张大数字卡片:本月已支付总额 / 待付款总额 / 本周异常退回)。数据来源 .NET 全公司聚合查询,缓存 5 分钟。


3.3 费用申请(Expense Application)

功能 优先级 说明
新建申请 P0 多费用类型(可同时勾选差旅+办公等)。关联项目(.NET → ERP ProjectService)→ 加载科目(.NET → ERP SubjectService)→ 查预算余额。预估明细行金额,附件上传
预算查看 P0 选完项目+科目后实时展示可用余额(BudgetService)。余额不足时金额标红并触发超支审批链。ERP 无预算数据时跳过校验,不影响提交。预算服务不可用时隐藏预算信息,允许正常提交
草稿暂存 P0 草稿可多次编辑后提交。草稿仅创建者本人可见(管理员也不例外),所有查询入口排除草稿
提交审批 P0 校验必填项+预算 → 提交至 ERP 审批引擎。超预算时允许提交但携带 budget_exceeded 标签,由 ERP 决定是否进入特批链路
列表筛选 P0 全部/草稿/审批中/已通过/已拒绝/已撤回/已归档
详情查看 P0 状态横幅 + 费用明细 + 附件 + 审批时间线
撤回申请 P1 pending 状态可撤回(任何审批阶段均可撤,ERP 最终裁决)
删除草稿 P1 draft 状态可删除(仅本人),删除后不可恢复
终态归档 P0 当 UsageStatus=fully_used 时,Status 自动流转为 archived,不可再被引用

3.4 费用报销(Expense Reimbursement)

功能 优先级 说明
新建报销 P0 两种方式:①导入费用申请(项目/科目自动带入,填每张导入金额);②直接新建(手动选项目→科目→查预算,与费用申请相同的链式操作)。均支持外币明细(自动汇率折算)、附件上传(图片/PDF/Word/Excel,表头附件+明细行附件)。支付方式(PaymentMethod)由员工在填单时选择
导入费用申请 P0 从已通过且尚有额度的申请多选导入,每条填导入金额。导入后自动回填项目/科目,额度实时校验,超申请金额不可提交。严格按 BizScope 过滤,不可导入 expense_apply 专属类别
列表筛选 P0 全部/草稿/审批中/已通过/待付款/已付款/已拒绝/已撤回/已归档
详情查看 P0 状态横幅 + 费用明细 + 审批时间线 + 附件预览
撤回申请 P1 pending 状态可撤回(任何审批阶段均可撤,ERP 最终裁决),撤回后立即释放已占用的申请额度
删除草稿 P1 draft 状态可删除(仅本人)
草稿/提交 P0 支持存为草稿后继续编辑,提交时校验必填项+预算,提交至 ERP 审批引擎。从费用申请导入的报销单提交时不重复校验预算
财务核销 P0 发票合规三字查验(验真/税号/类目)→ 三项均由财务人员手动勾选,提供"一键全部通过"快捷操作 → 录入电汇流水号+记账凭证号 → 归档。单笔 ≤200 元小额零星支出时系统自动勾选三项,财务仍可取消
连续核销 P1 归档后跳转下一笔待付款(FIFO:CreateTime 最早优先)
退回修改 P1 退给员工重填 或 退给经理重审

3.5 加班申请(Overtime)

功能 优先级 说明
新建申请 P0 加班类型(工作日/休息日/节假日)、补偿方式(转调休/加班费/混合)、开始/结束时间、原因
净工时自动计算 P0 扣除午休(12:00-13:00)和晚餐(18:00-18:30)盲区
混合模式 P1 调休比例滑块(10%-90%,步长10%),实时显示分配文案
列表筛选 P0 全部/草稿/审批中/已通过/已拒绝/已撤回/已归档
详情查看 P0 状态横幅 + 加班信息 + 审批时间线
撤回申请 P1 pending 状态可撤回(任何审批阶段均可撤,ERP 最终裁决)
删除草稿 P1 draft 状态可删除(仅本人)

3.6 用车申请(Vehicle)

功能 优先级 说明
新建申请 P0 车牌号选择(草稿时可空,提交时必填)、始发地/目的地(支持地图选点)、出车/还车时间、同行人(通讯录多选或手动输入外部人员)
排期冲突检测 P0 选好车牌+时间后实时防抖校验,冲突时警告并置灰提交按钮。草稿状态下也支持实时检测(但不锁车)
列表筛选 P0 全部/草稿/审批中/已通过/已拒绝/已撤回/已还车/已归档
详情查看 P0 状态横幅 + 行程信息 + 审批时间线 + 地图标记
撤回申请 P1 pending 状态可撤回(任何审批阶段均可撤,ERP 最终裁决)
删除草稿 P1 draft 状态可删除(仅本人)
还车登记 P0 approved 状态可登记还车:实还时间、出车前/还车后里程表读数、路桥停车费。还车登记完成后 Status 自动流转为 returned,再自动流转为 archived,车辆状态恢复 idle
车辆池管理 P1 管理员维护车辆信息(车牌/类型/品牌/座位/驾驶员/状态)。maintenance 状态车辆不可被申请

3.7 外勤日志(Outing Log)

功能 优先级 说明
新建日志 P0 GPS 自动定位(只读,不可手动修改)、客户名(自动联想 ERP 客户池)、工作总结、后续计划。草稿状态下不强制 GPS,提交时校验
现场拍照 P0 强制调用相机(不可选相册),照片带防伪水印(服务器授时+经纬度),最少 1 张最多 9 张。区分签到照(sign_in_photo)和现场照(visit_photo)
主管点评 P0 经理在详情页底部星级评分 + 文字点评,气泡样式展示。红点基于 CreateTime,修改点评不触发新红点
列表筛选 P0 全部/草稿/已完成
详情查看 P0 定位地图 + 工作摘要 + 照片墙 + 点评历史
新点评标记 P1 列表页橙色"新点评"标记(MAX(CreateTime) > LastViewedTime)。LastViewedTime 仅打开详情页时更新
客户动态创建 P2 输入新客户名时提交后自动在 ERP 创建
提交即锁定 P0 提交后 Status=completed,不可编辑。仅管理员可软删除

3.8 公告管理(Announcement)

功能 优先级 说明
公告列表 P0 置顶优先 → 未过期按发布时间倒序 → 已过期置灰;类型筛选;不支持搜索
公告详情 P0 红头文件样式、HTML/Markdown 正文、附件下载;停留 ≥2s 自动标记已读
发布公告 P0 富文本编辑、置顶开关、有效期、接收范围(全员/部门树/指定用户)、预览。全员时写入 TargetType='all' 记录
触达审计 P1 管理员查看已读/未读员工列表。已离职员工在未读名单中标记灰色"已离职",催办时自动过滤
DING 催办 P1 管理员在公告详情页查看已读/未读名单,对未读员工一键推送高优先级通知。可多次催办

3.9 数据报表(Reports)

报表入口、按角色数据范围、详细图表说明见 §3.11。此处仅列出优先级。

功能 优先级 说明
费用申请明细报表 P1 含数值卡片 + 趋势图,按角色控制数据范围
费用报销明细报表 P1 同上
加班明细报表 P1 同上
用车明细报表 P1 同上
外勤日志明细报表 P1 同上
数据导出 P2 财务角色可导出 Excel

3.10 权限管理(Admin)

功能 优先级 说明
用户搜索 P0 支持按姓名或工号模糊搜索,输入过程中自动联想匹配
权限配置 P0 快捷套餐 + 单点加减;无角色用户默认等同"员工"。快捷套餐权限点清单见附录
变更审计 P1 权限变更历史时间线
自保护 P0 管理员无法取消自己的 admin 角色;至少保留一名管理员

3.11 报表入口与权限

入口:唯一入口为工作台金刚区报表区域,点击任一报表直接进入对应独立页。五个报表各自独立路由、独立加载数据。页面内顶部为筛选条件,下方为数值卡片 + 趋势图。

角色数据范围

同一报表页,不同角色看到的数据范围不同:

角色 数据范围 展示形式 可导出
员工 仅本人 数值卡片 + 个人趋势图
经理/老板 本部门 数值卡片 + 部门横向对比柱状图 + 明细列表
财务 全公司 数值卡片 + 全公司趋势图 + 明细列表 ✅ Excel
管理员 全公司 与财务相同

数据来源:所有报表数据均来自 OA 本地业务表(费用申请/费用报销/加班/用车/外勤日志主表及明细表)。.NET 服务端按角色权限(本人/本部门/全公司)和时间范围聚合查询后返回。审批状态相关统计(如"待审批笔数")通过 .NET → ERP 实时查询补充。数值卡片和趋势图共用同一数据源,仅展示维度不同。

性能策略:预置时间段(本月/本季/本年)数据由 .NET 预计算,缓存 5 分钟。自定义时间段实时查询。数值卡片数据同时受时间筛选和角色数据范围双重约束,无数据时显示 0 或 ¥0.00,仅做展示不可点击。

各报表详细规格

报表 数值卡片 专属筛选 员工图表 经理图表 财务/管理员图表
费用申请明细 ①累计申请总额(含草稿)②当月笔数 ③已通过金额(Status='approved',含 fully_used)④待审批笔数 状态(全部/已通过/已拒绝/已撤回/已归档) 个人近 12 月申请金额 vs 已通过金额双折线 本部门横向对比柱状图(每人两根柱:申请/已通过)+ 底部明细列表 全公司趋势图(同员工)+ 底部明细列表
费用报销明细 ①累计核销总额(PaymentStatus='paid')②当月笔数 ③待审批笔数 ④待付款笔数 状态 + 付款状态 个人近 12 月报销金额 vs 审批通过金额双折线 本部门横向对比柱状图(每人两根柱:报销/通过)+ 底部明细列表 全公司趋势图 + 底部明细列表
加班明细 ①当月净工时 ②当月次数 ③累计调休小时(comp_leave 100%净工时,mixed 按 CompLeaveRatio 比例)④加班费次数 加班类型(工作日/休息日/节假日) 个人近 12 月加班工时柱状图,按类型分色堆叠 本部门横向对比柱状图(每人汇总工时)+ 底部明细列表 全公司趋势图 + 底部明细列表
用车明细 ①当月次数 ②累计里程(仅 Status='returned',EndOdometer-StartOdometer)③路桥停车费 ④未还车数 车辆 + 用途 个人近 12 月用车次数折线 本部门横向对比柱状图(每人次数/费用)+ 底部明细列表 全公司趋势图(次数 vs 费用双轴)+ 底部明细列表
外勤日志明细 ①当月拜访次数 ②拜访客户数(去重)③平均评分(至少一条点评,取最新点评,无点评显示"暂无点评")④未点评数 客户名模糊搜索 个人近 12 月拜访次数 vs 评分双轴折线 本部门横向对比柱状图(每人次数/评分)+ 底部明细列表 全公司趋势图 + 底部明细列表

数值卡片说明:所有卡片数据受时间筛选(本月/本季/本年)和角色数据范围(本人/本部门/全公司)双重约束。无数据时显示 0 或 ¥0.00。卡片仅做展示,不可点击。

经理版交互增强:点击柱状图上代表某员工的柱子 → 下方列表联动过滤该员工本月单据 → 可穿透跳转对应详情页。

各角色工作台看板卡片与报表的关系:看板卡片(§3.2)展示的是关键汇总数字,点击卡片跳转到的是对应单据列表页;金刚区报表入口(本小节)展示的是完整的趋势图表分析页。两者互补:看板做决策提醒,报表做深度分析。

3.12 关键业务规则澄清

# 规则 说明
审批链配置 审批链在 ERP 端维护,OA 不存储不配置。OA 检测到超预算时,通过 ApprovalService.SubmitAsync(tags: ["budget_exceeded"]) 告知 ERP,由 ERP 审批引擎决定是否插入特批审批节点
审批数据来源 审批状态、审批时间线、待办列表均通过 .NET → ERP 实时查询,OA 本地不存储。列表页和详情页每次打开均实时请求,保证数据始终最新
多 ERP 路由 宿主 App 登录时已确定用户所属 ERP 实例,OA 通过 .NET 服务端上下文获取,无需额外路由逻辑。一人跨多 ERP 场景由宿主 App 切换账套时重新初始化
附件存储 统一上传至云端对象存储(OSS),Attachment.FileUrl 存绝对 URL。访问通过 CDN 加速。上传限制:图片/PDF/Word/Excel ≤20MB。附件存储不设自动清理机制
无发票场景 单笔费用 ≤200 元且类别为办公费/交通卡充值等小额零星支出时,三项合规检查自动勾选,财务人员仍可手动取消勾选
申请过期处理 ValidUntil 到期后,定时 Job 自动释放冻结预算(调 BudgetService.Release),UsageStatus 标记为 fully_usedStatus 流转为 archived。通知申请人"申请已过期,预算已释放"
报表数据权限 个人报表:仅本人可见。部门报表(经理):按人汇总展示 + 可展开逐笔明细。全公司报表(财务/管理员):展示全公司所有明细。数据范围由角色权限控制,详见 §3.11
审批撤回窗口 Status=pending 即可撤回(不限制当前审批级别)。已审批通过的节点历史保留,流程终止。ERP 不支持撤回时,OA 按钮仍展示,调 ERP 后被拒则弹错误提示
预算、项目、科目 三个概念构成两级核算体系。项目是企业内按目标划分的独立核算单元。科目是费用类别在财务口径下的分类。预算挂在项目×科目的交叉点上。操作链:选项目 → 加载科目列表 → 选定科目后查询可用余额。三个字段均通过 .NET 适配器从 ERP 获取,ERP 无数据时对应下拉为空,后续预算校验自动跳过
外币/汇率 报销明细行默认币种 CNY。员工选择外币后,OA 调 .NET → ERP ExchangeRateService 获取当日汇率,自动填入 ExchangeRate。服务端计算 BaseAmount = TotalAmount × ExchangeRate,预算校验和报表均以本币(CNY)为准
费用申请状态 审批状态(Status)draft→可编辑/提交/删除;pending→可撤回;approved→可被报销引用;rejected→可重新编辑提交;withdrawn→仅查看;archived→已归档终态。使用状态(UsageStatus)unused/partially_used/fully_used(仅 approved 后有意义)。当 UsageStatus=fully_usedStatus 自动流转为 archived
费用报销状态 审批状态(Status)draftpendingapproved/rejected/withdrawn/archived付款状态(PaymentStatus):仅 approved 后生效,unpaid→财务核销后变为 paidPaymentStatus=paid 且业务完结后 Status 自动流转为 archived
加班申请状态 同费用申请,审批状态:draftpendingapproved/rejected/withdrawn/archived。业务完结后自动归档
用车申请状态 审批状态同其他单据,额外终态:returned(已还车)→archived。完整流转:draftpendingapprovedreturnedarchived(还车登记完成,车辆恢复空闲)
外勤日志状态 不走审批流,draft 草稿→completed 已提交。提交即完成且锁定不可编辑,仅管理员可软删除
公告状态 不走审批流,draft 草稿(仅创建者和管理员可见)→published 已发布(全员可见,触发触达记录写入)
列表筛选 使用顶部 Tabs 选项卡按状态筛选,按时间倒序排列。Tabs 下方增加筛选栏(日期范围 + 业务专属维度)。各单据 Tabs:事前/加班 全部/草稿/审批中/已通过/已拒绝/已撤回/已归档;报销 全部/草稿/审批中/已通过/待付款/已付款/已拒绝/已撤回/已归档;用车额外含已还车;外勤日志全部/草稿/已完成。公告——员工侧 Tabs 为公告类型(全部/通知公告/人事制度/放假活动),仅展示已发布公告;管理员侧在类型 Tabs 基础上,右上角多一个"我的草稿"入口,点开仅展示自己创建的草稿
列表搜索 各列表页在经理范围切换(如有)和状态 Tab 之间提供搜索框(TDSearchBar),客户端本地过滤。搜索栏位:费用报销:报销单号、申请人姓名;费用申请:申请单号、申请人姓名;加班申请:加班单号、申请人姓名;用车申请:用车单号、申请人姓名;外勤日志:客户名称、业务员姓名;公告:公告标题
经理列表范围 审批类单据列表页顶部状态 Tab 上方增加两个 TDChip 切换:我的发起(默认)和 下属审批(展示本部门下属提交的单据)。下属审批 模式下卡片显示申请人姓名和部门。pending 状态卡片左滑→[一键同意]
财务列表操作 费用报销列表页,财务角色默认查看全公司数据。[待付款] Tab 中卡片点击进入详情页,完成三项合规查验后方可归档
预算冻结异常 提交时调 ERP BudgetService.Freeze() 可能因超时或版本冲突失败。失败时提示"预算扣减失败,请稍后重试",不创建审批实例,用户可重新提交
草稿生命周期 存草稿→写入数据库(Status=draft)→返回列表页默认激活"草稿"Tab。继续编辑→打开表单页自动回填。草稿仅创建者本人可见(管理员也不例外),所有查询入口排除草稿。无过期时间,可长期保存
并发编辑 草稿仅创建者可见和编辑,不存在多人并发。报销单提交时使用乐观锁(Version 字段),冲突时提示"单据已被修改,请刷新后重试"
设备兼容性 仅支持竖屏手机。平板可运行但不做布局优化。折叠屏展开态默认按手机竖屏布局居中显示
多语言 V1 支持简体中文、繁体中文、英文。所有 UI 文案通过 Flutter 国际化(AppLocalizations)管理。数据库枚举值存储英文标识,前端负责翻译映射。默认跟随系统语言,用户可在个人中心手动切换
深色模式 V1 支持浅色/深色主题切换。入口在"我的"→"语言"下方 TDSwitch。通过 ThemeExtension 实现所有组件自动适配两种模式

4. 业务流程图

4.1 工作台角色路由

flowchart TD
    A[用户打开 App] --> B[.NET 加载 OaUserPermission]
    B --> C{权限判定}
    C -->|有 oa.admin.*| D[管理员版工作台]
    C -->|有 oa.expense.verify_invoice| E[财务版工作台]
    C -->|有 oa.*.approve 或 oa.report.view_dept| F[经理版工作台]
    C -->|其他| G[员工版工作台]

    D --> D1[轮播图 + 金刚区 + 发布公告入口 + 全公司财务看盘]
    E --> E1[轮播图 + 金刚区 + 全公司财务看盘]
    F --> F1[轮播图 + 金刚区 + 待审批卡片 + 部门快捷看板]
    G --> G1[轮播图 + 金刚区 + 个人快捷看板]

    D1 --> H[用户点击金刚区入口进入对应功能]
    E1 --> H
    F1 --> H
    G1 --> H

4.2 费用报销全流程

flowchart TD
    A[员工发起] --> B{有费用申请?}
    B -->|有| C[多选导入申请: 项目/科目自动带入, 填每张导入金额]
    B -->|无| D[手工选择项目→科目→查预算, 填报销单]
    C --> E[填发票明细: 币种/汇率/金额/发票号]
    D --> E
    E --> F{存草稿 还是 提交?}
    F -->|存草稿| G[草稿保存]
    G --> A
    F -->|提交审批| H[校验必填项 + .NET 调 ERP BudgetService 预算]
    H -->|超预算| I[金额标红警告, 允许提交带 budget_exceeded 标签]
    I --> K[调 ERP BudgetService 冻结预算]
    H -->|校验失败| J[ScrollTo 报错字段]
    J --> E
    H -->|校验通过| K
    K --> L[.NET → ERP 创建审批实例]
    L -->|创建失败| L1[保持 draft, 提示重试]
    L1 --> A
    L -->|创建成功| M[OA 存 ApprovalInstanceId, Status=pending]
    M --> N[.NET 消息推送审批人]

    N --> O[经理审批]
    O --> P{审批动作}
    P -->|同意| Q{是否最后一级?}
    Q -->|是| R[Status=approved, ERP 预算冻结转扣减]
    Q -->|否| S[流转下一级]
    S --> N
    P -->|拒绝| T[Status=rejected]
    M -.->|员工随时撤回| U[调 ERP 撤回 → 释放冻结预算]
    U --> V[Status=withdrawn, 审批终止]

    R --> W[.NET 通知申请人]
    W --> X{财务核销}
    X --> Y[查验: 手动勾选三项合规]
    Y --> Z{三项全勾?}
    Z -->|否| X
    Z -->|是| AA[录入电汇流水号+记账凭证号]
    AA --> AB[PaymentStatus=paid, 归档]
    AB --> AC{连续核销?}
    AC -->|是| AD[跳转下一笔待付款 FIFO]
    AD --> X
    AC -->|否| AE[返回列表]

    T --> AF[.NET 通知: 已拒绝]
    AF --> AG[员工重新编辑发起]
    AG --> A

4.3 费用申请全流程

flowchart TD
    A[员工发起] --> B[填写申请]
    B --> C[选择费用类型: 多选, 如差旅+办公]
    C --> D[选择项目 → 加载科目 → 查预算余额]
    D --> E[填预估明细行: 费用类别+预估金额, 支持多行]
    E --> F[上传支撑材料: 最多9张]
    F --> G{存草稿 还是 提交?}
    G -->|存草稿| H[草稿保存]
    H --> A
    G -->|提交审批| I[校验必填项 + 调 ERP BudgetService 查预算]
    I -->|超预算| J[金额标红警告, 允许提交]
    J --> L[调 ERP BudgetService 冻结预算, tags: budget_exceeded]
    I -->|校验失败| K[ScrollTo 报错字段]
    K --> E
    I -->|校验通过| L
    L --> L1[.NET → ERP 创建审批实例]
    L1 -->|创建失败| L2[保持 draft, 提示重试]
    L2 --> A
    L1 -->|创建成功| M[OA 存 ApprovalInstanceId, Status=pending]
    M --> N[.NET 消息推送审批人]

    N --> O[经理审批]
    O --> P{审批动作}
    P -->|同意| Q{是否最后一级?}
    Q -->|是| R[Status=approved, ERP 预算冻结转扣减]
    Q -->|否| T[流转下一级]
    T --> N
    P -->|拒绝| U[Status=rejected]

    N -.->|员工随时撤回| V[调 ERP 撤回 → 释放冻结预算]
    V --> W[Status=withdrawn, 审批终止]

    R --> X[.NET 通知申请人]
    X --> Y[UsageStatus=unused, 等待报销引用]
    Y --> Z{报销引用后 UsageStatus?}
    Z -->|fully_used| AA[Status 自动流转为 archived]
    U --> AB[.NET 通知: 已拒绝]
    AB --> AC[员工重新编辑发起]
    AC --> A

4.4 外勤日志全流程

flowchart TD
    A[业务员到达客户现场] --> B[打开 OA 创建外勤日志]
    B --> C[GPS 自动定位, 地址只读]
    C --> D{定位成功?}
    D -->|失败| E[提交按钮置灰, 提示检查定位权限]
    D -->|成功| F[输入/选择客户名称]
    F --> G[填写工作总结 + 后续计划]
    G --> H[强制拍照: 签到照1张 + 现场照1-8张]
    H --> I{至少 1 张照片?}
    I -->|否| J[提交按钮置灰]
    J --> H
    I -->|是| K[照片自动添加水印: 授时+GPS]
    K --> L{存草稿 还是 提交?}
    L -->|存草稿| M[保存草稿, 不校验GPS/照片]
    L -->|提交| N[校验GPS+照片, Status=completed, 写入数据库, 锁定不可编辑]

    N --> O[经理在详情页查看]
    O --> P[经理星级评分 + 文字点评]
    P --> Q[点评数据写入 OutingLogComment]
    Q --> R["列表页红点: MAX(CreateTime) > LastViewedTime"]
    R --> S[员工点击查看详情, 更新 LastViewedTime]
    S --> T[红点消失]

    N -.->|管理员| U[管理员可软删除已提交日志]

4.5 用车申请全流程

flowchart TD
    A[员工发起] --> B[选择车牌号: OA 本地 SysVehicle 车池]
    B --> C[填写用车事由 + 始发地/目的地]
    C --> D[地图选点: 回填经纬度]
    D --> E[选择出车/还车时间]
    E --> F[添加同行人: 通讯录多选/手动输入外部人员]
    F --> G[实时排期冲突检测: 防抖500ms]
    G -->|冲突| H[红色警告, 提交按钮置灰]
    G -->|无冲突| I{存草稿 还是 提交?}
    H --> B
    I -->|存草稿| J[草稿保存, VehicleId可空]
    I -->|提交审批| K[校验必填项 + VehicleId必填]
    K -->|校验失败| L[ScrollTo 报错字段]
    L --> C
    K -->|校验通过| M[.NET → ERP 创建审批实例]
    M -->|创建失败| M1[保持 draft, 提示重试]
    M1 --> A
    M -->|创建成功| N[OA 存 ApprovalInstanceId, Status=pending]
    N --> O[.NET 消息推送审批人]

    O --> P[经理审批]
    P --> Q{审批动作}
    Q -->|同意| R{是否最后一级?}
    R -->|是| S[Status=approved, 车辆状态更新为 in_use]
    R -->|否| T[流转下一级]
    T --> O
    Q -->|拒绝| U[Status=rejected, 车辆状态不变]

    N -.->|员工随时撤回| V[调 ERP 撤回]
    V --> W[Status=withdrawn, 车辆状态不变]

    S --> X[.NET 通知申请人]
    X --> Y[用车中, 等待还车登记]
    Y --> Z[员工点击确认还车]
    Z --> AA[填写: 实还时间 + 出车前里程 + 还车后里程 + 费用备注]
    AA --> AB{里程校验: 还车里程 >= 出车里程?}
    AB -->|否| AC[红色提示, 提交按钮置灰]
    AC --> AA
    AB -->|是| AD[确认提交]
    AD --> AE[Status=returned → archived, 车辆恢复 idle]
    U --> AF[.NET 通知: 已拒绝]
    AF --> AG[员工重新编辑发起]
    AG --> A

4.6 公告发布全流程

flowchart TD
    A[管理员进入公告发布页] --> B[填写标题 + 选择分类]
    B --> C[富文本编辑正文]
    C --> D[上传附件: 最多9个]
    D --> E[设置: 置顶开关 + 有效期可选]
    E --> F[选择接收范围]
    F --> G{范围类型}
    G -->|全员| H[PrivateLevel=0, 写入 TargetType='all']
    G -->|按部门| I[部门树多选, 实时统计覆盖人数, 预写 ReadLog]
    G -->|按用户| J[员工搜索多选, 实时统计覆盖人数, 预写 ReadLog]
    H --> K{操作}
    I --> K
    J --> K
    K -->|存草稿| L[Status=draft, 仅创建者和管理员可见]
    L --> M[后续可编辑后发布]
    K -->|预览| N[全屏模拟详情页展示效果]
    N --> K
    K -->|发布| O[确认弹窗: 确认向 N 名员工发布?]
    O -->|确认| P[Status=published, 批量写入 AnnouncementReadLog]
    P --> Q[.NET 消息推送范围内员工]

    P --> R[员工查看公告]
    R --> S[停留 >= 2秒 → 自动标记已读]
    S --> T[AnnouncementReadLog.IsRead=1, 列表红点消失]

    P -.->|管理员后续操作| U[查看触达统计: 已读/未读名单]
    U --> V[未读中标记已离职灰色标签]
    V --> W[DING 一键催办未读员工: 自动过滤已离职]

4.7 权限管理配置流程

flowchart TD
    A[管理员进入权限管理页] --> B[搜索员工: 姓名/工号]
    B --> C[点击员工卡片]
    C --> D[右侧滑出权限编辑抽屉]
    D --> E[展示当前权限状态]

    E --> F{选择操作}
    F -->|快捷套餐| G[点击套餐按钮: 员工/审批人/财务/管理员]
    F -->|手动勾选| H[逐项勾选/取消权限点]

    G --> J{套餐覆盖当前权限}
    H --> J

    J --> K{点击保存?}
    K -->|取消| L{有未保存修改?}
    L -->|是| M[确认弹窗: 放弃修改?]
    M -->|放弃| N[关闭抽屉]
    M -->|继续编辑| D
    L -->|否| N

    K -->|确认保存| O{校验}
    O -->|取消自己的admin| P[Toast: 无法移除自身管理员]
    P --> D
    O -->|移除最后admin| Q[后端拒绝: 至少保留一名管理员]
    Q --> D
    O -->|通过| R[写入 OaUserPermission + 审计日志 JSON快照]
    R --> S[Toast: 权限已更新]
    S --> N

5. 技术可行性分析

5.1 技术栈匹配

技术 成熟度 风险
移动端 Flutter 3.38.10 ✅ 已验证
Android 宿主 Java/Kotlin ✅ 已验证
iOS 宿主 OC, Xcode 14.2 ✅ 已验证
后端 .NET Framework 4.8 ✅ 已验证
数据库 SQL Server 2019+ ✅ 已验证

5.2 关键风险与缓解

风险 影响 缓解措施
多 ERP 审批 API 签名不一致 适配器层开发量不确定 先对接一套 ERP,验证适配器模式后再扩展;Flutter 端不感知差异
无 ERP 回调机制 审批状态同步延迟 列表页缓存 + 后台静默刷新 + 详情页实时校准
ERP 审批引擎能力边界未知 会签/或签等高级审批形态不可用 需求层面做最小假设(基础审批即可)
iOS 编译兼容性 Flutter 依赖可能不兼容 Xcode 14.2 每次新增依赖后在 iOS 端编译验证
预算/项目/科目依赖 ERP 适配器开发量不确定 统一适配器模式,ERP 无数据时返回空/不限,OA 隐藏对应功能区块

5.3 与现有系统的集成点

集成点 方向 方式
用户信息 ERP → OA .NET 服务端查询 ERP 主数据
组织架构 ERP → OA 同上
客户数据 ERP → OA .NET CustomerService,外勤日志输入时联想
预算 ERP → OA .NET BudgetService,余额查询/冻结/扣减/释放
项目 ERP → OA .NET ProjectService,费用申请表单级联下拉
科目 ERP → OA .NET SubjectService,依赖项目选定后加载
汇率 ERP → OA .NET ExchangeRateService,默认 CNY
审批发起 OA → ERP .NET 服务端调用 ERP 审批 API
审批状态查询 OA → ERP 同上
审批动作 OA → ERP 同上
消息推送 ERP → 用户 .NET 服务端消息模块触发推送
原生能力 App → OA MethodChannel:相机、相册、通讯录、地图、GPS

5.4 性能考量

场景 策略 预期体验
列表页加载 OA 本地业务数据 + .NET → ERP 实时查询审批状态 首次 1-2 秒
详情页打开 实时调用 ERP 刷新审批状态 200-500ms
附件上传 分片上传 + 缩略图预生成 图片 ≤20MB 3-5 秒
报表图表 后端预计算 + 5 分钟缓存 首次 1-2 秒
多 ERP 查询 .NET 服务端并行调用 + 超时熔断 单 ERP 失败不影响其他

5.5 非功能需求

5.5.1 性能

指标 目标
应用冷启动 ≤3 秒
列表页首屏 ≤1 秒(本地数据)
详情页加载 ≤2 秒(含 ERP 状态刷新)
附件上传 图片 ≤5 秒(20MB)
API 响应(列表) P95 ≤500ms
API 响应(ERP 查询) P95 ≤3s(含 ERP 耗时)

5.5.2 可用性

指标 目标
月度可用率 ≥99.5%
单 ERP 不可用降级 其他 ERP 用户不受影响;受影响用户看到明确错误提示
数据持久性 已提交单据零丢失(SQL Server 主备)

5.5.3 兼容性

平台 最低版本
Android 8.0 (API 26)
iOS 14.0
Flutter 3.38.10
SQL Server 2019+

5.5.4 安全

要求 说明
传输加密 全链路 HTTPS(客户端→服务端);内网 HTTP(服务端→ERP)
身份认证 复用宿主 App Token;401 自动触发宿主重登录
数据隔离 列表查询按 OA 权限严格控制数据范围
敏感数据脱敏 银行账号列表页展示后 4 位,详情页完整展示
审计 权限变更全量记录 OaPermissionChangeLog

5.6 依赖与假设

依赖 说明 不可用时的降级
宿主 App Flutter 集成 Flutter Module 已嵌入 Android/iOS 宿主 OA 模块不可用
ERP API 可用 审批/预算/项目/科目/汇率/客户接口 各 Adapter 返回空/不限,OA 隐藏对应功能区块
定时 Job 调度 申请过期自动释放预算 预算无法自动释放,需人工处理
.NET 服务端消息模块 推送通知 站内消息仍可见(轮询)
MethodChannel 相机/相册/通讯录/GPS/地图选点 对应功能不可用,按钮置灰+提示
SQL Server OA 业务数据持久化 全模块不可用

假设

  • 宿主 App 已完成用户登录认证,OA 启动时能从宿主获取 Token 和 ERP 用户 ID
  • ERP 审批引擎支持基础审批动作(同意/拒绝)
  • 每套 ERP 的审批 API 签名虽不同,但功能语义一致

附录

附录 A:快捷套餐权限点清单

套餐 包含权限点
员工(默认) oa.expense_apply.submitoa.expense.submitoa.overtime.submitoa.vehicle.submitoa.outing_log.submitoa.announcement.viewoa.report.view_own
审批人(经理) 员工所有权限 + oa.expense_apply.approveoa.expense.approveoa.overtime.approveoa.vehicle.approveoa.outing_log.commentoa.report.view_dept
财务 员工所有权限 + oa.expense.verify_invoiceoa.expense.payoa.report.view_alloa.report.export
管理员 全部权限(含以上所有)+ oa.announcement.publishoa.announcement.dingoa.admin.permissionoa.admin.vehicleoa.admin.banneroa.admin.cost_category

附录 B:术语表

术语 说明
ERP 企业资源计划系统,OA 模块的底层数据来源
ACL 访问控制列表,按用户逐个赋权
费用申请 费用发生前的预估申请,审批通过后可被报销单引用
审批实例 ERP 审批引擎中一次审批流程的运行实例
审批时间线 审批流程各节点的操作历史
净工时 扣除午休和晚餐休息盲区后的实际加班小时数
核销 财务确认发票合规、线下打款、凭证归档的完整闭环
DING 催办 管理员对未读公告的员工推送高优先级通知
快捷套餐 预设的权限组合模板
ERP 适配器 .NET 服务端统一接口层,每套 ERP 一个实现
预算控制 费用申请/报销关联项目预算,超支自动警告
预算科目 财务核算科目,预算挂在项目×科目的交叉点上
外币折算 报销明细选择外币后自动从 ERP 获取汇率,折算为本币
拼单导入 报销时从多张已通过的费用申请导入金额
排期冲突 用车申请选定车牌+时间后检测时段重叠
触达率 公告发布后已读人数占应达总人数的比例
乐观锁 使用 Version 字段控制并发更新冲突

文档版本:v1.1 | 日期:2026-06-27