[ 'auth_mode' => 'plain', 'access_key_id' => 'plain', 'access_key_secret' => 'secret', 'bucket' => 'plain', 'endpoint' => 'plain', 'prefix' => 'plain', 'ram_role_name' => 'plain', 'custom_domain' => 'plain', 'internal_endpoint' => 'plain', 'https' => 'plain', ], 'cos' => [ 'auth_mode' => 'plain', 'secret_id' => 'plain', 'secret_key' => 'secret', 'bucket' => 'plain', 'region' => 'plain', 'prefix' => 'plain', 'cam_role_name' => 'plain', 'custom_domain' => 'plain', 'https' => 'plain', ], 'qiniu' => [ 'access_key' => 'plain', 'secret_key' => 'secret', 'bucket' => 'plain', 'region' => 'plain', 'prefix' => 'plain', 'custom_domain' => 'plain', 'https' => 'plain', ], ]; foreach ($fieldMap as $d => $fields) { $old = storageConfigFor($d); $in = isset($_POST[$d]) && is_array($_POST[$d]) ? $_POST[$d] : []; $clearSecrets = !empty($in['clear_secrets']); $new = []; foreach ($fields as $f => $kind) { $posted = isset($in[$f]) ? trim((string)$in[$f]) : ''; if ($kind === 'secret') { if ($clearSecrets) { $new[$f] = ''; } else { // 留空表示保持原值 $new[$f] = $posted === '' ? (string)($old[$f] ?? '') : $posted; } } else { $new[$f] = $posted !== '' ? $posted : (string)($old[$f] ?? ''); } } // 复选框型字段(未勾选时浏览器不提交该字段,必须显式归零而不是沿用旧值) $new['https'] = ($new['https'] ?? '') === '0' ? '0' : '1'; if ($d === 'oss') { $new['internal_endpoint'] = ($new['internal_endpoint'] ?? '') === '1' ? '1' : '0'; } saveStorageConfig($d, $new); } setSetting('storage_driver', $driver); // 图片访问方式:direct(直连存储)/ proxy(经 media.php 服务端代理读取) $accessMode = ($_POST['storage_access_mode'] ?? 'direct') === 'proxy' ? 'proxy' : 'direct'; setSetting('storage_access_mode', $accessMode); $message = '设置已保存。当前存储方式:' . (storageDriverLabels()[$driver] ?? $driver) . ';图片访问方式:' . ($accessMode === 'proxy' ? '服务端代理' : '直连存储'); } // ---------- 清除错误提示 ---------- if ($_SERVER['REQUEST_METHOD'] === 'POST' && ($_POST['action'] ?? '') === 'clear_storage_error') { storageClearError(); $message = '已清除错误提示'; } // ---------- 切换界面主题(个人偏好,只影响当前账号)---------- if ($_SERVER['REQUEST_METHOD'] === 'POST' && ($_POST['action'] ?? '') === 'save_theme') { $themeKey = (string)($_POST['theme'] ?? ''); if (!isValidTheme($themeKey)) { $error = '没有这套主题,请从下面重新选一个。'; } elseif (setAdminTheme((int)$admin['id'], $themeKey)) { // setAdminTheme 已经把 session 一起更新了,所以本次请求往下渲染时就已经是新主题 $message = '界面主题已切换为「' . themeInfo($themeKey)['name'] . '」。'; } else { $error = '主题保存失败,请稍后再试。'; } } $themes = themeCatalog(); $curThemeKey = currentThemeKey(); $drivers = storageDriverLabels(); $current = currentStorageDriver(); $configs = []; foreach (['oss', 'cos', 'qiniu'] as $d) { $configs[$d] = storageConfigFor($d); } $lastError = storageLastError(); $isRemote = storageIsRemote(); $remoteReady = $current !== 'local' && storageConfigComplete($current); // 本地图片统计(只读目录,不查库) function localImageStat() { $count = 0; $bytes = 0; $base = UPLOAD_DIR; if (!is_dir($base)) return ['count' => 0, 'bytes' => 0]; $it = new RecursiveIteratorIterator( new RecursiveDirectoryIterator($base, FilesystemIterator::SKIP_DOTS), RecursiveIteratorIterator::LEAVES_ONLY ); foreach ($it as $f) { if (!$f->isFile()) continue; if ($f->getFilename() === '.htaccess') continue; $count++; $bytes += $f->getSize(); } return ['count' => $count, 'bytes' => $bytes]; } $localStat = localImageStat(); ?> > 系统设置 - 电影日志
最近一次存储错误(, 驱动:)

🎨 我的界面主题

挑一套配色,只作用于你自己的账号——别人登录看到的还是他们各自选的那套。
想先看看效果就点一下主题卡片,整页会立刻换色(只是预览,按「保存主题」才真正记住)。 按钮、链接、卡片边框、评分徽标与年度报告的图表颜色都会一起换。
$t): ?>
保存后立刻生效,全站页面都用这套配色;不用重新登录。

图片存储方式

图片可以存放在本站硬盘上,也可以托管到对象存储。改用对象存储后,图片不再占用服务器磁盘, 以后搬迁网站时也不必搬运图片文件。
切换存储方式不会影响已有图片:系统按"本地优先"读取, 本地存在的文件继续走本地,新上传的图片才走云端。
'默认方式,图片存在 uploads/ 目录', 'oss' => '阿里云对象存储,支持 ECS 免密钥', 'cos' => '腾讯云对象存储,支持 CVM 免密钥', 'qiniu' => '七牛云对象存储,需绑定域名', ]; foreach ($drivers as $id => $label): ?>
internalStatus(); } ?>
阿里云 OSS 配置
服务器在阿里云 ECS 上并已绑定 RAM 角色时,选第二项可完全不填密钥。
在 OSS 控制台"概览"里查看,形如 oss-cn-地域.aliyuncs.com,不要带 https://。
仅在「服务端代理」访问方式下生效。服务器与桶同地域时, 读取会改用 oss-<地域>-internal.aliyuncs.com——内网流量免费且更快。
不同地域时内网地址连不通(DNS 能解析、TCP 建不起来), 硬走内网会让每次读取先白等一次连接超时。系统会自动判定地域、不可用就跳过并回退公网, 不会因此变慢;此处结论见下方「当前状态」。
当前判定: 内网可用 已跳过内网,走公网 ——
填写后图片会存到桶内该目录下,键变为 前缀/uploads/posters/xxx.jpg; 同一个桶存放多个站点时用它区分。留空则直接放在桶根目录。
填写后图片 URL 会使用该域名;留空则使用 OSS 默认域名。
腾讯云 COS 配置
服务器在腾讯云 CVM 上并已绑定 CAM 角色时,选第二项可完全不填密钥。
COS 的桶名必须带 APPID 后缀。
形如 ap-地域,在 COS 控制台桶的"概览"中可查。
填写后图片会存到桶内该目录下,键变为 前缀/uploads/posters/xxx.jpg; 同一个桶存放多个站点时用它区分。留空则直接放在桶根目录。
七牛云 Kodo 配置
七牛云的对象必须通过绑定域名访问,未绑定域名则图片无法显示。
填写后图片会存到空间内该目录下,键变为 前缀/uploads/posters/xxx.jpg; 同一个空间存放多个站点时用它区分。留空则直接放在空间根目录。

当前状态

生效方式
配置完整 配置不完整,暂时按本地存储处理 本地存储
图片访问方式
服务端代理 经 media.php 鉴权读取,桶可设为私有 直连存储 图片 URL 直接指向存储
服务端读取通道
内网 公网(已跳过内网)
本地图片
张,占用
数据目录
对象前缀
/ 未设置,图片直接放在桶根目录
凭据加密
加密不可用 未启用 openssl 或 db/ 目录不可写,云厂商密钥将以明文保存 解密失败 密钥文件 db/.settings.key 丢失或损坏,请在各云厂商表单中重新填写密钥 已加密 ,密钥单独存放于 db/.settings.key(不在数据库内)
ECS 角色
CVM 角色

把已有图片迁移到云端

迁移会把 uploads/ 目录下的图片逐个上传到当前对象存储,并按内容指纹重命名 (<md5前12位>_<随机6位>.扩展名),同时自动改写数据库里对应的图片引用, 因此已有记录不会裂图。已经是本内容指纹名的文件会跳过改名,重复迁移是安全的。
执行顺序固定为先上传 → 再改库 → 最后才删本地:任一步失败都会停下并保留本地文件, 加上"本地优先"渲染,页面不会出现裂图。云端若已存在旧名对象,会保留不删(不影响使用)。
当前未启用对象存储(或配置不完整),迁移功能暂不可用。请先选择云端存储并保存。 (提示:当前驱动配置不完整,无法上传)
尚未开始。