增加用户名水印,避免信息泄露
This commit is contained in:
parent
9ac36d7a41
commit
4a7376c318
@ -589,3 +589,30 @@ input[type="date"]::-webkit-calendar-picker-indicator:hover{
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
/* Watermark styles */
|
||||
.watermark {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
pointer-events: none;
|
||||
z-index: 9999;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.watermark-text {
|
||||
position: absolute;
|
||||
font-size: 16px;
|
||||
color: var(--text);
|
||||
opacity: 0.08;
|
||||
transform: rotate(-45deg);
|
||||
white-space: nowrap;
|
||||
user-select: none;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
[data-theme="light"] .watermark-text {
|
||||
opacity: 0.06;
|
||||
}
|
||||
|
||||
@ -21,6 +21,58 @@
|
||||
} else if (avatarImg) {
|
||||
avatarImg.src = './assets/user-avatar.svg';
|
||||
}
|
||||
|
||||
// 更新水印
|
||||
if (user && user.username) {
|
||||
createWatermark(user.username);
|
||||
} else {
|
||||
removeWatermark();
|
||||
}
|
||||
}
|
||||
|
||||
// 创建水印
|
||||
function createWatermark(username) {
|
||||
// 检查水印是否启用
|
||||
const watermarkEnabled = localStorage.getItem('watermarkEnabled');
|
||||
if (watermarkEnabled === 'false') {
|
||||
return;
|
||||
}
|
||||
|
||||
removeWatermark();
|
||||
|
||||
const watermarkDiv = document.createElement('div');
|
||||
watermarkDiv.id = 'watermark-container';
|
||||
watermarkDiv.className = 'watermark';
|
||||
|
||||
const now = new Date();
|
||||
const dateStr = `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, '0')}-${String(now.getDate()).padStart(2, '0')} ${String(now.getHours()).padStart(2, '0')}:${String(now.getMinutes()).padStart(2, '0')}`;
|
||||
const watermarkText = `${username} ${dateStr}`;
|
||||
|
||||
// 计算水印平铺
|
||||
const spacing = 300;
|
||||
const rows = Math.ceil(window.innerHeight / spacing) + 2;
|
||||
const cols = Math.ceil(window.innerWidth / spacing) + 2;
|
||||
|
||||
for (let i = 0; i < rows; i++) {
|
||||
for (let j = 0; j < cols; j++) {
|
||||
const span = document.createElement('span');
|
||||
span.className = 'watermark-text';
|
||||
span.textContent = watermarkText;
|
||||
span.style.left = `${j * spacing - 100}px`;
|
||||
span.style.top = `${i * spacing - 100}px`;
|
||||
watermarkDiv.appendChild(span);
|
||||
}
|
||||
}
|
||||
|
||||
document.body.appendChild(watermarkDiv);
|
||||
}
|
||||
|
||||
// 移除水印
|
||||
function removeWatermark() {
|
||||
const existing = document.getElementById('watermark-container');
|
||||
if (existing) {
|
||||
existing.remove();
|
||||
}
|
||||
}
|
||||
|
||||
Router.onBeforeEach(async (path) => {
|
||||
@ -84,6 +136,7 @@
|
||||
API.logout()
|
||||
.then(() => {
|
||||
currentUser = null;
|
||||
removeWatermark();
|
||||
updateUserDisplay(null);
|
||||
userDropdown.style.display = 'none';
|
||||
location.hash = '#/login';
|
||||
@ -130,4 +183,14 @@
|
||||
|
||||
// 暴露更新用户显示的函数,供设置页面使用
|
||||
window.updateUserDisplay = updateUserDisplay;
|
||||
|
||||
// 暴露水印控制函数
|
||||
window.toggleWatermark = function(enabled) {
|
||||
localStorage.setItem('watermarkEnabled', enabled ? 'true' : 'false');
|
||||
if (enabled && currentUser && currentUser.username) {
|
||||
createWatermark(currentUser.username);
|
||||
} else {
|
||||
removeWatermark();
|
||||
}
|
||||
};
|
||||
})();
|
||||
@ -64,6 +64,19 @@ Router.register('/settings', async () => {
|
||||
<div class="actions"><button id="change-btn" class="btn">修改密码</button></div>
|
||||
</div>
|
||||
|
||||
<div style="margin-bottom:24px;padding-bottom:24px;border-bottom:1px solid var(--border)">
|
||||
<div style="font-weight:500;margin-bottom:12px">水印设置</div>
|
||||
<div style="display:flex;align-items:center;gap:12px;padding:12px;background:var(--surface);border:1px solid var(--border);border-radius:8px">
|
||||
<label style="flex:1;cursor:pointer;display:flex;align-items:center;gap:8px">
|
||||
<input type="checkbox" id="watermark-toggle" ${localStorage.getItem('watermarkEnabled') !== 'false' ? 'checked' : ''} style="width:18px;height:18px;cursor:pointer" />
|
||||
<span style="font-size:14px">启用页面水印(显示用户名和时间戳)</span>
|
||||
</label>
|
||||
</div>
|
||||
<div style="margin-top:8px;font-size:12px;color:var(--text-2)">
|
||||
水印用于防止数据泄露和责任追溯,建议保持启用状态
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="font-weight:500;margin-bottom:12px">超级管理员工具</div>
|
||||
<div style="margin-top:12px"></div>
|
||||
<div class="grid cols-2" style="margin-top:8px">
|
||||
@ -288,6 +301,16 @@ Router.register('/settings', async () => {
|
||||
change.disabled = false;
|
||||
}
|
||||
});
|
||||
|
||||
// 水印开关
|
||||
const watermarkToggle = document.getElementById('watermark-toggle');
|
||||
watermarkToggle?.addEventListener('change', (e) => {
|
||||
const enabled = e.target.checked;
|
||||
if (window.toggleWatermark) {
|
||||
window.toggleWatermark(enabled);
|
||||
API.toast(enabled ? '水印已启用' : '水印已关闭');
|
||||
}
|
||||
});
|
||||
document.querySelectorAll('button[data-clear]')?.forEach(btn => {
|
||||
btn.addEventListener('click', async () => {
|
||||
const mod = btn.getAttribute('data-clear');
|
||||
|
||||
Loading…
Reference in New Issue
Block a user