model = new OpmMwPermissionRule; } /** * 浏览 */ public function index(): Response { return view('opm-mw-permission-rule/index'); } /** * 插入 */ public function insert(Request $request): Response { if ($request->method() === 'POST') { return parent::insert($request); } return view('opm-mw-permission-rule/insert'); } /** * 更新 */ public function update(Request $request): Response { if ($request->method() === 'POST') { return parent::update($request); } return view('opm-mw-permission-rule/update'); } /** * 获取已配置的表名列表 */ public function getTables(Request $request): Response { $tables = OpmMwPermissionRule::query() ->distinct() ->pluck('table') ->toArray(); if (empty($tables)) { $tables = ['opm_mw_info_data', 'opm_mw_hospital', 'opm_mw_department']; } sort($tables); return json(['code' => 0, 'data' => $tables]); } /** * SQL 预览 API * * 说明: * - 这里使用 Db::table(),不要再用匿名 model * - 否则有些环境下 from 会被污染,导致表名解析异常 */ public function previewSql(Request $request): Response { $admin = runCatching(fn() => admin(), '无法获取登录状态')->getOrDefault([]); $tableName = (string)$request->get('table', 'opm_mw_info_data'); $admin = $this->compatibleAdminAttr($admin); if (!preg_match('/^[A-Za-z0-9_]+$/', $tableName)) { $tableName = 'opm_mw_info_data'; } $builderQuery = Db::table($tableName); $originalSql = $this->getSqlFromQuery($builderQuery); try { $service = new DataPermissionService($admin); $queryWithPermission = $service->apply($builderQuery); $permissionSql = $this->getSqlFromQuery($queryWithPermission); } catch (\Throwable $e) { return json([ 'code' => 1, 'msg' => 'SQL 预览失败:' . $e->getMessage(), 'data' => [ 'table' => $tableName, 'original' => $originalSql, 'permission' => '', 'admin_attr' => array_intersect_key($admin, array_flip(['hospitals', 'departments', 'data', 'datum'])) ] ]); } return json([ 'code' => 0, 'data' => [ 'table' => $tableName, 'original' => $originalSql, 'permission' => $permissionSql, 'admin_attr' => array_intersect_key($admin, array_flip(['hospitals', 'departments', 'data', 'datum'])) ] ]); } /** * 兼容用户属性键 */ protected function compatibleAdminAttr(array $admin): array { $pluralToSingular = ['data' => 'datum']; foreach ($pluralToSingular as $plural => $singular) { if (!isset($admin[$plural]) && isset($admin[$singular])) { $admin[$plural] = $admin[$singular]; } } return $admin; } /** * 从查询构造器获取 SQL */ protected function getSqlFromQuery($query): string { $sql = $query->toSql(); $bindings = $query->getBindings(); foreach ($bindings as $binding) { if (is_bool($binding)) { $value = $binding ? '1' : '0'; } elseif (is_null($binding)) { $value = 'null'; } elseif (is_numeric($binding)) { $value = (string)$binding; } else { $value = "'" . addslashes((string)$binding) . "'"; } $sql = preg_replace('/\?/', $value, $sql, 1); } return $sql; } }