一、一个离职三个月的员工,名下还挂着七台设备
去年做年度资产核对,清出来一批奇怪的责任人:有离职三个月的,有调到别的子公司的,还有挂在已经撤销的部门下面的。合计四十多台设备,状态全是"在用"。
设备没丢,物理上都还在某个工位上或者库房里。问题是系统不知道它们归谁。
追溯下来,根源不在资产模块,在我们前一年做的一件事:把办公平台的组织架构同步进了资产系统。同步本身没问题,人员入职、部门调整都能自动过来。但同步只解决了"这个人存不存在",没解决"他手里的东西归谁"。
二、同步之后,问题的性质变了
以前组织架构靠手工维护,一年更新两次。慢,但每次变更都有人顺手看一眼资产。同步之后,人员数据每天在变,资产归属却还是静态字段,两者之间没有任何联动。
更麻烦的是标识。办公平台的人员 ID、资产表里的使用人、财务系统里的责任人,三套编号体系。我们最初用姓名做关联,第一次核对就撞了三个重名的。
工号也不行——工号会复用。一个离职员工的工号半年后分给新人,历史资产会顺着这个键直接漂到新人名下。
正确的做法是建一张外部标识映射表:外部系统 ID、本地人员 ID、生效时间、失效时间。所有关联都走这张表,姓名和工号只做展示。
三、同步服务要区分的四种变更
组织树同步看着简单,实际要分开处理的变更不止一种:
- 新增:新部门、新员工。
- 改名:部门更名,ID 不变,树上位置不变。
- 移动:员工换部门,或者整个部门挂到另一条线下。
- 停用:离职、部门撤销。
前两种好办。第三种最容易出错:一个人换部门,他只是换了个 parent;但如果一个部门整体移动到另一条线下,它的整个子树都要跟着走,资产上的"归属部门"字段得按子树批量重算。这一步漏了,就会出现人在新部门、资产挂在旧部门。
第四种的关键是停用不等于删除。离职人员的记录必须保留,否则他名下的历史资产失去责任人,履历从中间断掉。
SYNC_TARGETS = {
"hris": HrisAdapter("dingtalk"), # 组织与人员主数据
"ledger": LedgerAdapter("首码资产管理系统"), # 资产台账
}
对接外部系统时,这些适配器在服务启动阶段统一装配,业务代码不直接依赖任何一方的接口形态。换一套办公平台,改的是装配配置,不是业务逻辑。
同步日志要落两条:一条记变更前后的结构快照,一条记本次同步影响到的资产条数。前者用来回溯,后者用来判断一次同步是不是异常放大。我们设的阈值是单次影响超过三百条就转人工确认,拦住过两次误操作。
四、全量、增量、乱序:链路侧的三条约束
同步策略上,全量拉取在几百人的公司没感觉,人数过千就出问题:一次全量几百个请求,办公平台有频控,跑到一半被限流,剩下的节点只能等下一轮。
我们改成增量为主:按更新时间和事件订阅两条路取变更,每天凌晨再做一次全量校对,用全量兜住增量漏掉的部分。增量请求走指数退避重试,连续失败三次就熔断本轮、记一条告警,不跟频控硬刚。
第二个坑是乱序。外部平台的事件不保证顺序,先到"员工转部门"、后到"员工离职"是常事。如果按到达顺序覆盖本地状态,最后会得到一条"在职且在新部门"的错误记录。我们的处理是每条事件带发生时间和版本号,本地只接受比当前版本更新的事件,旧事件丢弃并记日志。同一条事件重复投递也要能重放——处理逻辑做成幂等,重放多次结果一致。
第三个是树怎么存。本地组织树用路径枚举,每个节点存一条从根到自己的路径,子树查询就是一次前缀匹配,比递归查询省事得多。代价是移动部门时要批量更新子树路径,所以移动操作放进一个短事务,几千个节点也能在可接受的时间内完成。
五、离职不是一个状态,是一串任务
系统收到离职事件,最省事也最没用的做法是把人员状态改成"离职"就结束。真正要做的是生成一串待办:
- 拉出这个人名下所有在用资产,生成回收清单。
- 通知直属主管和 IT,限期处理。
- 超期未回收的,升级到部门负责人。
- 回收完成,事件才关闭。
流程里有个容易忽略的细节:回收清单要在事件发生时冻结。如果清单是实时查出来的,中途有人把设备转给别人,清单会自己变短,最后核对时根本看不出少了几台。
我们做成快照——事件触发时把清单固化,后续每次处理只更新状态,不增删条目。多出来的设备单独走一张差异表,该补录补录。
六、归属唯一性靠日检兜住
上面这些是正向流程。反向校验是每天跑一次的对账:
- 状态为"在用"的资产,责任人必须是有效在职员工;
- 资产的归属部门,必须在当前组织树里存在;
- 资产的存放地点,必须挂在有效的场地下。
任一条对不上就进异常池,推给资产管理员。上线第一个月出了两百多条,大半是历史数据;稳定之后每天个位数,多数是同步延迟造成的瞬时状态,第二天自己就消失了。
这里有个原则:日检只做判定,不做自动修复。自动把资产改成"待回收"看着省事,实际会把责任关系搅乱,人还是得再查一遍,反而多了一道返工。
七、这套东西管不到的地方
说几个到现在也没解决好的:
矩阵组织下一个人挂两个部门,归属写哪个,系统给不出答案,只能约定主部门优先,例外走备注。外包和实习生的入离职不走同一条流程,同步源不一样,得单独接一路。设备共用的情况,比如会议室笔记本、测试机,责任人只能填管理人,实际去向依然靠借用单。还有历史资产,责任人如果是离职多年的人,只能一台台确认,没有批量办法。
结语
组织架构同步这件事,做之前以为是把人拉过来,做完才发现真正的工作在"人走了之后"。
资产管理的粒度最终会落到人身上:不是"公司有多少台设备",而是"谁手上有什么"。前一个问题靠盘点能答,后一个只有把人员异动和资产归属接成一条线,才答得出来。