移除渠道管理

This commit is contained in:
2026-03-30 14:45:09 +08:00
parent 179d67cb0e
commit d9dc31e388
24 changed files with 71 additions and 780 deletions

View File

@@ -17,7 +17,7 @@ class Admin extends Backend
{
protected ?object $model = null;
protected array|string $preExcludeFields = ['create_time', 'update_time', 'password', 'salt', 'login_failure', 'last_login_time', 'last_login_ip', 'agent_id'];
protected array|string $preExcludeFields = ['create_time', 'update_time', 'password', 'salt', 'login_failure', 'last_login_time', 'last_login_ip', 'agent_id', 'agent_api_secret', 'channel_id'];
protected array|string $quickSearchField = ['username', 'nickname'];
@@ -25,8 +25,6 @@ class Admin extends Backend
protected string $dataLimitField = 'id';
protected array $withJoinTable = ['channel'];
protected function initController(Request $request): ?Response
{
$this->model = new AdminModel();
@@ -46,8 +44,7 @@ class Admin extends Backend
list($where, $alias, $limit, $order) = $this->queryBuilder();
$res = $this->model
->withoutField('login_failure,password,salt')
->withJoin($this->withJoinTable, $this->withJoinType ?? 'LEFT')
->visible(['channel' => ['name']])
->withJoin($this->withJoinTable ?? [], $this->withJoinType ?? 'LEFT')
->alias($alias)
->where($where)
->order($order)
@@ -81,13 +78,9 @@ class Admin extends Backend
'mobile' => 'regex:/^1[3-9]\d{9}$/|unique:admin,mobile',
'group_arr' => 'required|array',
];
if ($this->auth->isSuperAdmin()) {
$rules['channel_id'] = 'required|integer|min:1';
}
$messages = [
'username.regex' => __('Please input correct username'),
'password.regex' => __('Please input correct password'),
'channel_id.required' => __('Please select channel'),
];
Validator::make($data, $rules, $messages)->validate();
} catch (ValidationException $e) {
@@ -95,14 +88,6 @@ class Admin extends Backend
}
}
if (!$this->auth->isSuperAdmin()) {
$currentChannelId = (int) ($this->auth->model->channel_id ?? 0);
if ($currentChannelId <= 0) {
return $this->error(__('Current admin has no channel bound'));
}
$data['channel_id'] = $currentChannelId;
}
$passwd = $data['password'] ?? '';
$data = $this->excludeFields($data);
$result = false;
@@ -115,7 +100,12 @@ class Admin extends Backend
$result = $this->model->save($data);
if ($result !== false) {
$agentId = strtolower(md5($this->model->username . $this->model->id));
$this->model->where('id', $this->model->id)->update(['agent_id' => $agentId]);
$agentSecret = strtoupper(md5($this->model->username . $this->model->id));
// 使用原生 SQL避免 ThinkORM 按当前表结构校验字段时因未迁移缺少 agent_api_secret 列而报错
Db::execute(
'UPDATE `admin` SET `agent_id` = ?, `agent_api_secret` = ? WHERE `id` = ?',
[$agentId, $agentSecret, $this->model->id]
);
}
if (!empty($data['group_arr'])) {
$groupAccess = [];
@@ -306,6 +296,39 @@ class Admin extends Backend
]);
}
/**
* 去掉已废弃的渠道字段,避免组合搜索生成对不存在列的条件
*/
protected function filterSearchArray(array $search): array
{
return array_values(array_filter($search, static function ($item) {
if (!is_array($item) || !isset($item['field'])) {
return true;
}
$f = (string) $item['field'];
if ($f === 'channel_id' || str_ends_with($f, '.channel_id')) {
return false;
}
if ($f === 'channel.name' || str_starts_with($f, 'channel.')) {
return false;
}
return true;
}));
}
public function queryOrderBuilder(): array
{
$order = parent::queryOrderBuilder();
foreach (array_keys($order) as $key) {
if ($key === 'channel_id' || (is_string($key) && str_contains($key, 'channel.'))) {
unset($order[$key]);
}
}
return $order;
}
private function checkGroupAuth(array $groups): ?Response
{
if ($this->auth->isSuperAdmin()) {

View File

@@ -1,110 +0,0 @@
<?php
namespace app\admin\controller\channel;
use Throwable;
use app\common\controller\Backend;
/**
* 渠道管理
*/
class Manage extends Backend
{
/**
* ChannelManage模型对象
* @var object|null
* @phpstan-var \app\common\model\ChannelManage|null
*/
protected ?object $model = null;
protected array|string $preExcludeFields = ['id', 'create_time', 'update_time', 'secret'];
protected array $withJoinTable = ['admin'];
protected string|array $quickSearchField = ['id'];
protected bool $autoFillAdminId = true;
public function initialize(): void
{
parent::initialize();
$this->model = new \app\common\model\ChannelManage();
}
/**
* 查看
* @throws Throwable
*/
public function index(\Webman\Http\Request $request): \support\Response
{
$response = $this->initializeBackend($request);
if ($response !== null) {
return $response;
}
if ($request->get('select') || $request->post('select')) {
return $this->select($request);
}
/**
* 1. withJoin 不可使用 alias 方法设置表别名,别名将自动使用关联模型名称(小写下划线命名规则)
* 2. 以下的别名设置了主表别名,同时便于拼接查询参数等
* 3. paginate 数据集可使用链式操作 each(function($item, $key) {}) 遍历处理
*/
list($where, $alias, $limit, $order) = $this->queryBuilder();
$res = $this->model
->withJoin($this->withJoinTable, $this->withJoinType)
->visible(['admin' => ['username']])
->alias($alias)
->where($where)
->order($order)
->paginate($limit);
return $this->success('', [
'list' => $res->items(),
'total' => $res->total(),
'remark' => get_route_remark(),
]);
}
/**
* 白名单(页面按钮规则,用于菜单规则中配置按钮权限)
* 实际编辑通过 edit 接口提交 ip_white 字段
*/
public function whitelist(\Webman\Http\Request $request): \support\Response
{
$response = $this->initializeBackend($request);
if ($response !== null) {
return $response;
}
return $this->success();
}
/**
* 渠道下拉选择(供 remoteSelect 使用)
*/
public function select(\Webman\Http\Request $request): \support\Response
{
$response = $this->initializeBackend($request);
if ($response !== null) {
return $response;
}
list($where, $alias, $limit, $order) = $this->queryBuilder();
$res = $this->model
->field('id,name,title')
->alias($alias)
->where($where)
->order($order)
->paginate($limit);
return $this->success('', [
'list' => $res->items(),
'total' => $res->total(),
]);
}
/**
* add、edit、del、sortable 已由父类 Backend 实现,无需重写即可直接使用
* 若需重写,请确保调用 initializeBackend($request) 并传入 Request 参数
* 若模型有 admin_id 字段需自动填充,可设置 protected bool $autoFillAdminId = true
*/
}

View File

@@ -13,7 +13,7 @@ class AdminInfo extends Backend
{
protected ?object $model = null;
protected array|string $preExcludeFields = ['username', 'last_login_time', 'password', 'salt', 'status'];
protected array|string $preExcludeFields = ['username', 'last_login_time', 'password', 'salt', 'status', 'channel_id', 'agent_id', 'agent_api_secret'];
protected array $authAllowFields = ['id', 'username', 'nickname', 'avatar', 'email', 'mobile', 'motto', 'last_login_time'];
protected function initController(Request $request): ?Response

View File

@@ -2,6 +2,4 @@
return [
'Group Name Arr' => 'Administrator Grouping ',
'Please use another administrator account to disable the current account!' => 'Disable the current account, please use another administrator account!',
'Please select channel' => 'Please select channel',
'Current admin has no channel bound' => 'Current admin has no channel bound',
];

View File

@@ -3,6 +3,4 @@ return [
'Group Name Arr' => '管理员分组',
'Please use another administrator account to disable the current account!' => '请使用另外的管理员账户禁用当前账户!',
'You have no permission to add an administrator to this group!' => '您没有权限向此分组添加管理员!',
'Please select channel' => '请选择渠道',
'Current admin has no channel bound' => '当前管理员未绑定渠道',
];

View File

@@ -33,7 +33,7 @@ class Auth extends \ba\Auth
protected string $refreshToken = '';
protected int $keepTime = 86400;
protected int $refreshTokenKeepTime = 2592000;
protected array $allowFields = ['id', 'username', 'nickname', 'avatar', 'last_login_time', 'channel_id'];
protected array $allowFields = ['id', 'username', 'nickname', 'avatar', 'last_login_time'];
public function __construct(array $config = [])
{

View File

@@ -21,13 +21,23 @@ use support\think\Db;
* @property string $password 密码密文
* @property string $salt 密码盐
* @property string $status 状态:enable=启用,disable=禁用
* @property string $agent_id 代理ID关联渠道
* @property int $channel_id 渠道ID
* @property string $agent_id 代理 IDAPI 鉴权
* @property string $agent_api_secret Agent API 密钥
*/
class Admin extends Model
{
use TimestampInteger;
/**
* 已移除的 channel_id 等若仍被旧请求/缓存传入,禁止参与读写
*/
protected function getOptions(): array
{
return [
'disuse' => ['channel_id'],
];
}
protected string $table = 'admin';
protected string $pk = 'id';
protected bool $autoWriteTimestamp = true;
@@ -66,12 +76,4 @@ class Admin extends Model
{
return $this->where(['id' => $uid])->update(['password' => hash_password($newPassword), 'salt' => '']);
}
/**
* 关联渠道
*/
public function channel(): \think\model\relation\BelongsTo
{
return $this->belongsTo(\app\common\model\ChannelManage::class, 'channel_id', 'id');
}
}

View File

@@ -10,7 +10,6 @@ use app\common\controller\Api;
use app\common\facade\Token;
use app\common\library\Auth as UserAuth;
use app\common\library\AgentJwt;
use app\common\model\ChannelManage;
use app\common\model\MallPlayxUserAsset;
use app\admin\model\Admin;
use Webman\Http\Request;
@@ -72,17 +71,12 @@ class Auth extends Api
return $this->error(__('Agent not found'));
}
$channelId = intval($admin->channel_id ?? 0);
if ($channelId <= 0) {
$apiSecret = strval($admin->agent_api_secret ?? '');
if ($apiSecret === '') {
return $this->error(__('Agent not found'));
}
$channel = ChannelManage::where('id', $channelId)->find();
if (!$channel || $channel->secret === '') {
return $this->error(__('Agent not found'));
}
if ($channel->secret !== $secret) {
if ($apiSecret !== $secret) {
return $this->error(__('Invalid agent or secret'));
}
@@ -93,9 +87,8 @@ class Auth extends Api
$expire = intval(config('buildadmin.agent_auth.token_expire', 86400));
$payload = [
'agent_id' => $agentId,
'channel_id' => $channel->id,
'admin_id' => $admin->id,
'agent_id' => $agentId,
'admin_id' => $admin->id,
];
$authtoken = AgentJwt::encode($payload, $expire);

View File

@@ -238,6 +238,7 @@ class Backend extends Api
$limit = is_numeric($limit) ? intval($limit) : 10;
$search = $this->request->get('search', []);
$search = is_array($search) ? $search : [];
$search = $this->filterSearchArray($search);
$initKey = $this->request->get('initKey', $pk);
$initValue = $this->request->get('initValue', '');
$initOperator = $this->request->get('initOperator', 'in');
@@ -352,6 +353,14 @@ class Backend extends Api
return [$where, $alias, $limit, $this->queryOrderBuilder()];
}
/**
* 组合搜索条件过滤(子类可覆盖,例如去掉已删除的数据库字段)
*/
protected function filterSearchArray(array $search): array
{
return $search;
}
/**
* 查询的排序参数构建器
*/

View File

@@ -18,7 +18,7 @@ class AgentJwt
/**
* 生成 JWT authtoken
* @param array $payload agent_id, channel_id, admin_id 等
* @param array $payload agent_idadmin_id 等
* @param int $expire 有效期(秒)
*/
public static function encode(array $payload, int $expire = 86400): string

View File

@@ -1,84 +0,0 @@
<?php
namespace app\common\model;
use support\think\Model;
/**
* ChannelManage
*/
class ChannelManage extends Model
{
// 表名
protected $name = 'channel_manage';
// 自动写入时间戳字段
protected $autoWriteTimestamp = true;
// 字段类型转换
protected $type = [
'create_time' => 'integer',
'update_time' => 'integer',
'ip_white' => 'json',
];
/**
* 获取 IP 白名单,统一返回字符串数组格式
* 兼容:["127.0.0.1"]、[{"value":"127.0.0.1"}]、[{"127.0.0.1":""}]
*/
public function getipWhiteAttr($value): array
{
$arr = is_array($value) ? $value : (!$value ? [] : json_decode($value, true));
if (!is_array($arr)) {
return [];
}
$result = [];
foreach ($arr as $item) {
if (is_string($item)) {
$result[] = $item;
} elseif (is_array($item)) {
if (isset($item['value'])) {
$result[] = $item['value'];
} else {
$key = array_key_first($item);
if ($key !== null && $key !== '') {
$result[] = $key;
}
}
}
}
return array_values(array_filter($result));
}
/**
* 写入 IP 白名单,存储格式 ["127.0.0.1","192.168.1.1"]
*/
public function setipWhiteAttr($value): array
{
$arr = is_array($value) ? $value : [];
$result = [];
foreach ($arr as $ip) {
$ip = is_string($ip) ? trim($ip) : '';
if ($ip !== '') {
$result[] = $ip;
}
}
return array_values($result);
}
/**
* 创建时自动生成密钥strtoupper(md5(name+id))
*/
protected static function onAfterInsert($model): void
{
$pk = $model->getPk();
$secret = strtoupper(md5($model->name . $model->$pk));
$model->where($pk, $model->$pk)->update(['secret' => $secret]);
}
public function admin(): \think\model\relation\BelongsTo
{
return $this->belongsTo(\app\admin\model\Admin::class, 'admin_id', 'id');
}
}

View File

@@ -1,31 +0,0 @@
<?php
namespace app\common\validate;
use think\Validate;
class ChannelManage extends Validate
{
protected $failException = true;
/**
* 验证规则
*/
protected $rule = [
];
/**
* 提示消息
*/
protected $message = [
];
/**
* 验证场景
*/
protected $scene = [
'add' => [],
'edit' => [],
];
}

View File

@@ -167,7 +167,7 @@ if (!function_exists('get_auth_token')) {
if (!function_exists('get_agent_jwt_payload')) {
/**
* 解析 Agent JWT authtoken返回 payloadagent_id、channel_id、admin_id 等)
* 解析 Agent JWT authtoken返回 payloadagent_id、admin_id 等)
* @param string $token authtoken
* @return array 成功返回 payload失败返回空数组
*/