From 2ee78b3239ce1a9b18f1e7f9755eea6fb936639a Mon Sep 17 00:00:00 2001
From: zhenhui <1276357500@qq.com>
Date: Wed, 1 Apr 2026 16:16:06 +0800
Subject: [PATCH] =?UTF-8?q?=E6=B8=B8=E6=88=8F-=E6=B8=A0=E9=81=93=E7=AE=A1?=
=?UTF-8?q?=E7=90=86-=E4=BC=98=E5=8C=96=E6=B8=A0=E9=81=93=E5=92=8C?=
=?UTF-8?q?=E7=AE=A1=E7=90=86=E5=91=98=E6=B7=BB=E5=8A=A0=E6=96=B9=E5=BC=8F?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
app/admin/controller/auth/Admin.php | 86 +++++++++-
app/admin/controller/game/Channel.php | 148 ++++++++++++++++++
.../views/backend/game/channel/popupForm.vue | 11 +-
3 files changed, 233 insertions(+), 12 deletions(-)
diff --git a/app/admin/controller/auth/Admin.php b/app/admin/controller/auth/Admin.php
index 2931e19..8ab0762 100644
--- a/app/admin/controller/auth/Admin.php
+++ b/app/admin/controller/auth/Admin.php
@@ -42,11 +42,23 @@ class Admin extends Backend
}
list($where, $alias, $limit, $order) = $this->queryBuilder();
- $res = $this->model
+ $query = $this->model
->withoutField('login_failure,password,salt')
->withJoin($this->withJoinTable, $this->withJoinType)
->alias($alias)
- ->where($where)
+ ->where($where);
+
+ // 仅返回“顶级角色组(pid=0)”下的管理员(用于远程下拉等场景)
+ $topGroup = $request->get('top_group') ?? $request->post('top_group');
+ if ($topGroup === '1' || $topGroup === 1 || $topGroup === true) {
+ $query = $query
+ ->join('admin_group_access aga', $alias['admin'] . '.id = aga.uid')
+ ->join('admin_group ag', 'aga.group_id = ag.id')
+ ->where('ag.pid', 0)
+ ->distinct(true);
+ }
+
+ $res = $query
->order($order)
->paginate($limit);
@@ -57,6 +69,76 @@ class Admin extends Backend
]);
}
+ /**
+ * 远程下拉(重写:支持 top_group=1 仅返回顶级组管理员)
+ */
+ protected function _select(): Response
+ {
+ if (empty($this->model)) {
+ return $this->success('', [
+ 'list' => [],
+ 'total' => 0,
+ ]);
+ }
+
+ $pk = $this->model->getPk();
+
+ $fields = [$pk];
+ $quickSearchArr = is_array($this->quickSearchField) ? $this->quickSearchField : explode(',', (string) $this->quickSearchField);
+ foreach ($quickSearchArr as $f) {
+ $f = trim((string) $f);
+ if ($f === '') continue;
+ $f = str_contains($f, '.') ? substr($f, strrpos($f, '.') + 1) : $f;
+ if ($f !== '' && !in_array($f, $fields, true)) {
+ $fields[] = $f;
+ }
+ }
+
+ list($where, $alias, $limit, $order) = $this->queryBuilder();
+ $modelTable = strtolower($this->model->getTable());
+ $mainAlias = ($alias[$modelTable] ?? $modelTable) . '.';
+
+ // 联表时避免字段歧义:主表字段统一 select 为 "admin.xxx as xxx"
+ $selectFields = [];
+ foreach ($fields as $f) {
+ $f = trim((string) $f);
+ if ($f === '') continue;
+ $selectFields[] = $mainAlias . $f . ' as ' . $f;
+ }
+
+ // 联表时避免排序字段歧义:无前缀的字段默认加主表前缀
+ $qualifiedOrder = [];
+ if (is_array($order)) {
+ foreach ($order as $k => $v) {
+ $k = (string) $k;
+ $qualifiedOrder[str_contains($k, '.') ? $k : ($mainAlias . $k)] = $v;
+ }
+ }
+
+ $query = $this->model
+ ->field($selectFields)
+ ->alias($alias)
+ ->where($where);
+
+ $topGroup = $this->request ? ($this->request->get('top_group') ?? $this->request->post('top_group')) : null;
+ if ($topGroup === '1' || $topGroup === 1 || $topGroup === true) {
+ $query = $query
+ ->join('admin_group_access aga', $mainAlias . 'id = aga.uid')
+ ->join('admin_group ag', 'aga.group_id = ag.id')
+ ->where('ag.pid', 0)
+ ->distinct(true);
+ }
+
+ $res = $query
+ ->order($qualifiedOrder ?: $order)
+ ->paginate($limit);
+
+ return $this->success('', [
+ 'list' => $res->items(),
+ 'total' => $res->total(),
+ ]);
+ }
+
public function add(Request $request): Response
{
$response = $this->initializeBackend($request);
diff --git a/app/admin/controller/game/Channel.php b/app/admin/controller/game/Channel.php
index f075f1f..684fabf 100644
--- a/app/admin/controller/game/Channel.php
+++ b/app/admin/controller/game/Channel.php
@@ -4,6 +4,7 @@ namespace app\admin\controller\game;
use Throwable;
use app\common\controller\Backend;
+use support\think\Db;
use support\Response;
use Webman\Http\Request as WebmanRequest;
@@ -31,6 +32,153 @@ class Channel extends Backend
return null;
}
+ /**
+ * 添加(重写:管理员只选顶级组;admin_group_id 后端自动写入)
+ * @throws Throwable
+ */
+ protected function _add(): Response
+ {
+ if ($this->request && $this->request->method() === 'POST') {
+ $data = $this->request->post();
+ if (!$data) {
+ return $this->error(__('Parameter %s can not be empty', ['']));
+ }
+
+ $data = $this->applyInputFilter($data);
+ $data = $this->excludeFields($data);
+
+ $adminId = $data['admin_id'] ?? null;
+ if ($adminId === null || $adminId === '') {
+ return $this->error(__('Parameter %s can not be empty', ['admin_id']));
+ }
+
+ // 不允许前端填写,统一后端根据管理员所属“顶级角色组(pid=0)”自动回填
+ if (array_key_exists('admin_group_id', $data)) {
+ unset($data['admin_group_id']);
+ }
+
+ $topGroupId = Db::name('admin_group_access')
+ ->alias('aga')
+ ->join('admin_group ag', 'aga.group_id = ag.id')
+ ->where('aga.uid', $adminId)
+ ->where('ag.pid', 0)
+ ->value('ag.id');
+
+ if ($topGroupId === null || $topGroupId === '') {
+ return $this->error(__('Record not found'));
+ }
+ $data['admin_group_id'] = $topGroupId;
+
+ if ($this->dataLimit && $this->dataLimitFieldAutoFill) {
+ $data[$this->dataLimitField] = $this->auth->id;
+ }
+
+ $result = false;
+ $this->model->startTrans();
+ try {
+ if ($this->modelValidate) {
+ $validate = str_replace("\\model\\", "\\validate\\", get_class($this->model));
+ if (class_exists($validate)) {
+ $validate = new $validate();
+ if ($this->modelSceneValidate) {
+ $validate->scene('add');
+ }
+ $validate->check($data);
+ }
+ }
+ $result = $this->model->save($data);
+ $this->model->commit();
+ } catch (Throwable $e) {
+ $this->model->rollback();
+ return $this->error($e->getMessage());
+ }
+ if ($result !== false) {
+ return $this->success(__('Added successfully'));
+ }
+ return $this->error(__('No rows were added'));
+ }
+
+ return $this->error(__('Parameter error'));
+ }
+
+ /**
+ * 编辑(重写:管理员只选顶级组;admin_group_id 后端自动写入)
+ * @throws Throwable
+ */
+ protected function _edit(): Response
+ {
+ $pk = $this->model->getPk();
+ $id = $this->request ? ($this->request->post($pk) ?? $this->request->get($pk)) : null;
+ $row = $this->model->find($id);
+ if (!$row) {
+ return $this->error(__('Record not found'));
+ }
+
+ $dataLimitAdminIds = $this->getDataLimitAdminIds();
+ if ($dataLimitAdminIds && !in_array($row[$this->dataLimitField], $dataLimitAdminIds)) {
+ return $this->error(__('You have no permission'));
+ }
+
+ if ($this->request && $this->request->method() === 'POST') {
+ $data = $this->request->post();
+ if (!$data) {
+ return $this->error(__('Parameter %s can not be empty', ['']));
+ }
+
+ $data = $this->applyInputFilter($data);
+ $data = $this->excludeFields($data);
+
+ // 不允许前端填写,统一后端根据管理员所属“顶级角色组(pid=0)”自动回填
+ if (array_key_exists('admin_group_id', $data)) {
+ unset($data['admin_group_id']);
+ }
+
+ $nextAdminId = array_key_exists('admin_id', $data) ? $data['admin_id'] : ($row['admin_id'] ?? null);
+ if ($nextAdminId !== null && $nextAdminId !== '') {
+ $topGroupId = Db::name('admin_group_access')
+ ->alias('aga')
+ ->join('admin_group ag', 'aga.group_id = ag.id')
+ ->where('aga.uid', $nextAdminId)
+ ->where('ag.pid', 0)
+ ->value('ag.id');
+
+ if ($topGroupId === null || $topGroupId === '') {
+ return $this->error(__('Record not found'));
+ }
+ $data['admin_group_id'] = $topGroupId;
+ }
+
+ $result = false;
+ $this->model->startTrans();
+ try {
+ if ($this->modelValidate) {
+ $validate = str_replace("\\model\\", "\\validate\\", get_class($this->model));
+ if (class_exists($validate)) {
+ $validate = new $validate();
+ if ($this->modelSceneValidate) {
+ $validate->scene('edit');
+ }
+ $data[$pk] = $row[$pk];
+ $validate->check($data);
+ }
+ }
+ $result = $row->save($data);
+ $this->model->commit();
+ } catch (Throwable $e) {
+ $this->model->rollback();
+ return $this->error($e->getMessage());
+ }
+ if ($result !== false) {
+ return $this->success(__('Update successful'));
+ }
+ return $this->error(__('No rows updated'));
+ }
+
+ return $this->success('', [
+ 'row' => $row
+ ]);
+ }
+
/**
* 查看
* @throws Throwable
diff --git a/web/src/views/backend/game/channel/popupForm.vue b/web/src/views/backend/game/channel/popupForm.vue
index 43a2e50..bfa5ceb 100644
--- a/web/src/views/backend/game/channel/popupForm.vue
+++ b/web/src/views/backend/game/channel/popupForm.vue
@@ -60,20 +60,12 @@
@keyup.ctrl.enter="baTable.onSubmit(formRef)"
:placeholder="t('Please input field', { field: t('game.channel.remark') })"
/>
-
@@ -110,7 +102,6 @@ const rules: Partial> = reactive({
name: [buildValidatorData({ name: 'required', title: t('game.channel.name') })],
user_count: [buildValidatorData({ name: 'integer', title: t('game.channel.user_count') })],
profit_amount: [buildValidatorData({ name: 'float', title: t('game.channel.profit_amount') })],
- admin_group_id: [buildValidatorData({ name: 'required', title: t('game.channel.admin_group_id') })],
admin_id: [buildValidatorData({ name: 'required', title: t('game.channel.admin_id') })],
create_time: [buildValidatorData({ name: 'date', title: t('game.channel.create_time') })],
update_time: [buildValidatorData({ name: 'date', title: t('game.channel.update_time') })],