diff --git a/VERSIONS.json b/VERSIONS.json index 0ca6fc1..28571c8 100644 --- a/VERSIONS.json +++ b/VERSIONS.json @@ -1,7 +1,7 @@ { "project": "ems-frontend-template", - "project_version": "1.3.0", - "core_version": "1.3.0", + "project_version": "1.4.0", + "core_version": "1.4.0", "last_updated": "2026-04-06", - "notes": "Generic branding, removed all Tianpu-specific hardcoding" + "notes": "Version display on login + sidebar for field engineers" } diff --git a/package.json b/package.json index 4ae3628..b940996 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "frontend", "private": true, - "version": "1.3.0", + "version": "1.4.0", "type": "module", "scripts": { "dev": "vite", diff --git a/src/layouts/MainLayout.tsx b/src/layouts/MainLayout.tsx index 23415ad..0028ca9 100644 --- a/src/layouts/MainLayout.tsx +++ b/src/layouts/MainLayout.tsx @@ -12,7 +12,7 @@ import { import { Outlet, useNavigate, useLocation } from 'react-router-dom'; import { useTranslation } from 'react-i18next'; import { getUser, removeToken } from '../utils/auth'; -import { getAlarmStats, getAlarmEvents } from '../services/api'; +import { getAlarmStats, getAlarmEvents, getVersion } from '../services/api'; import { useTheme } from '../contexts/ThemeContext'; const { Header, Sider, Content } = Layout; @@ -28,6 +28,7 @@ export default function MainLayout() { const [collapsed, setCollapsed] = useState(false); const [alarmCount, setAlarmCount] = useState(0); const [recentAlarms, setRecentAlarms] = useState([]); + const [versionInfo, setVersionInfo] = useState(null); const navigate = useNavigate(); const location = useLocation(); const user = getUser(); @@ -93,6 +94,10 @@ export default function MainLayout() { return () => clearInterval(timer); }, [fetchAlarms]); + useEffect(() => { + getVersion().then(setVersionInfo).catch(() => {}); + }, []); + const handleLogout = () => { removeToken(); localStorage.removeItem('user'); @@ -136,6 +141,14 @@ export default function MainLayout() { } }} /> + {!collapsed && versionInfo && ( +
+ v{versionInfo.project_version} +
+ )}
(null); const navigate = useNavigate(); + useEffect(() => { + getVersion().then(setVersionInfo).catch(() => {}); + }, []); + const doLogin = async (username: string, password: string) => { const res: any = await login(username, password); setToken(res.access_token); @@ -82,6 +87,11 @@ export default function LoginPage() { + {versionInfo && ( +
+ v{versionInfo.project_version} | Core: v{versionInfo.core_version || '—'} +
+ )} ); diff --git a/src/services/api.ts b/src/services/api.ts index 881ec23..46a764d 100644 --- a/src/services/api.ts +++ b/src/services/api.ts @@ -342,6 +342,9 @@ export const getStrategySavingsReport = (params: Record) => api.get export const getStrategyRecommendations = () => api.get('/strategy/recommendations'); export const simulateStrategy = (data: any) => api.post('/strategy/simulate', data); +// Version info (no auth required) +export const getVersion = () => api.get('/version').then(r => r.data); + // Weather (气象数据) export const getWeatherCurrent = () => api.get('/weather/current'); export const getWeatherForecast = (params?: Record) => api.get('/weather/forecast', { params });