Files
webman-buildadmin/app/common/service/AdminChannelScopeService.php

161 lines
4.1 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
declare(strict_types=1);
namespace app\common\service;
use app\admin\library\Auth;
use support\think\Db;
/**
* 后台管理员渠道数据范围:
* - 账号 channel_id 或角色组 channel_id 任一绑定 → 仅可读对应渠道(优先于「查看所有渠道」)
* - 均未绑定且拥有 viewAllChannels → 全平台只读
*/
class AdminChannelScopeService
{
/**
* 是否具备全平台只读范围(超管 / 未绑定任何渠道且拥有查看所有渠道)
*/
public static function hasGlobalReadScope(Auth $auth): bool
{
if (!$auth->isLogin()) {
return false;
}
if ($auth->isSuperAdmin()) {
return true;
}
if (self::resolveEffectiveChannelIds($auth) !== []) {
return false;
}
return self::hasViewAllChannelsPermission($auth);
}
/**
* 可读渠道 ID 列表null 表示不限制(全部渠道)
*
* @return array<int, int>|null
*/
public static function readableChannelIds(Auth $auth): ?array
{
if (!$auth->isLogin()) {
return [0];
}
if ($auth->isSuperAdmin()) {
return null;
}
$ids = self::resolveEffectiveChannelIds($auth);
if ($ids !== []) {
return $ids;
}
if (self::hasViewAllChannelsPermission($auth)) {
return null;
}
return [0];
}
/**
* 管理员实际绑定的渠道(角色组 channel_id + 账号 admin.channel_id去重
*
* @return array<int, int>
*/
public static function resolveEffectiveChannelIds(Auth $auth): array
{
$ids = self::resolveBoundGroupChannelIds($auth);
$selfChannelId = self::resolveAdminAccountChannelId($auth);
if ($selfChannelId > 0) {
$ids[] = $selfChannelId;
}
return array_values(array_unique($ids));
}
/**
* 当前管理员账号上的 channel_id
*/
public static function resolveAdminAccountChannelId(Auth $auth): int
{
if (!$auth->isLogin()) {
return 0;
}
$uid = (int) $auth->id;
if ($uid <= 0) {
return 0;
}
$value = Db::name('admin')->where('id', $uid)->value('channel_id');
if ($value === null || $value === '') {
return 0;
}
return (int) $value;
}
/**
* 当前管理员所属角色组上绑定的渠道 ID去重
*
* @return array<int, int>
*/
public static function resolveBoundGroupChannelIds(Auth $auth): array
{
$uid = (int) $auth->id;
if ($uid <= 0) {
return [];
}
$groupIds = Db::name('admin_group_access')->where('uid', $uid)->column('group_id');
if ($groupIds === []) {
return [];
}
$rows = Db::name('admin_group')
->where('id', 'in', $groupIds)
->whereNotNull('channel_id')
->where('channel_id', '>', 0)
->column('channel_id');
$ids = [];
foreach ($rows as $cid) {
$ids[] = (int) $cid;
}
return array_values(array_unique($ids));
}
/**
* 是否拥有「查看所有渠道」按钮权限
*/
public static function hasViewAllChannelsPermission(Auth $auth): bool
{
if (!$auth->isLogin()) {
return false;
}
$nodes = ['channel/viewAllChannels', 'channel/viewallchannels'];
foreach ($nodes as $node) {
if ($auth->check($node)) {
return true;
}
}
$ruleList = $auth->getRuleList();
foreach ($nodes as $node) {
if (in_array(strtolower($node), $ruleList, true)) {
return true;
}
}
return false;
}
/**
* 列表按 channel_id 过滤时使用的 IDnull=不过滤
*
* @return array<int, int>|null
*/
public static function channelIdFilterForQuery(Auth $auth): ?array
{
return self::readableChannelIds($auth);
}
}