From 54fb283b8dc5b29fcede5105faca3dac84397e81 Mon Sep 17 00:00:00 2001 From: zhenhui <1276357500@qq.com> Date: Fri, 29 May 2026 17:24:07 +0800 Subject: [PATCH] =?UTF-8?q?1.=E4=BC=98=E5=8C=96=E5=90=8E=E5=8F=B0=E7=AE=A1?= =?UTF-8?q?=E7=90=86=E5=91=98=E7=AE=A1=E7=90=86=E9=A1=B5=E9=9D=A2=E7=9A=84?= =?UTF-8?q?=E6=9D=83=E9=99=90=E8=AE=BE=E7=BD=AE=EF=BC=8C=E6=96=B0=E5=A2=9E?= =?UTF-8?q?zihuaadmin=E8=B4=A6=E5=8F=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/admin/controller/Channel.php | 80 ++---- app/admin/controller/auth/Admin.php | 240 ++++++++++++------ app/admin/controller/auth/Group.php | 134 +--------- config/process.php | 3 +- web/src/lang/backend/en/auth/admin.ts | 3 +- web/src/lang/backend/zh-cn/auth/admin.ts | 4 +- .../views/backend/auth/admin/popupForm.vue | 100 ++++++-- web/src/views/backend/auth/group/index.vue | 22 +- .../views/backend/auth/group/popupForm.vue | 139 +--------- 9 files changed, 287 insertions(+), 438 deletions(-) diff --git a/app/admin/controller/Channel.php b/app/admin/controller/Channel.php index a7d4b68..250c624 100644 --- a/app/admin/controller/Channel.php +++ b/app/admin/controller/Channel.php @@ -59,58 +59,15 @@ class Channel extends Backend } $channels = $query->select()->toArray(); - $groupChildrenCache = []; - $getGroupChildren = function ($groupId) use (&$getGroupChildren, &$groupChildrenCache) { - if ($groupId === null || $groupId === '') return []; - if (array_key_exists($groupId, $groupChildrenCache)) return $groupChildrenCache[$groupId]; - $children = Db::name('admin_group') - ->where('pid', $groupId) - ->where('status', 1) - ->column('id'); - $all = []; - foreach ($children as $cid) { - $all[] = $cid; - foreach ($getGroupChildren($cid) as $cc) { - $all[] = $cc; - } - } - $groupChildrenCache[$groupId] = $all; - return $all; - }; - $tree = []; foreach ($channels as $ch) { $channelId = (int) ($ch['id'] ?? 0); - $rootGroupIds = Db::name('admin_group') + $admins = Db::name('admin') + ->field(['id', 'username']) ->where('channel_id', $channelId) - ->where('pid', 0) - ->where('status', 1) - ->column('id'); - $groupIds = []; - foreach ($rootGroupIds as $rootId) { - $groupIds[] = $rootId; - foreach ($getGroupChildren($rootId) as $gid) { - $groupIds[] = $gid; - } - } - - $adminIds = []; - if ($groupIds) { - $adminIds = Db::name('admin_group_access') - ->where('group_id', 'in', array_unique($groupIds)) - ->column('uid'); - } - $adminIds = array_values(array_unique($adminIds)); - - $admins = []; - if ($adminIds) { - $admins = Db::name('admin') - ->field(['id', 'username']) - ->where('id', 'in', $adminIds) - ->order('id', 'asc') - ->select() - ->toArray(); - } + ->order('id', 'asc') + ->select() + ->toArray(); $children = []; foreach ($admins as $a) { @@ -458,9 +415,27 @@ class Channel extends Backend if ($channelId <= 0 || $adminIds === []) { return []; } + $accessRows = Db::name('admin_group_access') + ->field(['uid', 'group_id']) + ->where('uid', 'in', $adminIds) + ->order('uid', 'asc') + ->order('group_id', 'asc') + ->select() + ->toArray(); + $groupIds = []; + foreach ($accessRows as $accessRow) { + $gid = (int) ($accessRow['group_id'] ?? 0); + if ($gid > 0) { + $groupIds[] = $gid; + } + } + $groupIds = array_values(array_unique($groupIds)); + if ($groupIds === []) { + return []; + } $groupRows = Db::name('admin_group') ->field(['id', 'pid', 'name']) - ->where('channel_id', $channelId) + ->where('id', 'in', $groupIds) ->order('id', 'asc') ->select() ->toArray(); @@ -501,13 +476,6 @@ class Channel extends Backend return $depth; }; - $accessRows = Db::name('admin_group_access') - ->field(['uid', 'group_id']) - ->where('uid', 'in', $adminIds) - ->order('uid', 'asc') - ->order('group_id', 'asc') - ->select() - ->toArray(); $metaMap = []; foreach ($accessRows as $accessRow) { $uid = (int) ($accessRow['uid'] ?? 0); diff --git a/app/admin/controller/auth/Admin.php b/app/admin/controller/auth/Admin.php index dee28fc..52f8c8e 100644 --- a/app/admin/controller/auth/Admin.php +++ b/app/admin/controller/auth/Admin.php @@ -21,7 +21,7 @@ class Admin extends Backend /** * 分红比例余量查询(表单提示用) */ - protected array $noNeedPermission = ['commissionShareRemainder', 'groupMeta']; + protected array $noNeedPermission = ['commissionShareRemainder', 'groupMeta', 'parentMeta']; protected ?object $model = null; @@ -114,10 +114,7 @@ class Admin extends Backend ->alias($alias) ->where($where); - $visibleIds = AdminCommissionDistributionService::getVisibleAdminIdsForOperator( - intval($this->auth->id), - $this->auth->isSuperAdmin() - ); + $visibleIds = $this->getVisibleAdminIdsForAdminModule(); if ($visibleIds !== []) { $query->where($adminAlias . '.id', 'in', $visibleIds); } @@ -226,7 +223,7 @@ class Admin extends Backend return $this->error(__('Invalid parameters')); } - $group = Db::name('admin_group')->where('id', $groupId)->field(['id', 'pid', 'channel_id'])->find(); + $group = Db::name('admin_group')->where('id', $groupId)->field(['id', 'pid'])->find(); if (!is_array($group)) { return $this->error(__('Record not found')); } @@ -243,7 +240,45 @@ class Admin extends Backend return $this->success('', [ 'is_top_level' => $pid === 0, 'pid' => $pid, - 'channel_id' => $group['channel_id'] ?? null, + ]); + } + + /** + * 上级代理渠道信息(子代理表单只读展示用) + */ + public function parentMeta(Request $request): Response + { + $response = $this->initializeBackend($request); + if ($response !== null) { + return $response; + } + + $parentId = intval($request->get('parent_admin_id', 0)); + if ($parentId <= 0) { + return $this->success('', [ + 'channel_id' => null, + 'channel_name' => '', + ]); + } + + if (!$this->canManageAdminId($parentId) && !$this->auth->isSuperAdmin()) { + return $this->error(__('You have no permission')); + } + + $parent = Db::name('admin')->where('id', $parentId)->field(['id', 'channel_id'])->find(); + if (!is_array($parent)) { + return $this->error(__('Invalid parent administrator')); + } + + $cid = $parent['channel_id'] ?? null; + $channelName = ''; + if ($cid !== null && $cid !== '') { + $channelName = (string) (Db::name('channel')->where('id', $cid)->value('name') ?? ''); + } + + return $this->success('', [ + 'channel_id' => $cid, + 'channel_name' => $channelName, ]); } @@ -300,26 +335,14 @@ class Admin extends Backend $passwd = $data['password'] ?? ''; $data = $this->excludeFields($data); - $creatorChannelId = $this->getCreatorChannelId(); - $groupChannelId = $this->resolveChannelIdFromPrimaryGroup($data['group_arr'] ?? []); if (!$this->auth->isSuperAdmin()) { + $creatorChannelId = $this->getCreatorChannelId(); if ($creatorChannelId === null || $creatorChannelId === '') { return $this->error(__('You have no permission')); } - if ($groupChannelId === null || $groupChannelId === '') { - return $this->error(__('Selected role group is not bound to a channel')); - } - if ((string) $groupChannelId !== (string) $creatorChannelId) { - return $this->error(__('Selected role group channel does not match current account')); - } $data['channel_id'] = $creatorChannelId; $data['parent_admin_id'] = $this->auth->id; - } else { - $postedChannel = $data['channel_id'] ?? null; - if ($postedChannel === null || $postedChannel === '') { - $data['channel_id'] = ($groupChannelId === null || $groupChannelId === '') ? null : $groupChannelId; - } } $parentErr = $this->normalizeParentAndShareFields($data, null, $data['group_arr'] ?? []); @@ -456,28 +479,13 @@ class Admin extends Backend $data = $this->excludeFields($data); unset($data['invite_code'], $data['group_arr'], $data['group_name_arr']); - if (!$isSelfEdit && $editGroupArr !== null) { - $creatorChannelId = $this->getCreatorChannelId(); - $groupChannelId = $this->resolveChannelIdFromPrimaryGroup($editGroupArr); - if (!$this->auth->isSuperAdmin()) { - if ($creatorChannelId === null || $creatorChannelId === '') { - return $this->error(__('You have no permission')); - } - if ($groupChannelId === null || $groupChannelId === '') { - return $this->error(__('Selected role group is not bound to a channel')); - } - if ((string) $groupChannelId !== (string) $creatorChannelId) { - return $this->error(__('Selected role group channel does not match current account')); - } - $data['channel_id'] = $creatorChannelId; - } else { - $data['channel_id'] = ($groupChannelId === null || $groupChannelId === '') ? null : $groupChannelId; - } - } - if (!$isSelfEdit) { if (!$this->auth->isSuperAdmin()) { - unset($data['parent_admin_id']); + unset($data['parent_admin_id'], $data['channel_id']); + $creatorChannelId = $this->getCreatorChannelId(); + if ($creatorChannelId !== null && $creatorChannelId !== '') { + $data['channel_id'] = $creatorChannelId; + } } $parentErr = $this->normalizeParentAndShareFields($data, intval($id), $editGroupArr ?? []); if ($parentErr !== null) { @@ -611,10 +619,7 @@ class Admin extends Backend ->alias($alias) ->where($where); - $visibleIds = AdminCommissionDistributionService::getVisibleAdminIdsForOperator( - intval($this->auth->id), - $this->auth->isSuperAdmin() - ); + $visibleIds = $this->getVisibleAdminIdsForAdminModule(); if ($visibleIds !== []) { $query->where($adminAlias . '.id', 'in', $visibleIds); } @@ -628,6 +633,42 @@ class Admin extends Backend return $rows; } + /** + * 非超管可见管理员:本人 + 代理树下级 + 角色组管理范围内(本人所在组及下级组)的全部成员。 + * + * @return int[] 空数组表示不限制(超管) + */ + private function getVisibleAdminIdsForAdminModule(): array + { + if ($this->auth->isSuperAdmin()) { + return []; + } + + $operatorId = intval($this->auth->id); + $ids = AdminCommissionDistributionService::getVisibleAdminIdsForOperator($operatorId, false); + + $groupIds = $this->getManageableGroupIds(); + if ($groupIds !== []) { + $groupAdminIds = Db::name('admin_group_access') + ->where('group_id', 'in', $groupIds) + ->column('uid'); + foreach ($groupAdminIds as $uid) { + $uidInt = intval($uid); + if ($uidInt > 0) { + $ids[] = $uidInt; + } + } + } + + if ($operatorId > 0) { + $ids[] = $operatorId; + } + + $ids = array_values(array_unique(array_filter($ids, static fn(int $id): bool => $id > 0))); + + return $ids === [] ? [0] : $ids; + } + private function checkGroupAuth(array $groups): ?Response { if ($this->auth->isSuperAdmin()) { @@ -665,22 +706,6 @@ class Admin extends Backend return null; } - /** - * @param array $groupIds - */ - private function resolveChannelIdFromPrimaryGroup(array $groupIds): mixed - { - if ($groupIds === []) { - return null; - } - $gid = $groupIds[0]; - if ($gid === null || $gid === '') { - return null; - } - - return Db::name('admin_group')->where('id', $gid)->value('channel_id'); - } - private function canManageAdminId(int $adminId): bool { if ($this->auth->isSuperAdmin()) { @@ -689,11 +714,7 @@ class Admin extends Backend if ($adminId === intval($this->auth->id)) { return true; } - $visible = AdminCommissionDistributionService::getVisibleAdminIdsForOperator( - intval($this->auth->id), - false - ); - return in_array($adminId, $visible, true); + return in_array($adminId, $this->getVisibleAdminIdsForAdminModule(), true); } /** @@ -721,14 +742,30 @@ class Admin extends Backend { if ($this->isPrimaryGroupTopLevel($groupIds)) { $data['parent_admin_id'] = null; - $channelId = $data['channel_id'] ?? null; - if ($channelId === null || $channelId === '') { - $channelId = $this->resolveChannelIdFromPrimaryGroup($groupIds); - if ($channelId !== null && $channelId !== '') { - $data['channel_id'] = $channelId; + if (!$this->auth->isSuperAdmin()) { + $mayAssignChannel = false; + foreach (['channel/index', 'channel/Index', 'Channel/index', 'Channel/Index'] as $routePath) { + if ($this->auth->check($routePath)) { + $mayAssignChannel = true; + break; + } + } + if (!$mayAssignChannel) { + unset($data['channel_id']); } } + $channelId = $data['channel_id'] ?? null; $channelIdInt = intval($channelId ?? 0); + if ($channelIdInt <= 0) { + $data['channel_id'] = null; + $data['commission_share_rate'] = null; + + return null; + } + $exists = Db::name('channel')->where('id', $channelIdInt)->value('id'); + if (!$exists) { + return (string) __('Record not found'); + } $shareErr = AdminCommissionDistributionService::validateChannelRootCommissionShareRate( $channelIdInt, $data['commission_share_rate'] ?? null, @@ -752,6 +789,18 @@ class Admin extends Backend if ($parentId <= 0) { $data['parent_admin_id'] = null; $data['commission_share_rate'] = null; + if (!$this->auth->isSuperAdmin()) { + $mayAssignChannel = false; + foreach (['channel/index', 'channel/Index', 'Channel/index', 'Channel/Index'] as $routePath) { + if ($this->auth->check($routePath)) { + $mayAssignChannel = true; + break; + } + } + if (!$mayAssignChannel) { + unset($data['channel_id']); + } + } return null; } @@ -768,12 +817,10 @@ class Admin extends Backend return (string) __('You have no permission'); } - $channelId = $data['channel_id'] ?? null; - if ($channelId !== null && $channelId !== '' && (string) ($parent['channel_id'] ?? '') !== (string) $channelId) { - return (string) __('Parent administrator must belong to the same channel'); - } - if (($channelId === null || $channelId === '') && !empty($parent['channel_id'])) { + if (!empty($parent['channel_id'])) { $data['channel_id'] = $parent['channel_id']; + } else { + $data['channel_id'] = null; } $shareErr = AdminCommissionDistributionService::validateCommissionShareRate( @@ -893,4 +940,47 @@ class Admin extends Backend { return is_array($groups) && count($groups) === 1; } + + /** + * 兼容旧 worker 内存中仍调用本方法的 add/edit;新逻辑在 normalizeParentAndShareFields。 + * + * @param array $data + * @param array $groupIds + */ + private function applyTopLevelChannelFromOperator(array &$data, array $groupIds): ?string + { + if (!$this->isPrimaryGroupTopLevel($groupIds)) { + return null; + } + $parentId = isset($data['parent_admin_id']) && $data['parent_admin_id'] !== '' && $data['parent_admin_id'] !== null + ? intval($data['parent_admin_id']) + : 0; + if ($parentId > 0) { + return null; + } + if (!$this->auth->isSuperAdmin()) { + $mayAssignChannel = false; + foreach (['channel/index', 'channel/Index', 'Channel/index', 'Channel/Index'] as $routePath) { + if ($this->auth->check($routePath)) { + $mayAssignChannel = true; + break; + } + } + if (!$mayAssignChannel) { + unset($data['channel_id']); + } + } + $cid = $data['channel_id'] ?? null; + if ($cid === null || $cid === '') { + $data['channel_id'] = null; + + return null; + } + $exists = Db::name('channel')->where('id', $cid)->value('id'); + if (!$exists) { + return (string) __('Record not found'); + } + + return null; + } } diff --git a/app/admin/controller/auth/Group.php b/app/admin/controller/auth/Group.php index 1e7f023..b1b0c04 100644 --- a/app/admin/controller/auth/Group.php +++ b/app/admin/controller/auth/Group.php @@ -91,10 +91,7 @@ class Group extends Backend if (!$this->auth->isSuperAdmin() && $pidInt !== 0 && !in_array($pidInt, $this->manageableGroupIds, true)) { return $this->error(__('You have no permission')); } - $inheritRes = $this->applyChannelInheritance($data, $pidInt); - if ($inheritRes !== null) { - return $inheritRes; - } + unset($data['channel_id']); $rulesRes = $this->handleRules($data, $pidInt); if ($rulesRes instanceof Response) return $rulesRes; @@ -162,10 +159,7 @@ class Group extends Backend if (!$this->auth->isSuperAdmin() && $pidInt !== 0 && !in_array($pidInt, $this->manageableGroupIds, true)) { return $this->error(__('You have no permission')); } - $inheritRes = $this->applyChannelInheritance($data, $pidInt); - if ($inheritRes !== null) { - return $inheritRes; - } + unset($data['channel_id']); $rulesRes = $this->handleRules($data, $pidInt); if ($rulesRes instanceof Response) return $rulesRes; @@ -193,7 +187,6 @@ class Group extends Backend return $this->error($e->getMessage()); } if ($result !== false) { - $this->syncDescendantChannelIds(intval((string)$row['id'])); return $this->success(__('Update successful')); } return $this->error(__('No rows updated')); @@ -213,39 +206,11 @@ class Group extends Backend } $rowData = $row->toArray(); $rowData['rules'] = array_values($rules); - $rowData = $this->enrichChannelDisplay($rowData); return $this->success('', [ 'row' => $rowData ]); } - /** - * 表单只读展示:根据 channel_id 解析渠道名称与渠道负责人(admin.channel_id → admin.username,取首个) - */ - public function channelBindPreview(Request $request): Response - { - $response = $this->initializeBackend($request); - if ($response !== null) { - return $response; - } - $cid = $request->get('channel_id') ?? $request->post('channel_id'); - if ($cid === null || $cid === '') { - return $this->success('', [ - 'channel_name' => '', - 'channel_admin_username' => '', - ]); - } - if (!Db::name('channel')->where('id', $cid)->value('id')) { - return $this->error(__('Record not found')); - } - $row = $this->enrichChannelDisplay(['channel_id' => $cid]); - - return $this->success('', [ - 'channel_name' => $row['channel_name'] ?? '', - 'channel_admin_username' => $row['channel_admin_username'] ?? '', - ]); - } - public function del(Request $request): Response { $response = $this->initializeBackend($request); @@ -413,21 +378,7 @@ class Group extends Backend } $data = $this->model->where($where)->select()->toArray(); - $channelIds = []; - foreach ($data as $datum) { - $c = $datum['channel_id'] ?? null; - if ($c !== null && $c !== '') { - $channelIds[] = $c; - } - } - $channelNames = []; - if ($channelIds !== []) { - $channelNames = Db::name('channel')->where('id', 'in', array_unique($channelIds))->column('name', 'id'); - } - foreach ($data as &$datum) { - $c = $datum['channel_id'] ?? null; - $datum['channel_name'] = ($c !== null && $c !== '') ? ($channelNames[$c] ?? '') : ''; if ($datum['rules']) { if ($datum['rules'] == '*') { $datum['rules'] = __('Super administrator'); @@ -466,87 +417,6 @@ class Group extends Backend return array_values(array_unique(array_merge($own, $children))); } - /** - * 顶级角色组可选渠道;子级继承父级 channel_id(不信任客户端提交的子级 channel_id)。 - * - * @param array $data - */ - private function applyChannelInheritance(array &$data, int $pidInt): ?Response - { - if ($pidInt === 0) { - if (!$this->auth->isSuperAdmin()) { - unset($data['channel_id']); - $cc = $this->getCreatorChannelId(); - if ($cc !== null && $cc !== '') { - $data['channel_id'] = $cc; - } - } - $cid = $data['channel_id'] ?? null; - if ($cid !== null && $cid !== '') { - $exists = Db::name('channel')->where('id', $cid)->value('id'); - if (!$exists) { - return $this->error(__('Record not found')); - } - } - - return null; - } - - unset($data['channel_id']); - $parent = Db::name('admin_group')->where('id', $pidInt)->find(); - if (!$parent) { - return $this->error(__('Record not found')); - } - $data['channel_id'] = $parent['channel_id']; - - return null; - } - - /** - * @param array $row - * @return array - */ - private function enrichChannelDisplay(array $row): array - { - $row['channel_name'] = ''; - $row['channel_admin_username'] = ''; - $cid = $row['channel_id'] ?? null; - if ($cid === null || $cid === '') { - return $row; - } - $ch = Db::name('channel')->where('id', $cid)->field(['id', 'name'])->find(); - if (!$ch) { - return $row; - } - $row['channel_name'] = $ch['name'] ?? ''; - $row['channel_admin_username'] = (string) (Db::name('admin')->where('channel_id', $cid)->order('id', 'asc')->value('username') ?? ''); - - return $row; - } - - private function syncDescendantChannelIds(int $groupId): void - { - $channelId = Db::name('admin_group')->where('id', $groupId)->value('channel_id'); - $children = Db::name('admin_group')->where('pid', $groupId)->column('id'); - foreach ($children as $childId) { - Db::name('admin_group')->where('id', $childId)->update(['channel_id' => $channelId]); - $this->syncDescendantChannelIds($childId); - } - } - - private function getCreatorChannelId(): mixed - { - $currentAdmin = Db::name('admin') - ->field(['id', 'channel_id']) - ->where('id', $this->auth->id) - ->find(); - if ($currentAdmin && !empty($currentAdmin['channel_id'])) { - return $currentAdmin['channel_id']; - } - - return null; - } - private function canManageRoleGroups(): bool { foreach (['auth/group/index', 'auth/group/add', 'auth/group/edit', 'auth/Group/index', 'auth/Group/add', 'auth/Group/edit'] as $routePath) { diff --git a/config/process.php b/config/process.php index 02fd379..d224792 100644 --- a/config/process.php +++ b/config/process.php @@ -91,7 +91,8 @@ return [ 'php', 'html', 'htm', 'env' ], 'options' => [ - 'enable_file_monitor' => !in_array('-d', $argv) && DIRECTORY_SEPARATOR === '/', + // Windows 下也需监测 PHP 变更并 reload,否则长期占用旧版 Admin 等类 + 'enable_file_monitor' => !in_array('-d', $argv), 'enable_memory_monitor' => DIRECTORY_SEPARATOR === '/', ] ] diff --git a/web/src/lang/backend/en/auth/admin.ts b/web/src/lang/backend/en/auth/admin.ts index 402213d..fe1f909 100644 --- a/web/src/lang/backend/en/auth/admin.ts +++ b/web/src/lang/backend/en/auth/admin.ts @@ -3,6 +3,7 @@ export default { nickname: 'Nickname', group: 'Group', channel: 'Channel', + channel_inherit_from_parent: 'Channel is inherited from the selected parent agent and cannot be changed separately.', parent_admin: 'Parent agent', commission_share_rate: 'Commission share (%)', avatar: 'Avatar', @@ -16,7 +17,7 @@ export default { 'Personal signature': 'Personal Signature', 'Administrator login': 'Administrator Login Name', 'Manage subordinate agents here': - 'Manage your subordinate agents here. You can only see yourself and your downline, not sub-agents under other agents.', + 'Manage administrators within your role-group scope (all accounts in your groups and child groups, plus agents in your downline).', 'Parent admin placeholder': 'Leave empty for top-level channel agent', 'Top level group parent hint': 'The selected role group is top-level; no parent agent is required. Settlement uses the channel commission share configured here.', diff --git a/web/src/lang/backend/zh-cn/auth/admin.ts b/web/src/lang/backend/zh-cn/auth/admin.ts index 86020e0..9c5e927 100644 --- a/web/src/lang/backend/zh-cn/auth/admin.ts +++ b/web/src/lang/backend/zh-cn/auth/admin.ts @@ -3,6 +3,7 @@ export default { nickname: '昵称', group: '角色组', channel: '渠道', + channel_inherit_from_parent: '渠道继承自所选上级代理,不可单独修改', parent_admin: '上级代理', commission_share_rate: '分红比例(%)', avatar: '头像', @@ -15,7 +16,8 @@ export default { 'Please leave blank if not modified': '不修改请留空', 'Personal signature': '个性签名', 'Administrator login': '管理员登录名', - 'Manage subordinate agents here': '在此管理您下级代理管理员;仅显示您本人及所有下级,无法查看其他代理线下的子代理。', + 'Manage subordinate agents here': + '在此管理您角色组管理范围内的管理员(本人所在角色组及其下级组内的全部账号,并含您代理线下的下级)。', 'Parent admin placeholder': '留空表示渠道顶级代理', 'Top level group parent hint': '当前角色组为顶级角色组,无需绑定上级代理;系统将按渠道分红比例直接结算至该管理员。', 'Top level share formula hint': diff --git a/web/src/views/backend/auth/admin/popupForm.vue b/web/src/views/backend/auth/admin/popupForm.vue index f4cc515..47b79f3 100644 --- a/web/src/views/backend/auth/admin/popupForm.vue +++ b/web/src/views/backend/auth/admin/popupForm.vue @@ -41,7 +41,7 @@ :placeholder="t('Please input field', { field: t('auth.admin.nickname') })" /> + + + + + + baTable.form.operate === 'Edit' && adminInfo.id == baTable.form.items?.id) -const showChannelField = computed(() => adminInfo.super && !isSelfEdit.value) +const hasChannelIndexAuth = computed( + () => + adminInfo.super || + auth({ name: '/admin/channel', subNodeName: '/admin/channel/index' }) || + auth({ name: '/admin/Channel', subNodeName: '/admin/Channel/index' }) +) + +const hasParentAdmin = computed(() => { + const pid = baTable.form.items?.parent_admin_id + return pid !== null && pid !== undefined && pid !== '' && Number(pid) > 0 +}) + +const showChannelEditable = computed( + () => hasChannelIndexAuth.value && isTopLevelGroup.value && !hasParentAdmin.value && !isSelfEdit.value +) + +const channelDisplayName = computed(() => { + const row = baTable.form.items + if (!row) return '' + const name = row['channel_name'] + if (typeof name === 'string' && name !== '') { + return name + } + return '' +}) + +const showChannelReadonly = computed(() => { + if (isSelfEdit.value) return false + if (showChannelEditable.value) return false + if (hasParentAdmin.value) return true + if (!isTopLevelGroup.value && hasChannelForShare.value) return true + return channelDisplayName.value !== '' +}) const showParentField = computed(() => adminInfo.super && !isSelfEdit.value) +const hasChannelForShare = computed(() => { + const cid = baTable.form.items?.channel_id + return cid !== null && cid !== undefined && cid !== '' && Number(cid) > 0 +}) + const showShareRateField = computed(() => { if (isSelfEdit.value) return false if (isTopLevelGroup.value) { - return adminInfo.super || baTable.form.operate === 'Add' + if (!hasChannelForShare.value) return false + return hasChannelIndexAuth.value || baTable.form.operate === 'Add' } if (adminInfo.super) { const pid = baTable.form.items?.parent_admin_id @@ -273,24 +318,40 @@ const loadGroupMeta = async (groupId: unknown) => { isTopLevelGroup.value = !!res.data.is_top_level if (isTopLevelGroup.value && baTable.form.items) { baTable.form.items.parent_admin_id = null - const metaChannelId = res.data.channel_id - if ( - adminInfo.super && - (baTable.form.items.channel_id === null || - baTable.form.items.channel_id === undefined || - baTable.form.items.channel_id === '') && - metaChannelId !== null && - metaChannelId !== undefined && - metaChannelId !== '' - ) { - baTable.form.items.channel_id = metaChannelId - } } } catch { isTopLevelGroup.value = false } } +const loadParentChannelMeta = async (parentId: unknown) => { + const items = baTable.form.items + if (!items) return + if (parentId === null || parentId === undefined || parentId === '' || Number(parentId) <= 0) { + if (!isTopLevelGroup.value) { + items['channel_name'] = '' + } + return + } + try { + const res = await createAxios({ + url: '/admin/auth.Admin/parentMeta', + method: 'get', + params: { parent_admin_id: parentId }, + }) + const cid = res.data.channel_id + const cname = res.data.channel_name + if (cid !== null && cid !== undefined && cid !== '') { + items.channel_id = cid + } else { + items.channel_id = null + } + items['channel_name'] = typeof cname === 'string' ? cname : '' + } catch { + items['channel_name'] = '' + } +} + const loadShareRemainder = async () => { if (!showShareRateField.value) { shareHint.value = '' @@ -380,6 +441,15 @@ watch( { immediate: true } ) +watch( + () => baTable.form.items?.parent_admin_id, + (parentId) => { + if (isTopLevelGroup.value) return + void loadParentChannelMeta(parentId) + }, + { immediate: true } +) + watch( () => [ baTable.form.items?.parent_admin_id, diff --git a/web/src/views/backend/auth/group/index.vue b/web/src/views/backend/auth/group/index.vue index 137ce79..7955c64 100644 --- a/web/src/views/backend/auth/group/index.vue +++ b/web/src/views/backend/auth/group/index.vue @@ -60,12 +60,6 @@ const baTable: baTableClass = new baTableClass( align: 'left', minWidth: '180', }, - { - label: t('auth.group.channel_name'), - prop: 'channel_name', - align: 'center', - minWidth: '140', - }, { label: t('auth.group.jurisdiction'), prop: 'rules', align: 'center' }, { label: t('State'), @@ -91,7 +85,6 @@ const baTable: baTableClass = new baTableClass( { defaultItems: { status: 1, - channel_id: null, }, } ) @@ -101,14 +94,9 @@ baTable.before.onSubmit = ({ formEl, operate, items }) => { let submitCallback = () => { baTable.form.submitLoading = true const postItems: anyObj = { ...items } - const pid = Number(postItems.pid ?? 0) - if (pid !== 0) { - delete postItems.channel_id - delete postItems.channel_name - delete postItems.channel_admin_username - } else if (!adminInfo.super) { - delete postItems.channel_id - } + delete postItems.channel_id + delete postItems.channel_name + delete postItems.channel_admin_username baTable.api .postData(operate, { ...postItems, @@ -168,10 +156,6 @@ baTable.after.toggleForm = ({ operate }) => { // 编辑请求完成后钩子 baTable.after.getEditData = () => { - const pid = Number(baTable.form.items?.pid ?? 0) - if (pid !== 0 && baTable.form.items) { - delete baTable.form.items.channel_id - } menuRuleTreeUpdate() } diff --git a/web/src/views/backend/auth/group/popupForm.vue b/web/src/views/backend/auth/group/popupForm.vue index 15d1e7a..36cf8ae 100644 --- a/web/src/views/backend/auth/group/popupForm.vue +++ b/web/src/views/backend/auth/group/popupForm.vue @@ -41,43 +41,6 @@ valueOnClear: 0, }" /> -

- {{ t('auth.group.channel_inherit_hint') }} -

- - - - - - - -