2026-09-30 00:49:53 +08:00
|
|
|
<form method="post" action="<?= e(url('settings/update')) ?>" class="card card-pad">
|
|
|
|
|
<?= csrf_field() ?>
|
2026-09-30 08:13:07 +08:00
|
|
|
<h2 class="section-title">家庭</h2>
|
2026-09-30 00:49:53 +08:00
|
|
|
<div class="form-grid">
|
|
|
|
|
<div class="field full">
|
|
|
|
|
<label for="name">家庭名称</label>
|
|
|
|
|
<input class="input" id="name" name="name" value="<?= e($family['name']) ?>" required>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="field full">
|
|
|
|
|
<label for="motto">一句话</label>
|
|
|
|
|
<input class="input" id="motto" name="motto" value="<?= e($family['motto'] ?? '') ?>"
|
|
|
|
|
placeholder="展示在首页的一行小字">
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="btn-row">
|
|
|
|
|
<button class="btn" type="submit">保存</button>
|
|
|
|
|
</div>
|
|
|
|
|
</form>
|
|
|
|
|
|
2026-09-30 08:13:07 +08:00
|
|
|
<!-- ==================== 附件存储 ==================== -->
|
|
|
|
|
<form method="post" action="<?= e(url('settings/storage')) ?>" class="card card-pad" style="margin-top:20px">
|
|
|
|
|
<?= csrf_field() ?>
|
|
|
|
|
<h2 class="section-title">
|
|
|
|
|
附件存储
|
|
|
|
|
<span class="hint">头像等文件存哪儿</span>
|
|
|
|
|
</h2>
|
|
|
|
|
|
|
|
|
|
<p class="small muted" style="margin:0 0 16px">
|
|
|
|
|
数据库里只存「相对路径」,所以随时可以在本地与云端之间切换 ——
|
|
|
|
|
已上传的文件会按「本地优先」的顺序去找,切换后老文件照样能打开,出问题也能随时切回来。
|
|
|
|
|
</p>
|
|
|
|
|
|
|
|
|
|
<div class="field" style="margin-bottom:16px">
|
|
|
|
|
<label>存在哪里</label>
|
|
|
|
|
<div class="radio-row">
|
|
|
|
|
<label class="radio-item">
|
|
|
|
|
<input type="radio" name="driver" value="local" <?= $storageDriver === 'local' ? 'checked' : '' ?>>
|
|
|
|
|
<span><b>服务器本地</b><br><span class="muted small">最简单,文件和服务在一起。适合家里自己用。</span></span>
|
|
|
|
|
</label>
|
|
|
|
|
<label class="radio-item">
|
|
|
|
|
<input type="radio" name="driver" value="oss" <?= $storageDriver === 'oss' ? 'checked' : '' ?>>
|
|
|
|
|
<span><b>阿里云 OSS</b><br><span class="muted small">文件独立存放,换服务器不丢;也可以挂 CDN 加速。</span></span>
|
|
|
|
|
</label>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<?php if ($storageDriver === 'oss' && !$storageOk): ?>
|
|
|
|
|
<div class="flash"><div class="flash-item err">
|
|
|
|
|
云端配置还不完整,系统现在**临时用本地存储**在跑 —— 填全下面的信息再保存。
|
|
|
|
|
</div></div>
|
|
|
|
|
<?php elseif ($storageDriver === 'oss'): ?>
|
|
|
|
|
<div class="flash"><div class="flash-item">
|
|
|
|
|
当前生效:阿里云 OSS<?= $storageEffective === 'local' ? '(配置不完整,实际走的本地)' : '' ?>
|
|
|
|
|
</div></div>
|
|
|
|
|
<?php endif; ?>
|
|
|
|
|
|
|
|
|
|
<details class="oss-box" <?= $storageDriver === 'oss' ? 'open' : '' ?>>
|
|
|
|
|
<summary>阿里云 OSS 参数</summary>
|
|
|
|
|
<div class="form-grid" style="margin-top:14px">
|
|
|
|
|
<div class="field">
|
|
|
|
|
<label>凭据方式</label>
|
|
|
|
|
<select class="select" name="oss[auth_mode]">
|
|
|
|
|
<option value="ak" <?= $storageOss['auth_mode'] === 'ak' ? 'selected' : '' ?>>AccessKey(手动填)</option>
|
|
|
|
|
<option value="ecs_role" <?= $storageOss['auth_mode'] === 'ecs_role' ? 'selected' : '' ?>>服务器绑定角色(更安全)</option>
|
|
|
|
|
</select>
|
|
|
|
|
<span class="tip">若这台服务器是阿里云 ECS 且绑了 RAM 角色,优先用角色 —— 服务器上不落长期密钥。</span>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="field">
|
|
|
|
|
<label>Bucket</label>
|
|
|
|
|
<input class="input" name="oss[bucket]" value="<?= e($storageOss['bucket']) ?>" placeholder="例如 my-family-bucket">
|
|
|
|
|
</div>
|
|
|
|
|
<div class="field">
|
|
|
|
|
<label>Endpoint</label>
|
|
|
|
|
<input class="input" name="oss[endpoint]" value="<?= e($storageOss['endpoint']) ?>"
|
|
|
|
|
placeholder="oss-cn-beijing.aliyuncs.com">
|
|
|
|
|
<span class="tip">不要带 https://,且要和桶的地域一致。</span>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="field">
|
|
|
|
|
<label>桶内前缀</label>
|
|
|
|
|
<input class="input" name="oss[prefix]" value="<?= e($storageOss['prefix']) ?>" placeholder="可留空,如 familybook">
|
|
|
|
|
<span class="tip">一个桶放多个站点时用它隔开。</span>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="field">
|
|
|
|
|
<label>AccessKey ID</label>
|
|
|
|
|
<input class="input" name="oss[access_key_id]" value="<?= e($storageOss['access_key_id']) ?>"
|
|
|
|
|
autocomplete="off" placeholder="用角色方式时可留空">
|
|
|
|
|
</div>
|
|
|
|
|
<div class="field">
|
|
|
|
|
<label>AccessKey Secret</label>
|
|
|
|
|
<input class="input" name="oss[access_key_secret]" type="password"
|
|
|
|
|
value="<?= $storageOss['access_key_secret'] !== '' ? '••••••••••••' : '' ?>"
|
|
|
|
|
autocomplete="new-password" placeholder="留空表示不改动已保存的">
|
|
|
|
|
</div>
|
|
|
|
|
<div class="field">
|
|
|
|
|
<label>RAM 角色名</label>
|
|
|
|
|
<input class="input" name="oss[ram_role_name]" value="<?= e($storageOss['ram_role_name']) ?>"
|
|
|
|
|
placeholder="留空 = 自动取实例绑定的角色">
|
|
|
|
|
</div>
|
|
|
|
|
<div class="field">
|
|
|
|
|
<label>自定义域名 / CDN</label>
|
|
|
|
|
<input class="input" name="oss[custom_domain]" value="<?= e($storageOss['custom_domain']) ?>"
|
|
|
|
|
placeholder="可留空">
|
|
|
|
|
<span class="tip">填了会替代 bucket.endpoint 生成访问地址;该域名需已绑定到这个桶。</span>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="field full">
|
|
|
|
|
<label class="check-item">
|
|
|
|
|
<input type="checkbox" name="oss[internal_endpoint]" value="1"
|
|
|
|
|
<?= $storageOss['internal_endpoint'] === '1' ? 'checked' : '' ?>>
|
|
|
|
|
<span>服务端读取优先走内网 endpoint(服务器与桶在同地域时更快,还免流量费)</span>
|
|
|
|
|
</label>
|
|
|
|
|
<label class="check-item">
|
|
|
|
|
<input type="checkbox" name="oss[https]" value="1"
|
|
|
|
|
<?= $storageOss['https'] === '1' ? 'checked' : '' ?>>
|
|
|
|
|
<span>用 HTTPS 访问对象</span>
|
|
|
|
|
</label>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</details>
|
|
|
|
|
|
|
|
|
|
<div class="btn-row">
|
|
|
|
|
<button class="btn" type="submit">保存存储设置</button>
|
|
|
|
|
</div>
|
|
|
|
|
</form>
|
|
|
|
|
|
|
|
|
|
<form method="post" action="<?= e(url('settings/test_storage')) ?>" style="margin-top:12px">
|
|
|
|
|
<?= csrf_field() ?>
|
|
|
|
|
<button class="btn btn-ghost" type="submit">测试存储是否可用</button>
|
|
|
|
|
<span class="small muted" style="margin-left:10px">
|
|
|
|
|
会真的写一个临时文件、读回来、再删掉 —— 比只连一下可靠。
|
|
|
|
|
</span>
|
|
|
|
|
</form>
|
|
|
|
|
|
|
|
|
|
<!-- ==================== 运行环境 ==================== -->
|
2026-09-30 00:49:53 +08:00
|
|
|
<div class="card card-pad" style="margin-top:20px">
|
|
|
|
|
<h2 class="section-title">运行环境 <span class="hint">排错时看这一块</span></h2>
|
|
|
|
|
<dl class="kv">
|
|
|
|
|
<div class="kv-row"><dt>PHP</dt><dd><?= e(PHP_VERSION) ?></dd></div>
|
|
|
|
|
<div class="kv-row"><dt>数据库</dt><dd><?= e($dbVersion) ?></dd></div>
|
|
|
|
|
<div class="kv-row"><dt>加密密钥</dt><dd><?= $keyOk ? '已配置' : '<span style="color:var(--red)">未配置</span>' ?></dd></div>
|
2026-09-30 08:13:07 +08:00
|
|
|
<div class="kv-row">
|
|
|
|
|
<dt>附件存储</dt>
|
|
|
|
|
<dd><?= $storageEffective === 'oss' ? '阿里云 OSS' : '服务器本地' ?>
|
|
|
|
|
<?php if ($storageDriver !== $storageEffective): ?>
|
|
|
|
|
<span class="muted small">(设置的是 OSS,但配置不全,实际用本地)</span>
|
|
|
|
|
<?php endif; ?>
|
|
|
|
|
</dd>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="kv-row">
|
|
|
|
|
<dt>亲属连线</dt>
|
|
|
|
|
<dd><?= (int)$relCount ?> 条</dd>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="kv-row">
|
|
|
|
|
<dt>账号</dt>
|
|
|
|
|
<dd>
|
|
|
|
|
管理员 <?= (int)$roleCounts['admin'] ?> ·
|
|
|
|
|
家庭成员 <?= (int)$roleCounts['member'] ?> ·
|
|
|
|
|
访客 <?= (int)$roleCounts['guest'] ?>
|
|
|
|
|
</dd>
|
|
|
|
|
</div>
|
2026-09-30 00:49:53 +08:00
|
|
|
</dl>
|
|
|
|
|
<p class="small muted" style="margin:14px 0 0">
|
|
|
|
|
手机号与身份证号都是加密后入库的。这个密钥一旦换掉,已有数据就再也解不开 ——
|
|
|
|
|
请把它和数据库分开、各备份一份。
|
|
|
|
|
</p>
|
2026-09-30 08:13:07 +08:00
|
|
|
<p class="small muted" style="margin:10px 0 0">
|
|
|
|
|
访客账号在「<a href="<?= e(url('accounts/invite')) ?>">邀请访客</a>」里开通。
|
|
|
|
|
</p>
|
|
|
|
|
</div>
|