action = $action; } public function setMeta(array $meta): void { $this->meta = $meta + $this->meta; } /** 模型字段级变更推送(由 Trait 调用) */ public function pushModelChange(string $scene, $objectId, array $old, array $new): void { $keys = array_unique(array_merge(array_keys($old), array_keys($new))); foreach ($keys as $k) { $ov = $old[$k] ?? null; $nv = $new[$k] ?? null; if ($ov === $nv) continue; [$ovMasked, $nvMasked] = $this->maskIfNeeded($k, $ov, $nv); $this->changes[] = [ 'scene' => $scene, 'object_id' => $objectId, 'field' => $k, 'old' => $ovMasked, 'new' => $nvMasked, ]; } } private function maskIfNeeded(string $field, $old, $new): array { foreach ($this->maskFields as $m) { if (stripos($field, $m) !== false) { return [$old===null?null:'***', $new===null?null:'***']; } } if (preg_match('/(mobile|phone|tel|idcard|id_card)/i', $field)) { $mask = function ($v) { if ($v === null) return null; $s = (string)$v; return mb_substr($s, 0, 3).'****'.mb_substr($s, -4); }; return [$mask($old), $mask($new)]; } return [$old, $new]; } }