274 lines
8.3 KiB
PHP
Executable File
274 lines
8.3 KiB
PHP
Executable File
<?php
|
||
namespace App\Controllers\Admin;
|
||
|
||
use App\Core\AdminBaseController;
|
||
use Db\Database;
|
||
use \Exception;
|
||
|
||
class SettingsController extends AdminBaseController {
|
||
protected $db;
|
||
protected $uploadConfig;
|
||
|
||
public function __construct() {
|
||
$this->checkLogin();
|
||
$this->db = new Database();
|
||
$this->initSettingsTable();
|
||
|
||
$this->uploadConfig = [
|
||
'upload_dir' => dirname(dirname(dirname(__DIR__))) . '/Static/img/',
|
||
'max_size' => 5 * 1024 * 1024, // 5MB
|
||
'allowed_mimes' => [
|
||
'image/jpeg', 'image/png', 'image/gif', 'image/webp', 'image/x-icon', 'image/vnd.microsoft.icon'
|
||
]
|
||
];
|
||
}
|
||
|
||
/**
|
||
* 初始化系统设置表
|
||
*/
|
||
private function initSettingsTable() {
|
||
try {
|
||
$this->db->query("
|
||
CREATE TABLE IF NOT EXISTS `system_settings` (
|
||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||
`setting_key` varchar(100) NOT NULL,
|
||
`setting_value` text,
|
||
`updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||
PRIMARY KEY (`id`),
|
||
UNIQUE KEY `uk_setting_key` (`setting_key`)
|
||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||
");
|
||
} catch (Exception $e) {
|
||
// 表已存在或其他错误,忽略
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 系统设置页面
|
||
*/
|
||
public function index() {
|
||
$settings = $this->getAllSettings();
|
||
|
||
$this->render('Admin/settings.php', [
|
||
'title' => '系统设置',
|
||
'settings' => $settings
|
||
]);
|
||
}
|
||
|
||
/**
|
||
* 获取所有设置
|
||
*/
|
||
public function get() {
|
||
header('Content-Type: application/json');
|
||
|
||
try {
|
||
$settings = $this->getAllSettings();
|
||
echo json_encode([
|
||
'status' => 'success',
|
||
'data' => $settings
|
||
]);
|
||
exit;
|
||
} catch (Exception $e) {
|
||
$this->jsonError('获取设置失败: ' . $e->getMessage());
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 保存系统设置
|
||
*/
|
||
public function save() {
|
||
header('Content-Type: application/json');
|
||
$this->checkAdmin();
|
||
|
||
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
|
||
$this->jsonError('仅支持POST请求');
|
||
}
|
||
|
||
try {
|
||
$data = json_decode(file_get_contents('php://input'), true);
|
||
if (!$data) {
|
||
$data = $_POST;
|
||
}
|
||
|
||
// 处理logo上传(只支持site_logo和site_favicon)
|
||
$logoTypes = ['site_logo', 'site_favicon'];
|
||
foreach ($logoTypes as $logoType) {
|
||
$fileKey = $logoType . '_file';
|
||
if (isset($_FILES[$fileKey]) && $_FILES[$fileKey]['error'] === UPLOAD_ERR_OK) {
|
||
$_POST['logo_type'] = $logoType;
|
||
$logoUrl = $this->handleLogoUpload($_FILES[$fileKey]);
|
||
$this->saveSetting($logoType, $logoUrl);
|
||
}
|
||
}
|
||
|
||
// 保存其他设置
|
||
$allowedKeys = [
|
||
'site_title', 'site_description', 'site_keywords',
|
||
'site_logo', 'site_favicon', 'site_copyright',
|
||
'smtp_host', 'smtp_port', 'smtp_user', 'smtp_pass',
|
||
'smtp_from', 'smtp_from_name', 'smtp_encryption',
|
||
];
|
||
|
||
foreach ($allowedKeys as $key) {
|
||
if (isset($data[$key])) {
|
||
$this->saveSetting($key, $data[$key]);
|
||
}
|
||
}
|
||
|
||
// 清除SettingsHelper缓存
|
||
\App\Core\SettingsHelper::clearCache();
|
||
|
||
echo json_encode([
|
||
'status' => 'success',
|
||
'message' => '设置保存成功',
|
||
'data' => $this->getAllSettings()
|
||
]);
|
||
exit;
|
||
|
||
} catch (Exception $e) {
|
||
$this->jsonError('保存设置失败: ' . $e->getMessage());
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 处理logo上传
|
||
*/
|
||
private function handleLogoUpload($file) {
|
||
// 验证文件大小
|
||
if ($file['size'] > $this->uploadConfig['max_size']) {
|
||
throw new Exception('文件过大,最大支持5MB');
|
||
}
|
||
|
||
// 验证文件类型
|
||
$finfo = new \finfo(FILEINFO_MIME_TYPE);
|
||
$mime = $finfo->file($file['tmp_name']);
|
||
if (!in_array($mime, $this->uploadConfig['allowed_mimes'])) {
|
||
throw new Exception('不支持的文件类型,仅允许: JPG, PNG, GIF, WEBP, ICO');
|
||
}
|
||
|
||
// 确保上传目录存在
|
||
$uploadDir = rtrim($this->uploadConfig['upload_dir'], '/') . '/';
|
||
if (!is_dir($uploadDir)) {
|
||
mkdir($uploadDir, 0755, true);
|
||
}
|
||
|
||
// 生成文件名
|
||
$originalName = basename($file['name']);
|
||
$originalExt = pathinfo($originalName, PATHINFO_EXTENSION);
|
||
$filename = 'logo_' . date('YmdHis') . '_' . uniqid() . '.' . $originalExt;
|
||
$targetPath = $uploadDir . $filename;
|
||
|
||
// 移动文件
|
||
if (!move_uploaded_file($file['tmp_name'], $targetPath)) {
|
||
throw new Exception('文件上传失败');
|
||
}
|
||
|
||
// 返回相对路径(不含域名,兼容任何域名/端口)
|
||
return '/Static/img/' . $filename;
|
||
}
|
||
|
||
/**
|
||
* 获取单个设置值
|
||
*/
|
||
private function getSetting($key, $default = '') {
|
||
try {
|
||
$setting = $this->db->get('system_settings', 'setting_value', [
|
||
'setting_key' => $key
|
||
]);
|
||
return $setting !== false ? $setting : $default;
|
||
} catch (Exception $e) {
|
||
return $default;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 保存单个设置
|
||
*/
|
||
private function saveSetting($key, $value) {
|
||
try {
|
||
$existing = $this->db->get('system_settings', 'id', [
|
||
'setting_key' => $key
|
||
]);
|
||
|
||
if ($existing) {
|
||
// 更新
|
||
$this->db->update('system_settings', [
|
||
'setting_value' => $value
|
||
], [
|
||
'setting_key' => $key
|
||
]);
|
||
} else {
|
||
// 插入
|
||
$this->db->insert('system_settings', [
|
||
'setting_key' => $key,
|
||
'setting_value' => $value
|
||
]);
|
||
}
|
||
} catch (Exception $e) {
|
||
throw new Exception('保存设置失败: ' . $e->getMessage());
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 获取所有设置(以关联数组形式返回)
|
||
*/
|
||
private function getAllSettings() {
|
||
try {
|
||
$settings = $this->db->select('system_settings', ['setting_key', 'setting_value']);
|
||
$result = [];
|
||
|
||
foreach ($settings as $setting) {
|
||
$result[$setting['setting_key']] = $setting['setting_value'];
|
||
}
|
||
|
||
// 设置默认值
|
||
$defaults = [
|
||
'site_title' => 'Tài Xỉu Online - TM68',
|
||
'site_description' => 'Trang game tài xỉu đổi thưởng, nạp rút nhanh chóng',
|
||
'site_keywords' => 'tài xỉu, game online, đổi thưởng',
|
||
'site_logo' => '/Static/tm68/logo_tm68.png.png',
|
||
'site_favicon' => '/Static/css/favicon.ico',
|
||
'site_copyright' => '© 2024 TM68. All rights reserved.'
|
||
];
|
||
|
||
foreach ($defaults as $key => $default) {
|
||
if (!isset($result[$key])) {
|
||
$result[$key] = $default;
|
||
}
|
||
}
|
||
|
||
return $result;
|
||
} catch (Exception $e) {
|
||
return [];
|
||
}
|
||
}
|
||
|
||
/**
|
||
* SMTP 测试发信
|
||
*/
|
||
public function smtpTest() {
|
||
header('Content-Type: application/json');
|
||
$this->checkAdmin();
|
||
$data = json_decode(file_get_contents('php://input'), true);
|
||
$email = trim($data['email'] ?? '');
|
||
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
|
||
$this->jsonError('Invalid email');
|
||
}
|
||
\App\Core\SettingsHelper::clearCache();
|
||
$result = \App\Core\Mailer::test($email);
|
||
echo json_encode($result);
|
||
exit;
|
||
}
|
||
|
||
/**
|
||
* JSON错误响应
|
||
*/
|
||
private function jsonError($message) {
|
||
echo json_encode([
|
||
'status' => 'error',
|
||
'message' => $message
|
||
]);
|
||
exit;
|
||
}
|
||
}
|