这几年接触企业数字化项目时,我发现一个比较普遍的现象:
很多企业并不是没有软件,而是“软件很多,业务还是靠人”。
ERP里有一份数据,Excel里还有一份;销售在微信里跟客户,仓库通过群消息确认发货,财务最后再人工汇总。每个环节看起来都有工具,但真正串起来以后,数据还是断的。
所以一个企业软件项目真正难的地方,往往不是开发几个页面,而是如何把现实中的业务流程转换成一套可以执行的系统逻辑。
本文结合制造、商贸、供应链、物业等企业系统项目中比较常见的问题,聊一下企业数字化系统从需求到落地时值得关注的几个点。
一、企业提出的“功能需求”,很多时候并不是真正的需求
企业做软件时,经常会提出这样的需求:
我要一个客户管理。
或者:
仓库需要扫码出库。
从开发角度看,这种描述其实还无法直接进入开发。
以“扫码出库”为例,真正拆开以后,可能是这样的:
销售订单 ↓ 库存占用 ↓ 选择仓库 ↓ 选择商品批次 ↓ PDA扫码 ↓ 校验应出数量 ↓ 生成出库记录 ↓ 扣减库存 ↓ 更新订单状态 ↓ 同步财务或ERP
这里面至少涉及订单、商品、批次、库存、仓库、操作人和财务状态等多个数据对象。
如果只是按照“增加一个扫码按钮”去理解需求,页面可能很快就能做出来,但上线后往往无法真正使用。
所以在企业系统里,一个功能至少要考虑三个层面:
谁操作、操作什么数据、操作以后会影响什么。
这也是业务需求转换成系统需求的关键过程。
很多项目一开始就进入原型设计,其实比较容易出现问题。
更合理的顺序通常应该是:
业务流程 → 角色 → 数据 → 状态 → 页面
比如一个简单的采购流程:
需求申请 → 部门审批 → 采购询价 → 采购订单 → 到货 → 入库 → 对账 → 付款。
接下来再确定不同角色:
| 角色 | 主要操作 |
|---|---|
| 申请人 | 提交采购需求、查看状态 |
| 部门负责人 | 审批采购申请 |
| 采购人员 | 询价、生成采购订单 |
| 仓库人员 | 到货确认、入库 |
| 财务人员 | 对账、付款 |
| 管理人员 | 查看进度和统计 |
角色明确以后,权限和页面才比较容易确定。
例如仓库人员可能根本不需要看到供应商付款金额,而财务人员也不一定需要修改实际入库数量。
这时权限设计就不应该只停留在:
管理员
普通用户
而应该逐渐拆成:
用户
↓
角色
↓
菜单权限
↓
操作权限
↓
数据权限
企业系统中,真正复杂的通常不是“能不能打开这个页面”,而是:
打开页面以后能看到哪些数据。
很多业务系统实际上都可以理解成一个状态机。
以订单为例:
待确认
→ 已确认
→ 待采购
→ 采购中
→ 已到货
→ 待出库
→ 部分出库
→ 已完成
如果没有提前定义状态,后续很容易出现逻辑冲突。
例如:
订单已经部分出库以后还能不能修改商品?
订单取消以后库存占用是否释放?
已经付款的采购订单能不能删除?
部分退款以后订单应该显示什么状态?
这些问题都不是页面设计问题,而是业务状态设计问题。
在实际开发中,我更倾向于在产品阶段就把关键业务对象的状态整理出来。
例如订单表可以存在:
order_status
payment_status
delivery_status
settlement_status
而不是使用一个万能的:
status
否则项目做到后面,状态会越来越难维护。
企业系统另一个常见问题是数据模型设计得过于简单。
例如订单系统刚开始可能只设计:
order
一张订单表。
但业务深入以后,经常还需要:
order
order_item
order_payment
order_delivery
order_attachment
order_operation_log
如果涉及采购,还可能继续关联:
purchase_order
purchase_item
supplier
warehouse
inventory
inventory_batch
为什么要拆?
因为现实业务天然就是一对多关系。
一个销售订单可能有多个商品;
一次订单可能分三次出库;
客户可能分两次付款;
一个商品可能对应多个库存批次。
如果一开始全部塞进订单表,后期面对分批出库、多次收款、多批次库存时,数据库结构会越来越难维护。
现在很多企业已经有ERP、财务软件、电商平台或者设备平台。
因此新项目经常会遇到:
新系统
↓
API
↓
ERP / CRM / 财务 / 电商平台 / IoT平台
这时候系统设计重点就从CRUD变成了数据同步。
比如订单同步就需要考虑:
谁是主数据源?
哪个系统可以修改?
接口调用失败怎么办?
重复推送怎么办?
网络异常以后是否重试?
两个系统同时修改如何处理?
一个比较基础的接口同步设计通常需要:
业务操作
↓
本地事务成功
↓
生成同步任务
↓
异步调用第三方接口
↓
记录接口结果
↓
失败重试
↓
人工异常处理
而不是业务代码里面直接:
thirdPartyApi.send(order);
否则第三方系统一旦超时,本地业务也可能受到影响。
对于比较重要的数据同步,还应该考虑幂等。
例如可以通过:
business_id
request_id
sync_status
retry_count
保证同一条业务不会被重复写入。
举一个典型的CRM场景。
公司有100个销售。
所有人都可以访问“客户管理”页面。
但是:
销售A只能看自己的客户;
销售主管可以看自己团队的客户;
销售总监可以看整个销售部门;
老板可以看全部客户。
所以菜单权限其实都一样:
CRM
└─ 客户管理
真正不同的是SQL最终查询的数据范围。
一种常见做法是将数据权限拆成:
SELF
DEPARTMENT
DEPARTMENT_AND_CHILDREN
ASSIGNED
ALL
最终查询时根据当前用户的数据权限动态添加查询条件。
比如:
SELECT *
FROM customer
WHERE owner_id = ?
或者:
SELECT *
FROM customer
WHERE department_id IN (...)
很多企业系统做着做着发现权限越来越难处理,原因通常就是前期只设计了菜单权限,没有设计数据权限。
企业系统上线以后,经常会遇到这样的情况:
这个金额是谁改的?
这个订单昨天还是正常的。
客户资料为什么突然没有了?
如果系统只保存当前数据,没有操作日志,很多问题基本无法追踪。
所以重要业务最好保留:
操作人
操作时间
操作类型
修改前数据
修改后数据
IP
设备信息
业务单号
例如:
2026-09-10 14:32
用户:张三
操作:修改销售订单
订单号:SO20260910001
字段:销售价格
修改前:¥12,800
修改后:¥11,500
对于ERP、CRM、财务、供应链等系统,这类日志后期非常有价值。
除了方便排查Bug,也可以作为内部管理和审计依据。
企业第一次做定制系统时,经常有一种想法:
既然开发一次,那就一次全部做完。
于是一个项目逐渐变成:
CRM
+ ERP
+ OA
+ 财务
+ 商城
+ 小程序
+ APP
+ BI
+ AI
最终功能越来越多,项目周期越来越长,真正的核心业务反而没有跑通。
实际项目中,我更建议先确定一个闭环。
例如商贸企业一期只做:
客户
→ 报价
→ 合同
→ 销售订单
→ 采购
→ 入库
→ 出库
→ 回款
先保证这条主链路能够真实运行。
然后再逐步增加:
CRM分析
经营看板
移动审批
供应商门户
AI查询
软件项目并不是功能数量越多越好。
先跑通核心业务,再逐渐增加能力,通常比第一版就建设一个大平台风险更低。
客户有时会问:
Vue还是React?
Java还是PHP?
MySQL还是PostgreSQL?
技术选型当然重要,但对于普通企业管理系统而言,它通常不是项目失败的主要原因。
大部分系统使用:
Vue / React
+
Java / Node.js / .NET
+
MySQL / PostgreSQL
+
Redis
都可以完成。
真正容易导致项目失败的往往是:
需求理解错误;
业务状态没有设计清楚;
角色和权限边界混乱;
数据库结构无法支撑后续业务;
项目范围持续扩大;
上线以后没有真实业务人员使用。
所以企业软件项目本质上是:
业务设计 + 产品设计 + 软件工程。
代码只是其中一个环节。
我现在判断一个企业数字化项目是否真正完成,不太看页面数量,而更关注下面几个问题。
核心业务是不是可以从头到尾完整跑通?
关键数据是不是只有一个可信来源?
不同岗位是不是只看到自己应该看到的数据?
任何重要业务变化是不是能够追踪?
第三方接口异常以后系统是不是还能正常处理?
管理人员是不是可以直接通过系统得到经营数据,而不用再找人整理Excel?
如果这些问题都解决了,系统才真正开始产生价值。
反过来,如果系统上线以后员工依然每天:
导出Excel
↓
微信群确认
↓
人工汇总
↓
再录回系统
那么数字化实际上只完成了表面。
总结
企业数字化系统最难的部分,很少是把页面写出来。
真正需要解决的是如何把现实中的:
人、流程、规则、数据和系统
转换成稳定的软件模型。
从实践角度来看,可以概括成一条主线:
先理解业务 → 再梳理流程 → 明确角色权限 → 建立数据模型 → 定义状态 → 最后再开发页面和接口。
顺序一旦反过来,项目就很容易陷入不断改页面、改字段、改流程的循环。
这也是我现在做企业软件项目时越来越重视前期业务分析,而不是急着进入开发阶段的原因。
