tp/app/admin/BaseController.php
2026-01-26 14:48:27 +08:00

196 lines
5.2 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
declare (strict_types = 1);
namespace app\admin;
use think\App;
use think\exception\ValidateException;
use think\Validate;
use think\facade\Request;
use think\facade\Session;
use think\facade\Cache;
use app\admin\controller\OperationLog\OperationLogger;
/**
* 控制器基础类
*/
abstract class BaseController
{
/**
* Request实例
* @var \think\Request
*/
protected $request;
/**
* 应用实例
* @var \think\App
*/
protected $app;
/**
* 是否批量验证
* @var bool
*/
protected $batchValidate = false;
/**
* 控制器中间件
* @var array
*/
protected $middleware = [];
/**
* 构造方法
* @access public
* @param App $app 应用对象
*/
public function __construct(App $app)
{
$this->app = $app;
$this->request = $this->app->request;
// 控制器初始化
$this->initialize();
}
// 初始化
protected function initialize()
{}
/**
* 验证数据
* @access protected
* @param array $data 数据
* @param string|array $validate 验证器名或者验证规则数组
* @param array $message 提示信息
* @param bool $batch 是否批量验证
* @return array|string|true
* @throws ValidateException
*/
protected function validate(array $data, string|array $validate, array $message = [], bool $batch = false)
{
if (is_array($validate)) {
$v = new Validate();
$v->rule($validate);
} else {
if (strpos($validate, '.')) {
// 支持场景
[$validate, $scene] = explode('.', $validate);
}
$class = false !== strpos($validate, '\\') ? $validate : $this->app->parseClass('validate', $validate);
$v = new $class();
if (!empty($scene)) {
$v->scene($scene);
}
}
$v->message($message);
// 是否批量验证
if ($batch || $this->batchValidate) {
$v->batch(true);
}
return $v->failException(true)->check($data);
}
/**
* 记录操作日志
*
* @param string $module 模块名称(如:文件管理)
* @param string $action 操作名称(如:创建文件分组)
* @param array $responseData 响应数据(可选)
* @param array $userInfo 用户信息(可选,如果不提供则从 Session 获取)
* @return bool
*/
protected function logSuccess(string $module, string $action, array $responseData = [], array $userInfo = []): bool
{
return OperationLogger::success($module, $action, $responseData, $userInfo);
}
/**
* 记录失败日志
*
* @param string $module 模块名称
* @param string $action 操作名称
* @param string $errorMessage 错误信息
* @param array $userInfo 用户信息(可选,如果不提供则从 Session 获取)
* @return bool
*/
protected function logFail(string $module, string $action, string $errorMessage, array $userInfo = []): bool
{
return OperationLogger::fail($module, $action, $errorMessage, $userInfo);
}
/**
* 记录操作日志
*
* @param string $module 操作模块
* @param string $action 操作动作
* @param array $requestData 请求数据(为空则自动获取)
* @param array $responseData 响应数据
* @param int $status 操作状态1-成功0-失败
* @param string $errorMessage 错误信息
* @return bool
*/
protected function logOperation(
string $module,
string $action,
array $requestData = [],
array $responseData = [],
int $status = 1,
string $errorMessage = ''
): bool {
return OperationLogger::record(
$module,
$action,
$requestData,
$responseData,
$status,
$errorMessage
);
}
/**
* 获取当前登录管理员信息
*
* @return array 用户信息数组,包含 id、account、name 等字段
*/
protected function getAdminUserInfo(): array
{
$userId = $this->request->header('Authorization', '');
if (!preg_match('/Bearer\s+(.+)/i', $userId, $matches)) {
return ['id' => 0, 'account' => '', 'name' => ''];
}
$tokenData = $this->verifyTokenFromHeader($matches[1]);
if (!$tokenData || !isset($tokenData['user'])) {
return ['id' => 0, 'account' => '', 'name' => ''];
}
return (array)$tokenData['user'];
}
private function verifyTokenFromHeader($token): ?array
{
$authHeader = $this->request->header('Authorization', '');
if (!preg_match('/Bearer\s+(.+)/i', $authHeader, $matches)) {
return null;
}
try {
$decoded = \Firebase\JWT\JWT::decode(
$matches[1],
new \Firebase\JWT\Key(\app\service\JwtService::getSecret(), 'HS256')
);
return (array)$decoded;
} catch (\Exception $e) {
return null;
}
}
}