Files
dsserver/plugin/admin/app/controller/OpmMwPermissionRuleController.php
2026-04-03 16:21:28 +08:00

167 lines
4.4 KiB
PHP

<?php
namespace plugin\admin\app\controller;
use plugin\admin\app\common\DataPermissionService;
use plugin\admin\app\controller\Crud;
use plugin\admin\app\model\OpmMwPermissionRule;
use support\Db;
use support\Request;
use support\Response;
use support\exception\BusinessException;
/**
* 数据权限规则管理
*/
class OpmMwPermissionRuleController extends Crud
{
/**
* @var OpmMwPermissionRule
*/
protected $model = null;
public function __construct()
{
$this->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;
}
}