1.优化后台管理员管理页面的权限设置,新增zihuaadmin账号
This commit is contained in:
@@ -59,58 +59,15 @@ class Channel extends Backend
|
|||||||
}
|
}
|
||||||
$channels = $query->select()->toArray();
|
$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 = [];
|
$tree = [];
|
||||||
foreach ($channels as $ch) {
|
foreach ($channels as $ch) {
|
||||||
$channelId = (int) ($ch['id'] ?? 0);
|
$channelId = (int) ($ch['id'] ?? 0);
|
||||||
$rootGroupIds = Db::name('admin_group')
|
$admins = Db::name('admin')
|
||||||
|
->field(['id', 'username'])
|
||||||
->where('channel_id', $channelId)
|
->where('channel_id', $channelId)
|
||||||
->where('pid', 0)
|
->order('id', 'asc')
|
||||||
->where('status', 1)
|
->select()
|
||||||
->column('id');
|
->toArray();
|
||||||
$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();
|
|
||||||
}
|
|
||||||
|
|
||||||
$children = [];
|
$children = [];
|
||||||
foreach ($admins as $a) {
|
foreach ($admins as $a) {
|
||||||
@@ -458,9 +415,27 @@ class Channel extends Backend
|
|||||||
if ($channelId <= 0 || $adminIds === []) {
|
if ($channelId <= 0 || $adminIds === []) {
|
||||||
return [];
|
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')
|
$groupRows = Db::name('admin_group')
|
||||||
->field(['id', 'pid', 'name'])
|
->field(['id', 'pid', 'name'])
|
||||||
->where('channel_id', $channelId)
|
->where('id', 'in', $groupIds)
|
||||||
->order('id', 'asc')
|
->order('id', 'asc')
|
||||||
->select()
|
->select()
|
||||||
->toArray();
|
->toArray();
|
||||||
@@ -501,13 +476,6 @@ class Channel extends Backend
|
|||||||
return $depth;
|
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 = [];
|
$metaMap = [];
|
||||||
foreach ($accessRows as $accessRow) {
|
foreach ($accessRows as $accessRow) {
|
||||||
$uid = (int) ($accessRow['uid'] ?? 0);
|
$uid = (int) ($accessRow['uid'] ?? 0);
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ class Admin extends Backend
|
|||||||
/**
|
/**
|
||||||
* 分红比例余量查询(表单提示用)
|
* 分红比例余量查询(表单提示用)
|
||||||
*/
|
*/
|
||||||
protected array $noNeedPermission = ['commissionShareRemainder', 'groupMeta'];
|
protected array $noNeedPermission = ['commissionShareRemainder', 'groupMeta', 'parentMeta'];
|
||||||
|
|
||||||
protected ?object $model = null;
|
protected ?object $model = null;
|
||||||
|
|
||||||
@@ -114,10 +114,7 @@ class Admin extends Backend
|
|||||||
->alias($alias)
|
->alias($alias)
|
||||||
->where($where);
|
->where($where);
|
||||||
|
|
||||||
$visibleIds = AdminCommissionDistributionService::getVisibleAdminIdsForOperator(
|
$visibleIds = $this->getVisibleAdminIdsForAdminModule();
|
||||||
intval($this->auth->id),
|
|
||||||
$this->auth->isSuperAdmin()
|
|
||||||
);
|
|
||||||
if ($visibleIds !== []) {
|
if ($visibleIds !== []) {
|
||||||
$query->where($adminAlias . '.id', 'in', $visibleIds);
|
$query->where($adminAlias . '.id', 'in', $visibleIds);
|
||||||
}
|
}
|
||||||
@@ -226,7 +223,7 @@ class Admin extends Backend
|
|||||||
return $this->error(__('Invalid parameters'));
|
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)) {
|
if (!is_array($group)) {
|
||||||
return $this->error(__('Record not found'));
|
return $this->error(__('Record not found'));
|
||||||
}
|
}
|
||||||
@@ -243,7 +240,45 @@ class Admin extends Backend
|
|||||||
return $this->success('', [
|
return $this->success('', [
|
||||||
'is_top_level' => $pid === 0,
|
'is_top_level' => $pid === 0,
|
||||||
'pid' => $pid,
|
'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'] ?? '';
|
$passwd = $data['password'] ?? '';
|
||||||
$data = $this->excludeFields($data);
|
$data = $this->excludeFields($data);
|
||||||
$creatorChannelId = $this->getCreatorChannelId();
|
|
||||||
$groupChannelId = $this->resolveChannelIdFromPrimaryGroup($data['group_arr'] ?? []);
|
|
||||||
|
|
||||||
if (!$this->auth->isSuperAdmin()) {
|
if (!$this->auth->isSuperAdmin()) {
|
||||||
|
$creatorChannelId = $this->getCreatorChannelId();
|
||||||
if ($creatorChannelId === null || $creatorChannelId === '') {
|
if ($creatorChannelId === null || $creatorChannelId === '') {
|
||||||
return $this->error(__('You have no permission'));
|
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['channel_id'] = $creatorChannelId;
|
||||||
$data['parent_admin_id'] = $this->auth->id;
|
$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'] ?? []);
|
$parentErr = $this->normalizeParentAndShareFields($data, null, $data['group_arr'] ?? []);
|
||||||
@@ -456,28 +479,13 @@ class Admin extends Backend
|
|||||||
|
|
||||||
$data = $this->excludeFields($data);
|
$data = $this->excludeFields($data);
|
||||||
unset($data['invite_code'], $data['group_arr'], $data['group_name_arr']);
|
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 (!$isSelfEdit) {
|
||||||
if (!$this->auth->isSuperAdmin()) {
|
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 ?? []);
|
$parentErr = $this->normalizeParentAndShareFields($data, intval($id), $editGroupArr ?? []);
|
||||||
if ($parentErr !== null) {
|
if ($parentErr !== null) {
|
||||||
@@ -611,10 +619,7 @@ class Admin extends Backend
|
|||||||
->alias($alias)
|
->alias($alias)
|
||||||
->where($where);
|
->where($where);
|
||||||
|
|
||||||
$visibleIds = AdminCommissionDistributionService::getVisibleAdminIdsForOperator(
|
$visibleIds = $this->getVisibleAdminIdsForAdminModule();
|
||||||
intval($this->auth->id),
|
|
||||||
$this->auth->isSuperAdmin()
|
|
||||||
);
|
|
||||||
if ($visibleIds !== []) {
|
if ($visibleIds !== []) {
|
||||||
$query->where($adminAlias . '.id', 'in', $visibleIds);
|
$query->where($adminAlias . '.id', 'in', $visibleIds);
|
||||||
}
|
}
|
||||||
@@ -628,6 +633,42 @@ class Admin extends Backend
|
|||||||
return $rows;
|
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
|
private function checkGroupAuth(array $groups): ?Response
|
||||||
{
|
{
|
||||||
if ($this->auth->isSuperAdmin()) {
|
if ($this->auth->isSuperAdmin()) {
|
||||||
@@ -665,22 +706,6 @@ class Admin extends Backend
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param array<int|string> $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
|
private function canManageAdminId(int $adminId): bool
|
||||||
{
|
{
|
||||||
if ($this->auth->isSuperAdmin()) {
|
if ($this->auth->isSuperAdmin()) {
|
||||||
@@ -689,11 +714,7 @@ class Admin extends Backend
|
|||||||
if ($adminId === intval($this->auth->id)) {
|
if ($adminId === intval($this->auth->id)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
$visible = AdminCommissionDistributionService::getVisibleAdminIdsForOperator(
|
return in_array($adminId, $this->getVisibleAdminIdsForAdminModule(), true);
|
||||||
intval($this->auth->id),
|
|
||||||
false
|
|
||||||
);
|
|
||||||
return in_array($adminId, $visible, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -721,14 +742,30 @@ class Admin extends Backend
|
|||||||
{
|
{
|
||||||
if ($this->isPrimaryGroupTopLevel($groupIds)) {
|
if ($this->isPrimaryGroupTopLevel($groupIds)) {
|
||||||
$data['parent_admin_id'] = null;
|
$data['parent_admin_id'] = null;
|
||||||
$channelId = $data['channel_id'] ?? null;
|
if (!$this->auth->isSuperAdmin()) {
|
||||||
if ($channelId === null || $channelId === '') {
|
$mayAssignChannel = false;
|
||||||
$channelId = $this->resolveChannelIdFromPrimaryGroup($groupIds);
|
foreach (['channel/index', 'channel/Index', 'Channel/index', 'Channel/Index'] as $routePath) {
|
||||||
if ($channelId !== null && $channelId !== '') {
|
if ($this->auth->check($routePath)) {
|
||||||
$data['channel_id'] = $channelId;
|
$mayAssignChannel = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!$mayAssignChannel) {
|
||||||
|
unset($data['channel_id']);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
$channelId = $data['channel_id'] ?? null;
|
||||||
$channelIdInt = intval($channelId ?? 0);
|
$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(
|
$shareErr = AdminCommissionDistributionService::validateChannelRootCommissionShareRate(
|
||||||
$channelIdInt,
|
$channelIdInt,
|
||||||
$data['commission_share_rate'] ?? null,
|
$data['commission_share_rate'] ?? null,
|
||||||
@@ -752,6 +789,18 @@ class Admin extends Backend
|
|||||||
if ($parentId <= 0) {
|
if ($parentId <= 0) {
|
||||||
$data['parent_admin_id'] = null;
|
$data['parent_admin_id'] = null;
|
||||||
$data['commission_share_rate'] = 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;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -768,12 +817,10 @@ class Admin extends Backend
|
|||||||
return (string) __('You have no permission');
|
return (string) __('You have no permission');
|
||||||
}
|
}
|
||||||
|
|
||||||
$channelId = $data['channel_id'] ?? null;
|
if (!empty($parent['channel_id'])) {
|
||||||
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'])) {
|
|
||||||
$data['channel_id'] = $parent['channel_id'];
|
$data['channel_id'] = $parent['channel_id'];
|
||||||
|
} else {
|
||||||
|
$data['channel_id'] = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
$shareErr = AdminCommissionDistributionService::validateCommissionShareRate(
|
$shareErr = AdminCommissionDistributionService::validateCommissionShareRate(
|
||||||
@@ -893,4 +940,47 @@ class Admin extends Backend
|
|||||||
{
|
{
|
||||||
return is_array($groups) && count($groups) === 1;
|
return is_array($groups) && count($groups) === 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 兼容旧 worker 内存中仍调用本方法的 add/edit;新逻辑在 normalizeParentAndShareFields。
|
||||||
|
*
|
||||||
|
* @param array<string, mixed> $data
|
||||||
|
* @param array<int|string> $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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -91,10 +91,7 @@ class Group extends Backend
|
|||||||
if (!$this->auth->isSuperAdmin() && $pidInt !== 0 && !in_array($pidInt, $this->manageableGroupIds, true)) {
|
if (!$this->auth->isSuperAdmin() && $pidInt !== 0 && !in_array($pidInt, $this->manageableGroupIds, true)) {
|
||||||
return $this->error(__('You have no permission'));
|
return $this->error(__('You have no permission'));
|
||||||
}
|
}
|
||||||
$inheritRes = $this->applyChannelInheritance($data, $pidInt);
|
unset($data['channel_id']);
|
||||||
if ($inheritRes !== null) {
|
|
||||||
return $inheritRes;
|
|
||||||
}
|
|
||||||
$rulesRes = $this->handleRules($data, $pidInt);
|
$rulesRes = $this->handleRules($data, $pidInt);
|
||||||
if ($rulesRes instanceof Response) return $rulesRes;
|
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)) {
|
if (!$this->auth->isSuperAdmin() && $pidInt !== 0 && !in_array($pidInt, $this->manageableGroupIds, true)) {
|
||||||
return $this->error(__('You have no permission'));
|
return $this->error(__('You have no permission'));
|
||||||
}
|
}
|
||||||
$inheritRes = $this->applyChannelInheritance($data, $pidInt);
|
unset($data['channel_id']);
|
||||||
if ($inheritRes !== null) {
|
|
||||||
return $inheritRes;
|
|
||||||
}
|
|
||||||
$rulesRes = $this->handleRules($data, $pidInt);
|
$rulesRes = $this->handleRules($data, $pidInt);
|
||||||
if ($rulesRes instanceof Response) return $rulesRes;
|
if ($rulesRes instanceof Response) return $rulesRes;
|
||||||
|
|
||||||
@@ -193,7 +187,6 @@ class Group extends Backend
|
|||||||
return $this->error($e->getMessage());
|
return $this->error($e->getMessage());
|
||||||
}
|
}
|
||||||
if ($result !== false) {
|
if ($result !== false) {
|
||||||
$this->syncDescendantChannelIds(intval((string)$row['id']));
|
|
||||||
return $this->success(__('Update successful'));
|
return $this->success(__('Update successful'));
|
||||||
}
|
}
|
||||||
return $this->error(__('No rows updated'));
|
return $this->error(__('No rows updated'));
|
||||||
@@ -213,39 +206,11 @@ class Group extends Backend
|
|||||||
}
|
}
|
||||||
$rowData = $row->toArray();
|
$rowData = $row->toArray();
|
||||||
$rowData['rules'] = array_values($rules);
|
$rowData['rules'] = array_values($rules);
|
||||||
$rowData = $this->enrichChannelDisplay($rowData);
|
|
||||||
return $this->success('', [
|
return $this->success('', [
|
||||||
'row' => $rowData
|
'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
|
public function del(Request $request): Response
|
||||||
{
|
{
|
||||||
$response = $this->initializeBackend($request);
|
$response = $this->initializeBackend($request);
|
||||||
@@ -413,21 +378,7 @@ class Group extends Backend
|
|||||||
}
|
}
|
||||||
$data = $this->model->where($where)->select()->toArray();
|
$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) {
|
foreach ($data as &$datum) {
|
||||||
$c = $datum['channel_id'] ?? null;
|
|
||||||
$datum['channel_name'] = ($c !== null && $c !== '') ? ($channelNames[$c] ?? '') : '';
|
|
||||||
if ($datum['rules']) {
|
if ($datum['rules']) {
|
||||||
if ($datum['rules'] == '*') {
|
if ($datum['rules'] == '*') {
|
||||||
$datum['rules'] = __('Super administrator');
|
$datum['rules'] = __('Super administrator');
|
||||||
@@ -466,87 +417,6 @@ class Group extends Backend
|
|||||||
return array_values(array_unique(array_merge($own, $children)));
|
return array_values(array_unique(array_merge($own, $children)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 顶级角色组可选渠道;子级继承父级 channel_id(不信任客户端提交的子级 channel_id)。
|
|
||||||
*
|
|
||||||
* @param array<string, mixed> $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<string, mixed> $row
|
|
||||||
* @return array<string, mixed>
|
|
||||||
*/
|
|
||||||
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
|
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) {
|
foreach (['auth/group/index', 'auth/group/add', 'auth/group/edit', 'auth/Group/index', 'auth/Group/add', 'auth/Group/edit'] as $routePath) {
|
||||||
|
|||||||
@@ -91,7 +91,8 @@ return [
|
|||||||
'php', 'html', 'htm', 'env'
|
'php', 'html', 'htm', 'env'
|
||||||
],
|
],
|
||||||
'options' => [
|
'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 === '/',
|
'enable_memory_monitor' => DIRECTORY_SEPARATOR === '/',
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ export default {
|
|||||||
nickname: 'Nickname',
|
nickname: 'Nickname',
|
||||||
group: 'Group',
|
group: 'Group',
|
||||||
channel: 'Channel',
|
channel: 'Channel',
|
||||||
|
channel_inherit_from_parent: 'Channel is inherited from the selected parent agent and cannot be changed separately.',
|
||||||
parent_admin: 'Parent agent',
|
parent_admin: 'Parent agent',
|
||||||
commission_share_rate: 'Commission share (%)',
|
commission_share_rate: 'Commission share (%)',
|
||||||
avatar: 'Avatar',
|
avatar: 'Avatar',
|
||||||
@@ -16,7 +17,7 @@ export default {
|
|||||||
'Personal signature': 'Personal Signature',
|
'Personal signature': 'Personal Signature',
|
||||||
'Administrator login': 'Administrator Login Name',
|
'Administrator login': 'Administrator Login Name',
|
||||||
'Manage subordinate agents here':
|
'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',
|
'Parent admin placeholder': 'Leave empty for top-level channel agent',
|
||||||
'Top level group parent hint':
|
'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.',
|
'The selected role group is top-level; no parent agent is required. Settlement uses the channel commission share configured here.',
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ export default {
|
|||||||
nickname: '昵称',
|
nickname: '昵称',
|
||||||
group: '角色组',
|
group: '角色组',
|
||||||
channel: '渠道',
|
channel: '渠道',
|
||||||
|
channel_inherit_from_parent: '渠道继承自所选上级代理,不可单独修改',
|
||||||
parent_admin: '上级代理',
|
parent_admin: '上级代理',
|
||||||
commission_share_rate: '分红比例(%)',
|
commission_share_rate: '分红比例(%)',
|
||||||
avatar: '头像',
|
avatar: '头像',
|
||||||
@@ -15,7 +16,8 @@ export default {
|
|||||||
'Please leave blank if not modified': '不修改请留空',
|
'Please leave blank if not modified': '不修改请留空',
|
||||||
'Personal signature': '个性签名',
|
'Personal signature': '个性签名',
|
||||||
'Administrator login': '管理员登录名',
|
'Administrator login': '管理员登录名',
|
||||||
'Manage subordinate agents here': '在此管理您下级代理管理员;仅显示您本人及所有下级,无法查看其他代理线下的子代理。',
|
'Manage subordinate agents here':
|
||||||
|
'在此管理您角色组管理范围内的管理员(本人所在角色组及其下级组内的全部账号,并含您代理线下的下级)。',
|
||||||
'Parent admin placeholder': '留空表示渠道顶级代理',
|
'Parent admin placeholder': '留空表示渠道顶级代理',
|
||||||
'Top level group parent hint': '当前角色组为顶级角色组,无需绑定上级代理;系统将按渠道分红比例直接结算至该管理员。',
|
'Top level group parent hint': '当前角色组为顶级角色组,无需绑定上级代理;系统将按渠道分红比例直接结算至该管理员。',
|
||||||
'Top level share formula hint':
|
'Top level share formula hint':
|
||||||
|
|||||||
@@ -41,7 +41,7 @@
|
|||||||
:placeholder="t('Please input field', { field: t('auth.admin.nickname') })"
|
:placeholder="t('Please input field', { field: t('auth.admin.nickname') })"
|
||||||
/>
|
/>
|
||||||
<FormItem
|
<FormItem
|
||||||
v-if="showChannelField"
|
v-if="showChannelEditable"
|
||||||
:label="t('auth.admin.channel')"
|
:label="t('auth.admin.channel')"
|
||||||
v-model="baTable.form.items!.channel_id"
|
v-model="baTable.form.items!.channel_id"
|
||||||
type="remoteSelect"
|
type="remoteSelect"
|
||||||
@@ -53,6 +53,12 @@
|
|||||||
placeholder: t('Click select'),
|
placeholder: t('Click select'),
|
||||||
}"
|
}"
|
||||||
/>
|
/>
|
||||||
|
<el-form-item v-else-if="showChannelReadonly" :label="t('auth.admin.channel')">
|
||||||
|
<el-input :model-value="channelDisplayName" readonly />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item v-if="showChannelReadonly && hasParentAdmin" label=" ">
|
||||||
|
<el-alert :title="t('auth.admin.channel_inherit_from_parent')" type="info" :closable="false" show-icon />
|
||||||
|
</el-form-item>
|
||||||
<FormItem
|
<FormItem
|
||||||
:label="t('auth.admin.group')"
|
:label="t('auth.admin.group')"
|
||||||
v-model="singleGroupValue"
|
v-model="singleGroupValue"
|
||||||
@@ -184,6 +190,7 @@ import FormItem from '/@/components/formItem/index.vue'
|
|||||||
import { useAdminInfo } from '/@/stores/adminInfo'
|
import { useAdminInfo } from '/@/stores/adminInfo'
|
||||||
import { useConfig } from '/@/stores/config'
|
import { useConfig } from '/@/stores/config'
|
||||||
import createAxios from '/@/utils/axios'
|
import createAxios from '/@/utils/axios'
|
||||||
|
import { auth } from '/@/utils/common'
|
||||||
|
|
||||||
const config = useConfig()
|
const config = useConfig()
|
||||||
const adminInfo = useAdminInfo()
|
const adminInfo = useAdminInfo()
|
||||||
@@ -198,14 +205,52 @@ const isTopLevelGroup = ref(false)
|
|||||||
|
|
||||||
const isSelfEdit = computed(() => baTable.form.operate === 'Edit' && adminInfo.id == baTable.form.items?.id)
|
const isSelfEdit = computed(() => 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 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(() => {
|
const showShareRateField = computed(() => {
|
||||||
if (isSelfEdit.value) return false
|
if (isSelfEdit.value) return false
|
||||||
if (isTopLevelGroup.value) {
|
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) {
|
if (adminInfo.super) {
|
||||||
const pid = baTable.form.items?.parent_admin_id
|
const pid = baTable.form.items?.parent_admin_id
|
||||||
@@ -273,24 +318,40 @@ const loadGroupMeta = async (groupId: unknown) => {
|
|||||||
isTopLevelGroup.value = !!res.data.is_top_level
|
isTopLevelGroup.value = !!res.data.is_top_level
|
||||||
if (isTopLevelGroup.value && baTable.form.items) {
|
if (isTopLevelGroup.value && baTable.form.items) {
|
||||||
baTable.form.items.parent_admin_id = null
|
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 {
|
} catch {
|
||||||
isTopLevelGroup.value = false
|
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 () => {
|
const loadShareRemainder = async () => {
|
||||||
if (!showShareRateField.value) {
|
if (!showShareRateField.value) {
|
||||||
shareHint.value = ''
|
shareHint.value = ''
|
||||||
@@ -380,6 +441,15 @@ watch(
|
|||||||
{ immediate: true }
|
{ immediate: true }
|
||||||
)
|
)
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => baTable.form.items?.parent_admin_id,
|
||||||
|
(parentId) => {
|
||||||
|
if (isTopLevelGroup.value) return
|
||||||
|
void loadParentChannelMeta(parentId)
|
||||||
|
},
|
||||||
|
{ immediate: true }
|
||||||
|
)
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => [
|
() => [
|
||||||
baTable.form.items?.parent_admin_id,
|
baTable.form.items?.parent_admin_id,
|
||||||
|
|||||||
@@ -60,12 +60,6 @@ const baTable: baTableClass = new baTableClass(
|
|||||||
align: 'left',
|
align: 'left',
|
||||||
minWidth: '180',
|
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('auth.group.jurisdiction'), prop: 'rules', align: 'center' },
|
||||||
{
|
{
|
||||||
label: t('State'),
|
label: t('State'),
|
||||||
@@ -91,7 +85,6 @@ const baTable: baTableClass = new baTableClass(
|
|||||||
{
|
{
|
||||||
defaultItems: {
|
defaultItems: {
|
||||||
status: 1,
|
status: 1,
|
||||||
channel_id: null,
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@@ -101,14 +94,9 @@ baTable.before.onSubmit = ({ formEl, operate, items }) => {
|
|||||||
let submitCallback = () => {
|
let submitCallback = () => {
|
||||||
baTable.form.submitLoading = true
|
baTable.form.submitLoading = true
|
||||||
const postItems: anyObj = { ...items }
|
const postItems: anyObj = { ...items }
|
||||||
const pid = Number(postItems.pid ?? 0)
|
delete postItems.channel_id
|
||||||
if (pid !== 0) {
|
delete postItems.channel_name
|
||||||
delete postItems.channel_id
|
delete postItems.channel_admin_username
|
||||||
delete postItems.channel_name
|
|
||||||
delete postItems.channel_admin_username
|
|
||||||
} else if (!adminInfo.super) {
|
|
||||||
delete postItems.channel_id
|
|
||||||
}
|
|
||||||
baTable.api
|
baTable.api
|
||||||
.postData(operate, {
|
.postData(operate, {
|
||||||
...postItems,
|
...postItems,
|
||||||
@@ -168,10 +156,6 @@ baTable.after.toggleForm = ({ operate }) => {
|
|||||||
|
|
||||||
// 编辑请求完成后钩子
|
// 编辑请求完成后钩子
|
||||||
baTable.after.getEditData = () => {
|
baTable.after.getEditData = () => {
|
||||||
const pid = Number(baTable.form.items?.pid ?? 0)
|
|
||||||
if (pid !== 0 && baTable.form.items) {
|
|
||||||
delete baTable.form.items.channel_id
|
|
||||||
}
|
|
||||||
menuRuleTreeUpdate()
|
menuRuleTreeUpdate()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -41,43 +41,6 @@
|
|||||||
valueOnClear: 0,
|
valueOnClear: 0,
|
||||||
}"
|
}"
|
||||||
/>
|
/>
|
||||||
<p
|
|
||||||
v-if="!isRootGroup"
|
|
||||||
class="group-channel-inherit-hint"
|
|
||||||
:style="{ paddingLeft: (baTable.form.labelWidth ?? 120) + 'px' }"
|
|
||||||
>
|
|
||||||
{{ t('auth.group.channel_inherit_hint') }}
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<!-- 顶级+超管:可选渠道;展示只读渠道名称(channel_id 仅由表单传给后端) -->
|
|
||||||
<FormItem
|
|
||||||
v-if="isRootGroup && adminInfo.super"
|
|
||||||
:label="t('auth.group.channel_id')"
|
|
||||||
v-model="baTable.form.items!.channel_id"
|
|
||||||
type="remoteSelect"
|
|
||||||
prop="channel_id"
|
|
||||||
:input-attr="{
|
|
||||||
pk: 'id',
|
|
||||||
field: 'name',
|
|
||||||
remoteUrl: '/admin/channel/index',
|
|
||||||
placeholder: t('Click select'),
|
|
||||||
emptyValues: ['', null, undefined, 0],
|
|
||||||
valueOnClear: null,
|
|
||||||
}"
|
|
||||||
/>
|
|
||||||
<template v-if="isRootGroup && adminInfo.super && channelPreviewName">
|
|
||||||
<el-form-item :label="t('auth.group.channel_name')">
|
|
||||||
<el-input :model-value="channelPreviewName" readonly />
|
|
||||||
</el-form-item>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<!-- 子级:只读展示上级对应渠道名称,不提交 channel_id(由后端按父级写入) -->
|
|
||||||
<template v-if="!isRootGroup && channelPreviewName">
|
|
||||||
<el-form-item :label="t('auth.group.channel_name')">
|
|
||||||
<el-input :model-value="channelPreviewName" readonly />
|
|
||||||
</el-form-item>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<el-form-item prop="name" :label="t('auth.group.Group name')">
|
<el-form-item prop="name" :label="t('auth.group.Group name')">
|
||||||
<el-input
|
<el-input
|
||||||
v-model="baTable.form.items!.name"
|
v-model="baTable.form.items!.name"
|
||||||
@@ -122,7 +85,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { reactive, inject, useTemplateRef, computed, watch } from 'vue'
|
import { reactive, inject, useTemplateRef } from 'vue'
|
||||||
import { useI18n } from 'vue-i18n'
|
import { useI18n } from 'vue-i18n'
|
||||||
import type baTableClass from '/@/utils/baTable'
|
import type baTableClass from '/@/utils/baTable'
|
||||||
import FormItem from '/@/components/formItem/index.vue'
|
import FormItem from '/@/components/formItem/index.vue'
|
||||||
@@ -130,105 +93,13 @@ import type { ElTree, FormItemRule } from 'element-plus'
|
|||||||
import { buildValidatorData } from '/@/utils/validate'
|
import { buildValidatorData } from '/@/utils/validate'
|
||||||
import type Node from 'element-plus/es/components/tree/src/model/node'
|
import type Node from 'element-plus/es/components/tree/src/model/node'
|
||||||
import { useConfig } from '/@/stores/config'
|
import { useConfig } from '/@/stores/config'
|
||||||
import { useAdminInfo } from '/@/stores/adminInfo'
|
|
||||||
import createAxios from '/@/utils/axios'
|
|
||||||
|
|
||||||
const config = useConfig()
|
const config = useConfig()
|
||||||
const adminInfo = useAdminInfo()
|
|
||||||
const formRef = useTemplateRef('formRef')
|
const formRef = useTemplateRef('formRef')
|
||||||
const treeRef = useTemplateRef('treeRef')
|
const treeRef = useTemplateRef('treeRef')
|
||||||
const baTable = inject('baTable') as baTableClass
|
const baTable = inject('baTable') as baTableClass
|
||||||
|
|
||||||
const { t } = useI18n()
|
const { t } = useI18n()
|
||||||
const isRootGroup = computed(() => {
|
|
||||||
const p = baTable.form.items?.pid
|
|
||||||
if (p === undefined || p === null || p === '') {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return Number(p) === 0
|
|
||||||
})
|
|
||||||
|
|
||||||
const strFromRow = (key: string): string => {
|
|
||||||
const row = baTable.form.items
|
|
||||||
if (!row) return ''
|
|
||||||
const v = row[key]
|
|
||||||
return typeof v === 'string' ? v : ''
|
|
||||||
}
|
|
||||||
|
|
||||||
const channelPreviewName = computed(() => strFromRow('channel_name'))
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 子角色组:选择上级分组后,只拉取展示用渠道名;channel_id 由后端按父级保存,不在此写入提交字段。
|
|
||||||
*/
|
|
||||||
watch(
|
|
||||||
() => baTable.form.items?.pid,
|
|
||||||
async (pid, oldPid) => {
|
|
||||||
const items = baTable.form.items
|
|
||||||
if (!items || !baTable.form.operate || !['Add', 'Edit'].includes(baTable.form.operate)) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
const pidNum = Number(pid ?? 0)
|
|
||||||
const oldNum = oldPid === undefined || oldPid === null || oldPid === '' ? null : Number(oldPid)
|
|
||||||
|
|
||||||
if (pidNum === 0) {
|
|
||||||
if (adminInfo.super && oldNum !== null && oldNum !== 0) {
|
|
||||||
items.channel_id = null
|
|
||||||
items['channel_name'] = ''
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
delete items.channel_id
|
|
||||||
|
|
||||||
try {
|
|
||||||
const res = await createAxios(
|
|
||||||
{
|
|
||||||
url: '/admin/auth.Group/edit',
|
|
||||||
method: 'get',
|
|
||||||
params: { id: pidNum },
|
|
||||||
},
|
|
||||||
{ showErrorMessage: false, showCodeMessage: false }
|
|
||||||
)
|
|
||||||
const row = res.data.row
|
|
||||||
if (row) {
|
|
||||||
items['channel_name'] = typeof row.channel_name === 'string' ? row.channel_name : ''
|
|
||||||
}
|
|
||||||
} catch {
|
|
||||||
items['channel_name'] = ''
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
/** 顶级+超管:所选渠道变更时刷新只读渠道名 */
|
|
||||||
watch(
|
|
||||||
() => baTable.form.items?.channel_id,
|
|
||||||
async (cid) => {
|
|
||||||
const items = baTable.form.items
|
|
||||||
if (!items || !baTable.form.operate || !['Add', 'Edit'].includes(baTable.form.operate)) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if (!isRootGroup.value || !adminInfo.super) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if (cid === null || cid === undefined || cid === '') {
|
|
||||||
items['channel_name'] = ''
|
|
||||||
return
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
const res = await createAxios(
|
|
||||||
{
|
|
||||||
url: '/admin/auth.Group/channelBindPreview',
|
|
||||||
method: 'get',
|
|
||||||
params: { channel_id: cid },
|
|
||||||
},
|
|
||||||
{ showErrorMessage: false, showCodeMessage: false }
|
|
||||||
)
|
|
||||||
items['channel_name'] = typeof res.data.channel_name === 'string' ? res.data.channel_name : ''
|
|
||||||
} catch {
|
|
||||||
items['channel_name'] = ''
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
const rules: Partial<Record<string, FormItemRule[]>> = reactive({
|
const rules: Partial<Record<string, FormItemRule[]>> = reactive({
|
||||||
name: [buildValidatorData({ name: 'required', title: t('auth.group.Group name') })],
|
name: [buildValidatorData({ name: 'required', title: t('auth.group.Group name') })],
|
||||||
@@ -281,14 +152,6 @@ defineExpose({
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
.group-channel-inherit-hint {
|
|
||||||
margin: -6px 0 14px;
|
|
||||||
font-size: 12px;
|
|
||||||
line-height: 1.5;
|
|
||||||
color: var(--el-text-color-secondary);
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
|
|
||||||
:deep(.penultimate-node) {
|
:deep(.penultimate-node) {
|
||||||
.el-tree-node__children {
|
.el-tree-node__children {
|
||||||
padding-left: 60px;
|
padding-left: 60px;
|
||||||
|
|||||||
Reference in New Issue
Block a user