This commit is contained in:
zimoyin
2026-04-03 11:32:19 +08:00
parent 4c841b9dbf
commit 1a84e92384
30 changed files with 403 additions and 1030 deletions
+187
View File
@@ -2,10 +2,16 @@
namespace plugin\admin\app\model;
use app\utils\Logger;
use DateTimeInterface;
use Illuminate\Database\Eloquent\Builder;
use support\Db;
use support\Model;
/**
* @method static \Illuminate\Database\Eloquent\Builder|static withDataPermission()
*/
class Base extends Model
{
/**
@@ -23,4 +29,185 @@ class Base extends Model
{
return $date->format('Y-m-d H:i:s');
}
public function scopeWithDataPermission(Builder $query): Builder
{
$admin = runCatching(fn() => admin(),"无法获取登录状态")->getOrDefault([]);
$hospitalRaw = trim((string)($admin['hospitals'] ?? ''));
$departmentRaw = trim((string)($admin['departments'] ?? ''));
if ($hospitalRaw === '*' && $departmentRaw === '*') {
return $query;
}
$hospitalIds = $this->parseVisibleIds($hospitalRaw);
$departmentIds = $this->parseVisibleIds($departmentRaw);
if (empty($hospitalIds) && empty($departmentIds)) {
return $query->whereRaw('1 = 0');
}
$baseQuery = $query->getQuery();
// 主表
[$fromTable, $fromAlias] = $this->parseTableAlias((string)($baseQuery->from ?? ''));
// 识别 join 里的医院/科室表别名
$hospitalAlias = $this->findTableAlias($baseQuery, 'opm_mw_hospital');
$departmentAlias = $this->findTableAlias($baseQuery, 'opm_mw_department');
Logger::debug('scopeWithDataPermission fromTable:{} fromAlias:{} hospitalAlias:{} departmentAlias:{} hospitalIds:{} departmentIds:{}', [
$fromTable,
$fromAlias,
$hospitalAlias,
$departmentAlias,
$hospitalIds,
$departmentIds,
]);
// 1) 主表就是医院表:只加医院权限
if ($fromTable === 'opm_mw_hospital' && $hospitalAlias) {
if (empty($hospitalIds)) {
return $query->whereRaw('1 = 0');
}
return $query->whereIn("{$hospitalAlias}.id", $hospitalIds);
}
// 2) 主表就是科室表:只加科室权限
if ($fromTable === 'opm_mw_department' && $departmentAlias) {
return $query->where(function (Builder $q) use ($departmentAlias, $hospitalIds, $departmentIds) {
$has = false;
// 科室权限:department.id
if (!empty($departmentIds)) {
$q->whereIn("{$departmentAlias}.id", $departmentIds);
$has = true;
}
// 医院权限:department.organ_id
if (!empty($hospitalIds)) {
if ($has) {
$q->whereIn("{$departmentAlias}.organ_id", $hospitalIds);
} else {
$q->orWhereIn("{$departmentAlias}.organ_id", $hospitalIds);
}
$has = true;
}
if (!$has) {
$q->whereRaw('1 = 0');
}
});
}
// 3) 主表不是这两个,但 join 里有它们:按别名补条件
return $query->where(function (Builder $q) use (
$hospitalAlias,
$departmentAlias,
$hospitalIds,
$departmentIds
) {
$hasAny = false;
if ($hospitalAlias && !empty($hospitalIds)) {
$q->whereIn("{$hospitalAlias}.id", $hospitalIds);
$hasAny = true;
}
if ($departmentAlias) {
$q->where(function (Builder $dq) use ($departmentAlias, $hospitalIds, $departmentIds) {
$has = false;
if (!empty($departmentIds)) {
$dq->whereIn("{$departmentAlias}.id", $departmentIds);
$has = true;
}
if (!empty($hospitalIds)) {
if ($has) {
$dq->orWhereIn("{$departmentAlias}.organ_id", $hospitalIds);
} else {
$dq->whereIn("{$departmentAlias}.organ_id", $hospitalIds);
}
$has = true;
}
if (!$has) {
$dq->whereRaw('1 = 0');
}
});
$hasAny = true;
}
if (!$hasAny) {
$q->whereRaw('1 = 0');
}
});
}
/**
* 解析 "table as t" / "table t"
*/
protected function parseTableAlias(string $table): array
{
$table = trim(str_replace('`', '', $table));
if ($table === '') {
return ['', ''];
}
if (stripos($table, ' as ') !== false) {
[$name, $alias] = preg_split('/\s+as\s+/i', $table, 2);
return [trim($name), trim($alias)];
}
$parts = preg_split('/\s+/', $table);
if (count($parts) >= 2) {
return [trim($parts[0]), trim($parts[1])];
}
return [$table, $table];
}
/**
* 在 from / joins 中找指定表的别名
*/
protected function findTableAlias($baseQuery, string $tableName): ?string
{
[$fromTable, $fromAlias] = $this->parseTableAlias((string)($baseQuery->from ?? ''));
if ($fromTable === $tableName) {
return $fromAlias;
}
foreach (($baseQuery->joins ?? []) as $join) {
[$joinTable, $joinAlias] = $this->parseTableAlias((string)($join->table ?? ''));
if ($joinTable === $tableName) {
return $joinAlias;
}
}
return null;
}
/**
* 把 "1,2,3" / "123" / " 1 , 2 " 转成数组
*/
protected function parseVisibleIds(string $raw): array
{
$raw = trim($raw);
if ($raw === '' || $raw === '*') {
return [];
}
$parts = preg_split('/[,\s]+/u', $raw) ?: [];
$parts = array_filter($parts, static fn($v) => $v !== '');
return array_values(array_unique(array_map('intval', $parts)));
}
}
+2 -3
View File
@@ -1,8 +1,7 @@
<?php
namespace app\model;
namespace plugin\admin\app\model;
use support\Model;
/**
* OpmMwDepartment 模型
@@ -30,7 +29,7 @@ use support\Model;
* @property string $deptId deptId
* @property int $s_report s_report(默认值:1
*/
class OpmMwDepartment extends Model
class OpmMwDepartment extends Base
{
/**
* 数据表名
+3 -2
View File
@@ -1,7 +1,8 @@
<?php
namespace app\model;
namespace plugin\admin\app\model;
use plugin\admin\app\model\Base;
use support\Model;
/**
@@ -38,7 +39,7 @@ use support\Model;
* @property string $url2 url2
* @property int $is_push is_push(默认值:0
*/
class OpmMwHospital extends Model
class OpmMwHospital extends Base
{
/**
* 数据表名