feat: 飞书单点登录和通知功能

This commit is contained in:
2026-02-03 11:38:16 +08:00
parent c657fbe01a
commit 78ebc67e2a
18 changed files with 2136 additions and 105 deletions

View File

@@ -1,61 +1,74 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>错误 - TaskBot</title>
<title>无权访问</title>
<script src="https://cdn.tailwindcss.com"></script>
<style>
body { font-family: 'Inter', system-ui, sans-serif; }
body {
font-family: 'Inter', system-ui, sans-serif;
}
</style>
</head>
<body class="min-h-screen bg-slate-50 flex items-center justify-center">
<div class="max-w-md w-full px-6">
<div class="text-center">
<div class="mb-6">
<svg class="w-24 h-24 mx-auto text-slate-300" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"></path>
</svg>
</div>
<h1 class="text-6xl font-bold text-slate-900 mb-2" id="error-code">404</h1>
<h2 class="text-xl font-medium text-slate-700 mb-4" id="error-title">页面未找到</h2>
<p class="text-sm text-slate-500 mb-8" id="error-message">抱歉,您访问的页面不存在或已被移除。</p>
<div class="space-y-3">
<button onclick="window.parent.switchTab('dashboard')" class="block w-full bg-indigo-600 hover:bg-indigo-700 text-white font-medium py-3 px-6 rounded-lg transition-colors">
返回控制台
</button>
</div>
</div>
<div class="mt-12 text-center">
<p class="text-xs text-slate-400">TaskBot v1.1.0</p>
<body class="bg-gray-50 flex items-center justify-center h-screen">
<div class="text-center p-8 bg-white rounded-lg shadow-lg max-w-md w-full border border-gray-100">
<div class="mb-6 inline-flex items-center justify-center w-16 h-16 rounded-full bg-red-100 text-red-500">
<svg class="w-8 h-8" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z">
</path>
</svg>
</div>
<h1 class="text-2xl font-bold text-gray-900 mb-2">访问被拒绝</h1>
<p class="text-gray-500 mb-6">您没有权限访问此页面 (系统设置)。请联系管理员获取权限。</p>
<button id="requestBtn" onclick="requestPermission()"
class="px-5 py-2 bg-indigo-600 text-white rounded-md hover:bg-indigo-700 transition-colors font-medium flex items-center justify-center mx-auto">
<span>点击发送权限请求</span>
</button>
<p id="msg" class="text-sm mt-4 h-5"></p>
</div>
<script>
const params = new URLSearchParams(window.location.search);
const code = params.get('code') || '404';
const title = params.get('title') || '';
const message = params.get('message') || '';
const errorMap = {
'400': { title: '请求错误', message: '请求参数有误,请检查后重试。' },
'401': { title: '未授权', message: '您没有权限访问此资源,请先登录。' },
'403': { title: '禁止访问', message: '您没有权限访问此页面。' },
'404': { title: '页面未找到', message: '抱歉,您访问的页面不存在或已被移除。' },
'500': { title: '服务器错误', message: '服务器遇到了一些问题,请稍后再试。' },
'503': { title: '服务不可用', message: '服务暂时不可用,请稍后再试。' },
'施工中': { title: '图形化编辑映射功能暂不可用', message: '该功能预计2026/01/30下午上线' }
};
const error = errorMap[code] || errorMap['404'];
document.getElementById('error-code').textContent = code;
document.getElementById('error-title').textContent = title || error.title;
document.getElementById('error-message').textContent = message || error.message;
document.title = `${code} ${error.title} - TaskBot`;
async function requestPermission() {
const btn = document.getElementById('requestBtn');
const msg = document.getElementById('msg');
btn.disabled = true;
btn.classList.add('opacity-50', 'cursor-not-allowed');
btn.innerHTML = '<svg class="animate-spin -ml-1 mr-2 h-4 w-4 text-white" fill="none" viewBox="0 0 24 24"><circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle><path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path></svg>发送中...';
msg.textContent = '';
msg.className = 'text-sm mt-4 h-5 text-gray-500';
try {
const res = await fetch('/api/request-permission', { method: 'POST' });
const data = await res.json();
if (data.success) {
msg.textContent = data.message;
msg.className = 'text-sm mt-4 h-5 text-emerald-600 font-medium';
btn.innerHTML = '已发送请求';
} else {
msg.textContent = data.error;
msg.className = 'text-sm mt-4 h-5 text-rose-500';
resetBtn(btn);
}
} catch (e) {
msg.textContent = e.message;
msg.className = 'text-sm mt-4 h-5 text-rose-500';
resetBtn(btn);
}
}
function resetBtn(btn) {
btn.disabled = false;
btn.classList.remove('opacity-50', 'cursor-not-allowed');
setTimeout(() => {
btn.innerHTML = '点击发送权限请求';
}, 2000);
}
</script>
</body>
</html>
</html>