接入移动端原生扫码能力

新增 scanner.scanQrCode HostBridge 契约与二维码结果归一。

接入 Expo Camera 扫码 overlay 并保留 H5 浏览器扫码回退。

让 Tauri 白名单识别扫码 method 但不声明桌面扫码能力。

同步原生壳门禁、Expo 权限检查、方案文档和共享决策记录。
This commit is contained in:
2026-06-19 05:13:21 +08:00
parent a471e69455
commit e4b9cbf09d
26 changed files with 758 additions and 28 deletions
@@ -16,6 +16,7 @@ type BarcodeDetectorConstructorLike = new (options?: {
export type PlatformProfileQrScannerModalProps = {
error: string | null;
mode?: 'camera' | 'resultOnly';
result: string | null;
onClose: () => void;
onError: (message: string) => void;
@@ -37,6 +38,7 @@ function getBarcodeDetectorConstructor(): BarcodeDetectorConstructorLike | null
*/
export function PlatformProfileQrScannerModal({
error,
mode = 'camera',
result,
onClose,
onError,
@@ -47,7 +49,7 @@ export function PlatformProfileQrScannerModal({
useEffect(() => {
const videoElement = videoRef.current;
if (!videoElement) {
if (!videoElement || mode === 'resultOnly') {
return;
}
@@ -141,7 +143,7 @@ export function PlatformProfileQrScannerModal({
clearScanTimer();
stopCamera();
};
}, [onError, onResult]);
}, [mode, onError, onResult]);
return (
<PlatformProfileModalShell
@@ -162,15 +164,17 @@ export function PlatformProfileQrScannerModal({
/>
</div>
<div className="space-y-3 px-5 py-5">
<div className="platform-qr-scanner-modal__viewport">
<video
ref={videoRef}
className="h-full w-full object-cover"
playsInline
muted
/>
<span className="platform-qr-scanner-modal__frame" />
</div>
{mode === 'camera' ? (
<div className="platform-qr-scanner-modal__viewport">
<video
ref={videoRef}
className="h-full w-full object-cover"
playsInline
muted
/>
<span className="platform-qr-scanner-modal__frame" />
</div>
) : null}
{result ? (
<PlatformStatusMessage
tone="success"