权限管理与测试
This commit is contained in:
@@ -0,0 +1,167 @@
|
||||
<?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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user