$path) { $source = file_get_contents($path); if (!is_string($source)) { throw new RuntimeException("无法读取 {$name}: {$path}"); } $sources[$name] = $source; } $migration = $sources['migrationPath']; foreach (['qywx_promotion_pool_operator', 'uk_pool_admin', 'granted_by_admin_id'] as $needle) { if (!str_contains($migration, $needle)) { throw new RuntimeException("共享操作人迁移缺少 {$needle}"); } } $logic = $sources['logicPath']; foreach (['batchSetOperators', 'applyPoolAccessScope', 'isPoolOperator', 'can_manage_access', 'operator_options'] as $needle) { if (!str_contains($logic, $needle)) { throw new RuntimeException("获客助手共享权限逻辑缺少 {$needle}"); } } $deleteStart = strpos($logic, 'public static function deletePool('); $deleteEnd = strpos($logic, 'public static function batchSetOperators(', $deleteStart === false ? 0 : $deleteStart); if ($deleteStart === false || $deleteEnd === false) { throw new RuntimeException('无法定位 deletePool/batchSetOperators'); } $deleteMethod = substr($logic, $deleteStart, $deleteEnd - $deleteStart); if (!str_contains($deleteMethod, "assertScopedRow('qywx_promotion_pool', \$id, \$adminId, \$adminInfo, false)")) { throw new RuntimeException('共享操作人不得永久删除分流方案'); } if (!str_contains($sources['customerLogicPath'], 'operatorPoolIds($adminId)') || !str_contains($sources['customerLogicPath'], "whereOr('p.id', 'in', \$operatorPoolIds)")) { throw new RuntimeException('共享操作人尚未接入获客客户统计权限'); } if (!str_contains($sources['controllerPath'], 'public function batchSetOperators()')) { throw new RuntimeException('控制器缺少批量设置操作人接口'); } if (!str_contains($sources['apiPath'], '/firstvisit.wecomPromotion/batchSetOperators')) { throw new RuntimeException('前端 API 缺少批量设置操作人接口'); } foreach (['批量设置访问操作', '添加操作人', '移除操作人', 'selectedPoolIds', 'can_manage_access'] as $needle) { if (!str_contains($sources['viewPath'], $needle)) { throw new RuntimeException("前端共享权限交互缺少 {$needle}"); } } echo "WECOM_PROMOTION_POOL_OPERATOR_CONTRACT_OK\n";