1.优化后台管理员管理页面的权限设置,新增zihuaadmin账号

This commit is contained in:
2026-05-29 17:33:48 +08:00
parent 54fb283b8d
commit db0ddb1a2a
2 changed files with 94 additions and 138 deletions

View File

@@ -156,20 +156,9 @@ class Admin extends Backend
$parentAdminId = intval($request->get('parent_admin_id', 0)); $parentAdminId = intval($request->get('parent_admin_id', 0));
$excludeId = intval($request->get('exclude_id', 0)); $excludeId = intval($request->get('exclude_id', 0));
$isTopLevelGroup = ($request->get('is_top_level') ?? $request->post('is_top_level')) === '1'
|| ($request->get('is_top_level') ?? $request->post('is_top_level')) === 1
|| ($request->get('is_top_level') ?? $request->post('is_top_level')) === true;
$channelId = intval($request->get('channel_id', 0)); $channelId = intval($request->get('channel_id', 0));
if ($isTopLevelGroup) { if ($parentAdminId <= 0 && $channelId > 0) {
if ($channelId <= 0) {
return $this->success('', [
'used_rate' => '0.00',
'remaining_rate' => '100.00',
'parent_has_no_share' => false,
'is_top_level' => true,
]);
}
$stats = AdminCommissionDistributionService::getChannelRootShareRemainder( $stats = AdminCommissionDistributionService::getChannelRootShareRemainder(
$channelId, $channelId,
$excludeId > 0 ? $excludeId : null $excludeId > 0 ? $excludeId : null
@@ -178,7 +167,7 @@ class Admin extends Backend
'used_rate' => $stats['used_rate'], 'used_rate' => $stats['used_rate'],
'remaining_rate' => $stats['remaining_rate'], 'remaining_rate' => $stats['remaining_rate'],
'parent_has_no_share' => bccomp($stats['remaining_rate'], '0', 2) <= 0, 'parent_has_no_share' => bccomp($stats['remaining_rate'], '0', 2) <= 0,
'is_top_level' => true, 'is_channel_root' => true,
]); ]);
} }
@@ -187,7 +176,7 @@ class Admin extends Backend
'used_rate' => '0.00', 'used_rate' => '0.00',
'remaining_rate' => '100.00', 'remaining_rate' => '100.00',
'parent_has_no_share' => false, 'parent_has_no_share' => false,
'is_top_level' => false, 'is_channel_root' => false,
]); ]);
} }
@@ -524,17 +513,15 @@ class Admin extends Backend
$groupArr = is_array($rowData['group_arr'] ?? null) ? $rowData['group_arr'] : []; $groupArr = is_array($rowData['group_arr'] ?? null) ? $rowData['group_arr'] : [];
$rowData['primary_group_is_top_level'] = $this->isPrimaryGroupTopLevel($groupArr); $rowData['primary_group_is_top_level'] = $this->isPrimaryGroupTopLevel($groupArr);
$parentId = intval($rowData['parent_admin_id'] ?? 0); $parentId = intval($rowData['parent_admin_id'] ?? 0);
if ($rowData['primary_group_is_top_level']) { $channelId = intval($rowData['channel_id'] ?? 0);
$channelId = intval($rowData['channel_id'] ?? 0); if ($parentId > 0) {
if ($channelId > 0) {
$rowData['root_share_remainder'] = AdminCommissionDistributionService::getChannelRootShareRemainder(
$channelId,
intval($id)
);
}
} elseif ($parentId > 0) {
$remainder = AdminCommissionDistributionService::getShareRemainder($parentId, intval($id)); $remainder = AdminCommissionDistributionService::getShareRemainder($parentId, intval($id));
$rowData['share_remainder'] = $remainder; $rowData['share_remainder'] = $remainder;
} elseif ($channelId > 0) {
$rowData['root_share_remainder'] = AdminCommissionDistributionService::getChannelRootShareRemainder(
$channelId,
intval($id)
);
} }
return $this->success('', [ return $this->success('', [
@@ -742,89 +729,66 @@ class Admin extends Backend
{ {
if ($this->isPrimaryGroupTopLevel($groupIds)) { if ($this->isPrimaryGroupTopLevel($groupIds)) {
$data['parent_admin_id'] = null; $data['parent_admin_id'] = 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']);
}
}
$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,
$editAdminId
);
if ($shareErr !== null) {
return $shareErr;
}
$data['commission_share_rate'] = bcadd(strval($data['commission_share_rate'] ?? '0'), '0', 2);
return null;
} }
$parentId = isset($data['parent_admin_id']) && $data['parent_admin_id'] !== '' && $data['parent_admin_id'] !== null $parentId = isset($data['parent_admin_id']) && $data['parent_admin_id'] !== '' && $data['parent_admin_id'] !== null
? intval($data['parent_admin_id']) ? intval($data['parent_admin_id'])
: 0; : 0;
if ($parentId <= 0 && $editAdminId !== null && $editAdminId > 0) { if ($parentId <= 0 && $editAdminId !== null && $editAdminId > 0 && !array_key_exists('parent_admin_id', $data)) {
$existingParent = Db::name('admin')->where('id', $editAdminId)->value('parent_admin_id'); $existingParent = Db::name('admin')->where('id', $editAdminId)->value('parent_admin_id');
$parentId = intval($existingParent ?? 0); $parentId = intval($existingParent ?? 0);
} }
if ($parentId <= 0) {
$data['parent_admin_id'] = null; if ($parentId > 0) {
$data['commission_share_rate'] = null; if ($editAdminId !== null && $parentId === $editAdminId) {
if (!$this->auth->isSuperAdmin()) { return (string) __('Cannot set yourself as parent administrator');
$mayAssignChannel = false; }
foreach (['channel/index', 'channel/Index', 'Channel/index', 'Channel/Index'] as $routePath) {
if ($this->auth->check($routePath)) { $parent = Db::name('admin')->where('id', $parentId)->find();
$mayAssignChannel = true; if (!is_array($parent)) {
break; return (string) __('Invalid parent administrator');
} }
} if (!$this->canManageAdminId($parentId) && !$this->auth->isSuperAdmin()) {
if (!$mayAssignChannel) { return (string) __('You have no permission');
unset($data['channel_id']); }
$data['parent_admin_id'] = $parentId;
if (!empty($parent['channel_id'])) {
$data['channel_id'] = $parent['channel_id'];
$shareErr = AdminCommissionDistributionService::validateCommissionShareRate(
$parentId,
$data['commission_share_rate'] ?? null,
$editAdminId
);
if ($shareErr !== null) {
return $shareErr;
} }
$data['commission_share_rate'] = bcadd(strval($data['commission_share_rate'] ?? '0'), '0', 2);
} else {
$data['channel_id'] = null;
$data['commission_share_rate'] = null;
} }
return null; return null;
} }
if ($editAdminId !== null && $parentId === $editAdminId) { $data['parent_admin_id'] = null;
return (string) __('Cannot set yourself as parent administrator'); if ($editAdminId !== null && $editAdminId > 0 && !array_key_exists('channel_id', $data)) {
return null;
} }
$channelIdInt = intval($data['channel_id'] ?? 0);
$parent = Db::name('admin')->where('id', $parentId)->find(); if ($channelIdInt <= 0) {
if (!is_array($parent)) {
return (string) __('Invalid parent administrator');
}
if (!$this->canManageAdminId($parentId) && !$this->auth->isSuperAdmin()) {
return (string) __('You have no permission');
}
if (!empty($parent['channel_id'])) {
$data['channel_id'] = $parent['channel_id'];
} else {
$data['channel_id'] = null; $data['channel_id'] = null;
} $data['commission_share_rate'] = null;
$shareErr = AdminCommissionDistributionService::validateCommissionShareRate( return null;
$parentId, }
$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, $data['commission_share_rate'] ?? null,
$editAdminId $editAdminId
); );
@@ -832,7 +796,6 @@ class Admin extends Backend
return $shareErr; return $shareErr;
} }
$data['commission_share_rate'] = bcadd(strval($data['commission_share_rate'] ?? '0'), '0', 2); $data['commission_share_rate'] = bcadd(strval($data['commission_share_rate'] ?? '0'), '0', 2);
$data['parent_admin_id'] = $parentId;
return null; return null;
} }

