142 行
7.5 KiB
PHP
142 行
7.5 KiB
PHP
<?php
|
|
require __DIR__ . '/includes/init.php';
|
|
requireLogin('settings.php');
|
|
$pageTitle = __('settings_page.title');
|
|
$stmt = db()->prepare('SELECT id, username, email, nickname, verified, is_admin, status, avatar FROM ' . tn('users') . ' WHERE id = ?');
|
|
$stmt->execute([$_SESSION['user_id']]);
|
|
$user = $stmt->fetch();
|
|
$msg = '';
|
|
$msgOk = false;
|
|
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
|
verifyCsrf();
|
|
$u = trim($_POST['username'] ?? '');
|
|
$em = trim($_POST['email'] ?? '');
|
|
$nk = trim($_POST['nickname'] ?? '');
|
|
if (mb_strlen($u) < 3) $msg = __('settings_page.err_username_short');
|
|
elseif (!filter_var($em, FILTER_VALIDATE_EMAIL)) $msg = __('settings_page.err_email_invalid');
|
|
elseif ($nk !== '' && mb_strlen($nk) > 30) $msg = __('settings_page.err_nickname_long');
|
|
if ($msg === '') {
|
|
$chk = db()->prepare('SELECT id FROM ' . tn('users') . ' WHERE username = ? AND id <> ?');
|
|
$chk->execute([$u, $user['id']]);
|
|
if ($chk->fetch()) {
|
|
$msg = __('settings_page.err_username_taken');
|
|
} else {
|
|
$emailChanged = ($em !== $user['email']);
|
|
db()->prepare('UPDATE ' . tn('users') . ' SET username = ?, email = ?, nickname = ? WHERE id = ?')
|
|
->execute([$u, $em, $nk, $user['id']]);
|
|
if ($emailChanged && !empty($user['verified'])) {
|
|
db()->prepare('UPDATE ' . tn('users') . ' SET verified = 0 WHERE id = ?')
|
|
->execute([$user['id']]);
|
|
}
|
|
$stmt->execute([$user['id']]);
|
|
$user = $stmt->fetch();
|
|
$msg = $emailChanged ? __('settings_page.saved_email_change') : __('settings_page.saved');
|
|
$msgOk = true;
|
|
}
|
|
}
|
|
}
|
|
require 'includes/header.php';
|
|
?>
|
|
<section class="section">
|
|
<h2 class="sec-title"><i class="fas fa-cog"></i> <?= __('settings_page.title') ?></h2>
|
|
<?php if ($msg): ?>
|
|
<p class="<?= $msgOk ? 'banner-ok' : 'form-err' ?>"><?= h($msg) ?></p>
|
|
<?php endif; ?>
|
|
<form method="post" action="" class="grid-form settings-form">
|
|
<?= csrfField() ?>
|
|
<!-- 头像上传 -->
|
|
<div class="span2" style="margin-bottom:18px">
|
|
<h3 style="color:var(--primary);font-size:1.05rem;margin-bottom:12px"><i class="fas fa-camera"></i> <?= __('settings_page.avatar_section') ?></h3>
|
|
<div style="display:flex;align-items:center;gap:16px;flex-wrap:wrap">
|
|
<div id="avatarPreviewWrap" style="width:80px;height:80px;border-radius:50%;overflow:hidden;background:var(--primary-container);display:flex;align-items:center;justify-content:center;border:3px solid var(--outline);flex-shrink:0">
|
|
<?php if (!empty($user['avatar'])): ?>
|
|
<img src="<?= h($user['avatar']) ?>" alt="" style="width:100%;height:100%;object-fit:cover">
|
|
<?php else: ?>
|
|
<span style="font-size:1.8rem;font-weight:700;color:var(--on-primary-container)"><?= h(avatarText($user['nickname'] ?: $user['username'])) ?></span>
|
|
<?php endif; ?>
|
|
</div>
|
|
<div>
|
|
<label for="avatarInput" class="btn btn-sm btn-ghost" style="cursor:pointer;display:inline-flex;align-items:center;gap:6px">
|
|
<i class="fas fa-upload"></i> <?= __('settings_page.select_image') ?>
|
|
</label>
|
|
<input type="file" id="avatarInput" accept="image/jpeg,image/png,image/webp,image/gif" style="display:none">
|
|
<p style="font-size:.8rem;color:var(--muted);margin-top:4px"><?= __('settings_page.avatar_hint') ?></p>
|
|
</div>
|
|
</div>
|
|
<p id="avatarMsg" style="font-size:.88rem;margin-top:6px"></p>
|
|
</div>
|
|
<label><?= __('auth.username') ?><input type="text" name="username" value="<?= h($user['username']) ?>" required></label>
|
|
<label><?= __('auth.email') ?><input type="email" name="email" value="<?= h($user['email']) ?>" required></label>
|
|
<label class="span2"><?= __('user.nickname') ?><input type="text" name="nickname" value="<?= h($user['nickname']) ?>" placeholder="<?= __('settings_page.nickname_placeholder') ?>" maxlength="30"></label>
|
|
<div class="form-actions span2">
|
|
<button type="submit" class="btn btn-primary"><?= __('settings_page.save_btn') ?></button>
|
|
<a href="myorders.php" class="btn btn-ghost"><?= __('settings_page.back_orders') ?></a>
|
|
</div>
|
|
</form>
|
|
<div class="panel verify-panel">
|
|
<h3><i class="fas fa-envelope-circle-check"></i> <?= __('settings_page.verify_section') ?></h3>
|
|
<?php if (!empty($user['verified'])): ?>
|
|
<p class="ok-line"><i class="fas fa-circle-check"></i> <?= __('settings_page.verify_done') ?></p>
|
|
<?php else: ?>
|
|
<p class="warn-line"><i class="fas fa-triangle-exclamation"></i> <?= str_replace('{link}', '<a href="verify.php?resend=1">' . __('settings_page.verify_send_link') . '</a>', __('settings_page.verify_not_done')) ?></p>
|
|
<?php endif; ?>
|
|
</div>
|
|
</section>
|
|
<script>
|
|
(function () {
|
|
var input = document.getElementById('avatarInput');
|
|
var msg = document.getElementById('avatarMsg');
|
|
var wrap = document.getElementById('avatarPreviewWrap');
|
|
if (!input) return;
|
|
input.addEventListener('change', function () {
|
|
if (!input.files || !input.files[0]) return;
|
|
var file = input.files[0];
|
|
if (file.size > 2 * 1024 * 1024) {
|
|
msg.textContent = '<?= __('settings_page.img_too_big') ?>';
|
|
msg.style.color = 'var(--danger)';
|
|
return;
|
|
}
|
|
var reader = new FileReader();
|
|
reader.onload = function (e) {
|
|
wrap.innerHTML = '<img src="' + e.target.result + '" alt="" style="width:100%;height:100%;object-fit:cover;border-radius:50%">';
|
|
};
|
|
reader.readAsDataURL(file);
|
|
msg.textContent = '<?= __('settings_page.uploading') ?>';
|
|
msg.style.color = 'var(--muted)';
|
|
var fd = new FormData();
|
|
fd.append('avatar', file);
|
|
fd.append('csrf_token', Fnw.csrf());
|
|
var xhr = new XMLHttpRequest();
|
|
xhr.open('POST', 'avatar_upload.php', true);
|
|
xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
|
|
xhr.onload = function () {
|
|
if (xhr.status === 200) {
|
|
try { var res = JSON.parse(xhr.responseText); } catch (e) { res = { ok: false, msg: '<?= __('settings_page.response_err') ?>' }; }
|
|
if (res.ok) {
|
|
msg.textContent = res.msg || '<?= __('settings_page.upload_ok') ?>';
|
|
msg.style.color = 'var(--ok)';
|
|
updateAvatars(res.data.url);
|
|
} else {
|
|
msg.textContent = res.msg || '<?= __('settings_page.upload_fail') ?>';
|
|
msg.style.color = 'var(--danger)';
|
|
}
|
|
} else {
|
|
msg.textContent = '<?= str_replace('{code}', "' + xhr.status + '", __('settings_page.network_err')) ?>';
|
|
msg.style.color = 'var(--danger)';
|
|
}
|
|
};
|
|
xhr.onerror = function () {
|
|
msg.textContent = '<?= __('settings_page.network_retry') ?>';
|
|
msg.style.color = 'var(--danger)';
|
|
};
|
|
xhr.send(fd);
|
|
});
|
|
function updateAvatars(url) {
|
|
document.querySelectorAll('.avatar, .uc-avatar').forEach(function (el) {
|
|
el.innerHTML = '<img src="' + url + '" alt="" style="width:100%;height:100%;object-fit:cover;border-radius:50%">';
|
|
});
|
|
}
|
|
})();
|
|
</script>
|
|
<?php require 'includes/footer.php'; ?>
|