feat(大屏): 园区登录 + 多租户 — 动态页眉名称/两段简介 + 租户 MQTT/数据

- utils/tenant.js:账密→长效 tenant token(localStorage 持久),login/logout/tenantFetch(附 tenant_id+token)。
- main.jsx 门禁:未登录显示 TenantLogin(登录页),登录后(App)。一次登录持久保持。
- PageHeader:名称+两段式简介改由 getTenantInfo()(后端 /park/auth/login 返回) 驱动,回退默认。
- mqtt.js:订阅 command/<tid>/<clientId> 与 tick/<tid>(租户频道);useMqttControl 心跳带 tenant_id。
- parkData.js:snapshot 走 tenantFetch(带 tenant_id+token),按租户取数。
- vite build 通过。
This commit is contained in:
Pine
2026-08-24 18:15:11 +08:00
parent d7c82fa9d4
commit daf6889580
7 changed files with 108 additions and 7 deletions
+9 -2
View File
@@ -7,6 +7,7 @@ import { PAGE_ORDER, usePageIndex } from '../utils/pageNav';
import { Avatar, AvatarImage, AvatarFallback } from '@appica/ui-react/avatar'
import { Sfx } from '../utils/sounds';
import { getApiBase as API_BASE } from '../config';
import { getTenantInfo } from '../utils/tenant';
/* =========================================================
共享页眉 —— 所有大屏页面统一(由 ScreenLayout 注入)
@@ -24,6 +25,12 @@ const STATUS_BY_PATH = {
export default function PageHeader() {
const navigate = useNavigate();
const location = useLocation();
// 多租户:页眉名称 + 两段式简介取自园区登录信息(后端可配置),回退默认
const tInfo = getTenantInfo() || {};
const parkName = tInfo.name || '昆明市大学生创业园';
const parkSuffix = 'OPC 智能园区数字运营中心';
const intro0 = (tInfo.intro && tInfo.intro[0]) || '云南省首家政府主办大学生创业孵化园区';
const intro1 = (tInfo.intro && tInfo.intro[1]) || '空间+孵化+融资+政策+资源+AI赋能+综合服务';
const [now, setNow] = useState(new Date());
const [aboutOpen, setAboutOpen] = useState(false);
const [gestureHit, setGestureHit] = useState(false); // 识别到手势 → 惊喜图标 3s
@@ -155,8 +162,8 @@ export default function PageHeader() {
</Avatar>
</span>
<div className="bd-header-titles">
<h1 className="bd-header-title">昆明市大学生创业园 <span className="bd-header-title-accent">· OPC 智能园区数字运营中心</span></h1>
<div className="bd-header-sub">云南省首家政府主办大学生创业孵化园区 · <span className="bd-header-content—highlights">空间+孵化+融资+政策+资源+AI赋能+综合服务</span></div>
<h1 className="bd-header-title">{parkName} <span className="bd-header-title-accent">· {parkSuffix}</span></h1>
<div className="bd-header-sub">{intro0} · <span className="bd-header-content—highlights">{intro1}</span></div>
</div>
{location.pathname !== '/screen' && (
<span className="bd-credit">