Files
webman-buildadmin/app/common/service/AdminChannelScopeService.php
zhenhui 1cdd597879 1.优化充值跳转链接的问题
2.优化后台渠道管理页面的显示样式
2026-05-30 14:37:46 +08:00

198 lines
5.0 KiB
PHP
Raw Permalink 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/index、edit 等)→ 全部渠道(读+写)
* - 均未绑定且无渠道模块权限 → 不可见
*/
class AdminChannelScopeService
{
/**
* 是否具备全平台只读范围(其它菜单按 admin 收窄时跳过):超管 / 未绑定渠道且拥有渠道模块权限
*/
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::hasAnyChannelMenuPermission($auth);
}
/**
* 可读渠道 ID 列表null 表示不限制(全部渠道)
*
* @return array<int, int>|null
*/
public static function readableChannelIds(Auth $auth): ?array
{
return self::resolveScopedChannelIds($auth);
}
/**
* 可写渠道 ID 列表null 表示不限制(全部渠道)
*
* @return array<int, int>|null
*/
public static function writableChannelIds(Auth $auth): ?array
{
return self::resolveScopedChannelIds($auth);
}
/**
* @return array<int, int>|null
*/
private static function resolveScopedChannelIds(Auth $auth): ?array
{
if (!$auth->isLogin()) {
return [0];
}
if ($auth->isSuperAdmin()) {
return null;
}
$ids = self::resolveEffectiveChannelIds($auth);
if ($ids !== []) {
return $ids;
}
if (self::hasAnyChannelMenuPermission($auth)) {
return null;
}
return [0];
}
/**
* 是否拥有渠道管理模块相关权限(菜单或任一 channel/* 按钮)
*/
public static function hasAnyChannelMenuPermission(Auth $auth): bool
{
if (!$auth->isLogin()) {
return false;
}
if ($auth->isSuperAdmin()) {
return true;
}
$checkNodes = [
'channel',
'channel/index',
'channel/add',
'channel/edit',
'channel/del',
'channel/manualSettle',
'channel/batchSettlePending',
'channel/settleStats',
];
foreach ($checkNodes as $node) {
if ($auth->check($node)) {
return true;
}
}
$ruleList = $auth->getRuleList();
foreach ($ruleList as $name) {
if (!is_string($name) || $name === '') {
continue;
}
$lower = strtolower($name);
if ($lower === 'channel' || str_starts_with($lower, 'channel/')) {
return true;
}
}
return false;
}
/**
* 管理员实际绑定的渠道(角色组 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));
}
/**
* 列表按 channel_id 过滤时使用的 IDnull=不过滤
*
* @return array<int, int>|null
*/
public static function channelIdFilterForQuery(Auth $auth): ?array
{
return self::readableChannelIds($auth);
}
}