From 26d59190c9736dfcdac291b18c4b13c4860eb80f Mon Sep 17 00:00:00 2001 From: kkfluous Date: Wed, 15 Apr 2026 18:42:43 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=B0=8F=E7=A8=8B=E5=BA=8F=20webview?= =?UTF-8?q?=20=E5=86=85=E7=82=B9=E5=85=A8=E5=B1=8F=E7=9B=91=E6=8E=A7?= =?UTF-8?q?=E8=87=AA=E5=8A=A8=20CSS=20=E6=A8=AA=E5=B1=8F=EF=BC=8C=E7=89=88?= =?UTF-8?q?=E6=9C=AC=E5=8F=B7=201.1.4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 小程序 webview 无法调用系统旋转 API,竖屏全屏体验很差。检测到微信/抖音/ 支付宝小程序 UA 且当前为竖屏时,全屏覆盖层用 transform: rotate(90deg) 配合 100vh × 100vw 的尺寸模拟真横屏,用户用横屏姿势看设备即可获得横屏 监控面板。浏览器会自动把触摸坐标映射回旋转前坐标系,交互不受影响。 Co-Authored-By: Claude Opus 4.6 (1M context) --- package.json | 2 +- src/modules/mileage/MonitoringView.tsx | 38 ++++++++++++++++++++++---- 2 files changed, 34 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index 273d366..9624f62 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "ln-bi", "private": true, - "version": "1.1.3", + "version": "1.1.4", "type": "module", "scripts": { "dev": "concurrently -n server,client -c blue,green \"npm run dev:server\" \"npm run dev:client\"", diff --git a/src/modules/mileage/MonitoringView.tsx b/src/modules/mileage/MonitoringView.tsx index 21f8387..194e058 100644 --- a/src/modules/mileage/MonitoringView.tsx +++ b/src/modules/mileage/MonitoringView.tsx @@ -7,6 +7,7 @@ import { } from 'lucide-react'; import type { MonitoringVehicle, MonitoringStats, MonitoringFilters } from './types'; import { fetchMonitoring } from './api'; +import Blur from '../../components/Blur'; const SearchableSelect = ({ options, @@ -278,6 +279,20 @@ export default function MonitoringView() { return () => { document.body.style.overflow = ''; }; }, [isFullscreen]); + // 检测是否在小程序 webview 中(微信/抖音/支付宝等),且当前是竖屏 + // 小程序 webview 无法调用系统旋转 API,只能用 CSS rotate 强制横屏 + const forceLandscape = useMemo(() => { + if (typeof window === 'undefined') return false; + const ua = navigator.userAgent || ''; + const isMiniProgram = + /miniProgram/i.test(ua) || + /toutiaomicroapp/i.test(ua) || + /AlipayClient/i.test(ua) || + (window as any).__wxjs_environment === 'miniprogram'; + const isPortrait = window.innerHeight > window.innerWidth; + return isMiniProgram && isPortrait; + }, [isFullscreen]); + return ( <> {/* 顶部哨兵:离开视口时显示回到顶部按钮 */} @@ -290,7 +305,20 @@ export default function MonitoringView() { initial={{ opacity: 0 }} animate={{ opacity: 1 }} exit={{ opacity: 0 }} - className="fixed inset-0 z-[100] bg-slate-950 flex flex-col overflow-hidden" + className="fixed z-[100] bg-slate-950 flex flex-col overflow-hidden" + style={ + forceLandscape + ? { + // 小程序 webview 无法真横屏,强制 CSS 旋转 90 度模拟横屏 + top: 0, + left: '100vw', + width: '100vh', + height: '100vw', + transform: 'rotate(90deg)', + transformOrigin: 'top left', + } + : { top: 0, left: 0, right: 0, bottom: 0 } + } > {/* Top bar: compact inline KPI */}
@@ -458,8 +486,8 @@ export default function MonitoringView() {
- {v.plate} - {v.customer || '-'} + {v.plate} + {v.customer || '-'} {v.rentStatus || '-'} {v.department || '-'} @@ -829,14 +857,14 @@ export default function MonitoringView() {
- {v.plate} + {v.plate} {v.isOnline ? '在线' : '离线'}
{v.rentStatus || ''}{v.department ? ` · ${v.department.replace('业务', '')}` : ''} - {v.customer || '-'} + {v.customer || '-'}