View File

@@ -40,25 +40,6 @@
prop="nickname" prop="nickname"
:placeholder="t('Please input field', { field: t('auth.admin.nickname') })" :placeholder="t('Please input field', { field: t('auth.admin.nickname') })"
/> />
<FormItem
v-if="showChannelEditable"
:label="t('auth.admin.channel')"
v-model="baTable.form.items!.channel_id"
type="remoteSelect"
prop="channel_id"
:input-attr="{
remoteUrl: '/admin/channel/index',
field: 'name',
pk: 'id',
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"
@@ -94,6 +75,26 @@
<el-form-item v-if="showParentField && isTopLevelGroup" label=" "> <el-form-item v-if="showParentField && isTopLevelGroup" label=" ">
<el-alert :title="t('auth.admin.Top level group parent hint')" type="info" :closable="false" show-icon /> <el-alert :title="t('auth.admin.Top level group parent hint')" type="info" :closable="false" show-icon />
</el-form-item> </el-form-item>
<FormItem
v-if="showChannelEditable"
:label="t('auth.admin.channel')"
v-model="baTable.form.items!.channel_id"
type="remoteSelect"
prop="channel_id"
:key="'channel-' + (baTable.form.items!.parent_admin_id ?? '') + '-' + baTable.form.items!.id"
:input-attr="{
remoteUrl: '/admin/channel/index',
field: 'name',
pk: 'id',
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
v-if="showShareRateField" v-if="showShareRateField"
:label="t('auth.admin.commission_share_rate')" :label="t('auth.admin.commission_share_rate')"
@@ -190,8 +191,6 @@ 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()
const formRef = useTemplateRef('formRef') const formRef = useTemplateRef('formRef')
@@ -205,20 +204,13 @@ 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 hasChannelIndexAuth = computed(
() =>
adminInfo.super ||
auth({ name: '/admin/channel', subNodeName: '/admin/channel/index' }) ||
auth({ name: '/admin/Channel', subNodeName: '/admin/Channel/index' })
)
const hasParentAdmin = computed(() => { const hasParentAdmin = computed(() => {
const pid = baTable.form.items?.parent_admin_id const pid = baTable.form.items?.parent_admin_id
return pid !== null && pid !== undefined && pid !== '' && Number(pid) > 0 return pid !== null && pid !== undefined && pid !== '' && Number(pid) > 0
}) })
const showChannelEditable = computed( const showChannelEditable = computed(
() => hasChannelIndexAuth.value && isTopLevelGroup.value && !hasParentAdmin.value && !isSelfEdit.value () => adminInfo.super && !hasParentAdmin.value && !isSelfEdit.value
) )
const channelDisplayName = computed(() => { const channelDisplayName = computed(() => {
@@ -235,7 +227,7 @@ const showChannelReadonly = computed(() => {
if (isSelfEdit.value) return false if (isSelfEdit.value) return false
if (showChannelEditable.value) return false if (showChannelEditable.value) return false
if (hasParentAdmin.value) return true if (hasParentAdmin.value) return true
if (!isTopLevelGroup.value && hasChannelForShare.value) return true if (!adminInfo.super && baTable.form.operate === 'Add') return true
return channelDisplayName.value !== '' return channelDisplayName.value !== ''
}) })
@@ -248,19 +240,9 @@ const hasChannelForShare = computed(() => {
const showShareRateField = computed(() => { const showShareRateField = computed(() => {
if (isSelfEdit.value) return false if (isSelfEdit.value) return false
if (isTopLevelGroup.value) { if (!hasChannelForShare.value) return false
if (!hasChannelForShare.value) return false if (hasParentAdmin.value) return true
return hasChannelIndexAuth.value || baTable.form.operate === 'Add' return true
}
if (adminInfo.super) {
const pid = baTable.form.items?.parent_admin_id
return pid !== null && pid !== undefined && pid !== '' && Number(pid) > 0
}
if (baTable.form.operate === 'Add') {
return true
}
const pid = baTable.form.items?.parent_admin_id
return pid !== null && pid !== undefined && pid !== '' && Number(pid) > 0
}) })
const parentSelectParams = computed(() => { const parentSelectParams = computed(() => {
@@ -328,7 +310,7 @@ const loadParentChannelMeta = async (parentId: unknown) => {
const items = baTable.form.items const items = baTable.form.items
if (!items) return if (!items) return
if (parentId === null || parentId === undefined || parentId === '' || Number(parentId) <= 0) { if (parentId === null || parentId === undefined || parentId === '' || Number(parentId) <= 0) {
if (!isTopLevelGroup.value) { if (showChannelEditable.value) {
items['channel_name'] = '' items['channel_name'] = ''
} }
return return
@@ -357,14 +339,13 @@ const loadShareRemainder = async () => {
shareHint.value = '' shareHint.value = ''
return return
} }
if (isTopLevelGroup.value) { if (!hasParentAdmin.value && hasChannelForShare.value) {
const channelId = resolveChannelIdForShare() const channelId = resolveChannelIdForShare()
try { try {
const res = await createAxios({ const res = await createAxios({
url: '/admin/auth.Admin/commissionShareRemainder', url: '/admin/auth.Admin/commissionShareRemainder',
method: 'get', method: 'get',
params: { params: {
is_top_level: 1,
channel_id: channelId, channel_id: channelId,
exclude_id: baTable.form.items?.id || 0, exclude_id: baTable.form.items?.id || 0,
}, },
@@ -444,7 +425,6 @@ watch(
watch( watch(
() => baTable.form.items?.parent_admin_id, () => baTable.form.items?.parent_admin_id,
(parentId) => { (parentId) => {
if (isTopLevelGroup.value) return
void loadParentChannelMeta(parentId) void loadParentChannelMeta(parentId)
}, },
{ immediate: true } { immediate: true }
@@ -491,7 +471,9 @@ watch(
watch( watch(
() => baTable.form.items?.root_share_remainder, () => baTable.form.items?.root_share_remainder,
(val) => { (val) => {
if (val && baTable.form.operate === 'Edit' && isTopLevelGroup.value) { const pid = baTable.form.items?.parent_admin_id
const hasParent = pid !== null && pid !== undefined && pid !== '' && Number(pid) > 0
if (val && baTable.form.operate === 'Edit' && !hasParent) {
shareHint.value = t('auth.admin.Channel root share remainder hint', { shareHint.value = t('auth.admin.Channel root share remainder hint', {
used: val.used_rate ?? '0.00', used: val.used_rate ?? '0.00',
remaining: val.remaining_rate ?? '100.00', remaining: val.remaining_rate ?? '100.00',
@@ -508,6 +490,17 @@ watch(isTopLevelGroup, (topLevel) => {
} }
}) })
watch(
() => baTable.form.operate,
(operate) => {
if (operate !== 'Add' || adminInfo.super || !baTable.form.items) {
return
}
baTable.form.items.parent_admin_id = adminInfo.id
void loadParentChannelMeta(adminInfo.id)
}
)
const rules: Partial<Record<string, FormItemRule[]>> = reactive({ const rules: Partial<Record<string, FormItemRule[]>> = reactive({
username: [buildValidatorData({ name: 'required', title: t('auth.admin.username') }), buildValidatorData({ name: 'account' })], username: [buildValidatorData({ name: 'required', title: t('auth.admin.username') }), buildValidatorData({ name: 'account' })],
nickname: [buildValidatorData({ name: 'required', title: t('auth.admin.nickname') })], nickname: [buildValidatorData({ name: 'required', title: t('auth.admin.nickname') })],