chore: initialize insar management system v2

This commit is contained in:
2026-04-14 13:16:01 +08:00
commit ecc72ec9cd
361 changed files with 2142522 additions and 0 deletions
@@ -0,0 +1,112 @@
import { memo } from 'react';
import { formatUtc, getStatusClass } from '../../utils/appUiHelpers';
function AppStatusHeader({
language,
setLanguage,
currentUser,
isAdmin,
isReadOnlyUser,
activeTasks,
avgTaskProgress,
licenseStatus,
healthStatus,
healthLoading,
healthError,
onRefreshHealth,
onLogout,
}) {
const hasHealthStatus = !!healthStatus;
const licenseOk = !!licenseStatus?.ok;
const dbOk = !!(healthStatus?.database?.ok && healthStatus?.database?.schema_ok && healthStatus?.database?.postgis_ok);
const workerOk = !!healthStatus?.worker?.ok;
const idlOk = !!healthStatus?.idl?.ok;
const aiOk = !!healthStatus?.ollama?.ok;
const nginxOk = !!healthStatus?.nginx?.ok;
return (
<>
<div className="top-status-bar">
<div className="status-brand">
<div className="brand-title">InSAR 自动化管理系统</div>
<div className="brand-subtitle">科研工程模式 · {licenseOk ? '已授权' : '未授权'}</div>
</div>
<div className="status-items">
<div className="status-item">
<span className={`status-dot ${getStatusClass(dbOk, hasHealthStatus)}`}></span>DB
</div>
<div className="status-item">
<span className={`status-dot ${getStatusClass(workerOk, hasHealthStatus)}`}></span>Worker
</div>
<div className="status-item">
<span className={`status-dot ${getStatusClass(idlOk, hasHealthStatus)}`}></span>IDL
</div>
<div className="status-item">
<span className={`status-dot ${getStatusClass(aiOk, hasHealthStatus)}`}></span>Ollama
</div>
<div className="status-item">
<span className={`status-dot ${getStatusClass(nginxOk, hasHealthStatus)}`}></span>Nginx
</div>
</div>
<div className="status-actions">
<div className="status-lang-switch" data-no-i18n="true">
<button
className={`status-lang-btn ${language === 'zh' ? 'active' : ''}`}
onClick={() => setLanguage('zh')}
title="切换到中文"
>
中文
</button>
<button
className={`status-lang-btn ${language === 'en' ? 'active' : ''}`}
onClick={() => setLanguage('en')}
title="Switch to English"
>
EN
</button>
</div>
<div className={`user-role-chip ${isAdmin ? 'admin' : 'viewer'}`}>
<span className="user-role-name">{currentUser.username}</span>
<span className="user-role-divider">·</span>
<span>{isAdmin ? '管理员' : '只读账号'}</span>
</div>
<div className={`status-task ${activeTasks.length > 0 ? 'has-active-tasks' : ''}`}>
<span>{activeTasks.length > 0 ? `⚙️ 运行中 ${activeTasks.length}` : '✓ 空闲'}</span>
{activeTasks.length > 0 && (
<div className="status-task-bar">
<div className="status-task-fill" style={{ width: `${avgTaskProgress}%` }}></div>
</div>
)}
</div>
{licenseStatus?.expires_at && (
<div className="status-license">
授权至 {formatUtc(licenseStatus.expires_at, language)}
</div>
)}
<button
className="status-refresh"
onClick={onRefreshHealth}
disabled={healthLoading}
title={healthError || '刷新自检状态'}
>
{healthLoading ? '自检中...' : '刷新自检'}
</button>
<button
className="status-refresh"
onClick={onLogout}
title="退出登录"
>
退出登录
</button>
</div>
</div>
{isReadOnlyUser && (
<div className="read-only-banner">
当前账号为只读权限可查看数据与状态但不能执行写操作
</div>
)}
</>
);
}
export default memo(AppStatusHeader);