5fb269cc0a
- 保存先写本地缓存,登录后可选云端同步;退出登录不再因文件操作跳转登录 - 修复 Layui 遮罩残留、design2 保存后线条、toast 被 finally 提前关闭 - 保存过程恢复 loading spinner;成功提示 2.5 秒 - 云端 payload 瘦身与体积超限提示;后端 schema 迁移与 FileService 容错 Co-authored-by: Cursor <cursoragent@cursor.com>
101 lines
3.0 KiB
PHP
101 lines
3.0 KiB
PHP
<?php
|
|
declare(strict_types=1);
|
|
|
|
/**
|
|
* Bootstrap: 配置加载、自动加载、生产环境禁止回退 example 配置。
|
|
*/
|
|
|
|
if (defined('SOON_BOOTSTRAPPED')) {
|
|
return;
|
|
}
|
|
define('SOON_BOOTSTRAPPED', true);
|
|
|
|
define('SOON_API_ROOT', __DIR__);
|
|
define('SOON_SERVER_ROOT', dirname(__DIR__));
|
|
|
|
$configDir = SOON_SERVER_ROOT . '/config';
|
|
$localConfig = $configDir . '/local.php';
|
|
$exampleConfig = $configDir . '/local.php.example';
|
|
$hostConfig = null;
|
|
if (isset($_SERVER['HTTP_HOST'])) {
|
|
$slug = strtolower(preg_replace('/[^a-z0-9]+/i', '-', $_SERVER['HTTP_HOST']));
|
|
$candidate = $configDir . '/config.' . $slug . '.php';
|
|
if (is_file($candidate)) {
|
|
$hostConfig = $candidate;
|
|
}
|
|
}
|
|
|
|
if (is_file($localConfig)) {
|
|
$config = require $localConfig;
|
|
} elseif ($hostConfig !== null) {
|
|
$config = require $hostConfig;
|
|
} else {
|
|
$allowExample = PHP_SAPI === 'cli' || getenv('SOON_ALLOW_EXAMPLE_CONFIG') === '1';
|
|
if ($allowExample && is_file($exampleConfig)) {
|
|
$config = require $exampleConfig;
|
|
} else {
|
|
http_response_code(500);
|
|
header('Content-Type: application/json; charset=utf-8');
|
|
echo json_encode([
|
|
'error' => 'config_missing',
|
|
'message' => '未找到 backend-web/config/local.php,请先写入生产配置。',
|
|
], JSON_UNESCAPED_UNICODE);
|
|
exit;
|
|
}
|
|
}
|
|
|
|
if (!is_array($config)) {
|
|
http_response_code(500);
|
|
header('Content-Type: application/json; charset=utf-8');
|
|
echo json_encode(['error' => 'config_invalid'], JSON_UNESCAPED_UNICODE);
|
|
exit;
|
|
}
|
|
|
|
if (!isset($config['app']) || !is_array($config['app'])) {
|
|
$config['app'] = [];
|
|
}
|
|
if (!isset($config['app']['env'])) {
|
|
$config['app']['env'] = 'production';
|
|
}
|
|
if (!isset($config['app']['debug'])) {
|
|
$config['app']['debug'] = false;
|
|
}
|
|
|
|
if ($config['app']['debug']) {
|
|
ini_set('display_errors', '1');
|
|
ini_set('display_startup_errors', '1');
|
|
error_reporting(E_ALL);
|
|
} else {
|
|
ini_set('display_errors', '0');
|
|
error_reporting(E_ALL & ~E_NOTICE & ~E_DEPRECATED);
|
|
}
|
|
|
|
date_default_timezone_set($config['app']['timezone'] ?? 'Asia/Shanghai');
|
|
|
|
spl_autoload_register(static function (string $class): void {
|
|
$prefixes = [
|
|
'Soon\\Api\\' => SOON_API_ROOT . '/',
|
|
'Soon\\Admin\\' => SOON_API_ROOT . '/',
|
|
];
|
|
foreach ($prefixes as $prefix => $baseDir) {
|
|
if (strpos($class, $prefix) !== 0) {
|
|
continue;
|
|
}
|
|
$relative = substr($class, strlen($prefix));
|
|
$path = $baseDir . str_replace('\\', '/', $relative) . '.php';
|
|
if (is_file($path)) {
|
|
require $path;
|
|
return;
|
|
}
|
|
}
|
|
});
|
|
|
|
require SOON_API_ROOT . '/Core/Config.php';
|
|
\Soon\Api\Core\Config::init($config);
|
|
require SOON_API_ROOT . '/Services/PaymentConfigLoader.php';
|
|
require SOON_API_ROOT . '/Services/SettingsConfigLoader.php';
|
|
\Soon\Api\Services\PaymentConfigLoader::reload($config);
|
|
\Soon\Api\Core\Config::init($config);
|
|
require SOON_API_ROOT . '/Core/ErrorHandler.php';
|
|
\Soon\Api\Core\ErrorHandler::register();
|