feat: 飞书单点登录和通知功能
This commit is contained in:
@@ -24,14 +24,39 @@ function switchTab(tab) {
|
||||
|
||||
//如果切换到日志页,开始实时加载
|
||||
if (tab === 'logs') {
|
||||
startLogStreaming();
|
||||
checkAdminStatus().then(allowed => {
|
||||
if (allowed) {
|
||||
startLogStreaming();
|
||||
} else {
|
||||
const container = document.getElementById('content-logs');
|
||||
container.innerHTML = `
|
||||
<div class="w-full h-[calc(100vh-100px)] rounded-lg overflow-hidden bg-white shadow-sm border border-slate-200">
|
||||
<iframe src="/error.html" class="w-full h-full border-0"></iframe>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
});
|
||||
return;
|
||||
} else {
|
||||
stopLogStreaming();
|
||||
}
|
||||
|
||||
//如果切换到设置页,加载 .env 文件
|
||||
if (tab === 'settings') {
|
||||
loadEnvFile();
|
||||
checkAdminStatus().then(allowed => {
|
||||
if (allowed) {
|
||||
loadEnvFile();
|
||||
} else {
|
||||
const container = document.getElementById('content-settings');
|
||||
// 使用 iframe 嵌入错误页,保持侧边栏导航
|
||||
container.innerHTML = `
|
||||
<div class="w-full h-[calc(100vh-100px)] rounded-lg overflow-hidden bg-white shadow-sm border border-slate-200">
|
||||
<iframe src="/error.html" class="w-full h-full border-0"></iframe>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
});
|
||||
return; // 等待检查结果,暂不加载内容
|
||||
}
|
||||
|
||||
//如果切换到使用指南页,加载 README
|
||||
@@ -40,6 +65,17 @@ function switchTab(tab) {
|
||||
}
|
||||
}
|
||||
|
||||
async function checkAdminStatus() {
|
||||
try {
|
||||
const res = await fetch('/api/me');
|
||||
const data = await res.json();
|
||||
return data.loggedIn && data.isAdmin;
|
||||
} catch (e) {
|
||||
console.error('Check admin status failed:', e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
//日志流控制
|
||||
let logInterval = null;
|
||||
let lastLogSize = 0;
|
||||
@@ -101,6 +137,17 @@ function escapeHtml(text) {
|
||||
async function loadDashboardData() {
|
||||
try {
|
||||
const res = await fetch('/api/status');
|
||||
|
||||
if (res.status === 403) {
|
||||
document.getElementById('today-syncs').textContent = '无权限';
|
||||
document.getElementById('repo-count').textContent = '无权限';
|
||||
document.getElementById('error-count').textContent = '无权限';
|
||||
document.getElementById('uptime').textContent = '系统运行时间: 无权限';
|
||||
updateServiceStatus('unknown');
|
||||
loadHistory(); // 也会处理 403
|
||||
return;
|
||||
}
|
||||
|
||||
const data = await res.json();
|
||||
|
||||
if (data.success) {
|
||||
@@ -124,6 +171,13 @@ async function loadDashboardData() {
|
||||
async function loadHistory() {
|
||||
try {
|
||||
const res = await fetch('/api/history');
|
||||
|
||||
if (res.status === 403) {
|
||||
const tbody = document.getElementById('history-table');
|
||||
tbody.innerHTML = '<tr><td colspan="4" class="px-4 py-8 text-center text-sm text-slate-500">无权限查看历史记录</td></tr>';
|
||||
return;
|
||||
}
|
||||
|
||||
const data = await res.json();
|
||||
|
||||
if (data.success && data.history) {
|
||||
@@ -163,6 +217,15 @@ function updateServiceStatus(status) {
|
||||
运行中
|
||||
`;
|
||||
statusText.textContent = '运行中';
|
||||
} else if (status === 'unknown') {
|
||||
badge.className = 'px-3 py-1 rounded-full text-xs font-medium flex items-center border bg-slate-100 text-slate-600 border-slate-200';
|
||||
badge.innerHTML = `
|
||||
<svg class="w-4 h-4 mr-1" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8.228 9c.549-1.165 2.03-2 3.772-2 2.21 0 4 1.343 4 3 0 1.4-1.278 2.575-3.006 2.907-.542.104-.994.54-.994 1.093m0 3h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path>
|
||||
</svg>
|
||||
状态未知
|
||||
`;
|
||||
statusText.textContent = '状态未知';
|
||||
} else {
|
||||
badge.className = 'px-3 py-1 rounded-full text-xs font-medium flex items-center border bg-slate-100 text-slate-600 border-slate-200';
|
||||
badge.innerHTML = `
|
||||
|
||||
Reference in New Issue
Block a user