!DOCTYPE html html lang=zh-HK head meta charset=UTF-8 meta name=viewport content=width=device-width, initial-scale=1.0, viewport-fit=cover title西鐵紅van通title style root { --primary-color #7A1F1F; 招牌深邃棗紅 --accent-color #FFD700; 高對比亮黃 --bg-color #121212; 暗黑背景 --text-light #FFFFFF; --success-color #2ecc71; 綠色 --danger-color #e74c3c; 亮紅色 --panel-bg #1e1e1e; --warning-bar #f39c12; } { margin 0; padding 0; box-sizing border-box; font-family sans-serif; } body { background-color var(--bg-color); color var(--text-light); padding-top 75px; padding-bottom 100px; min-height 100vh; display flex; flex-direction column; } 頂部導航欄 (強制雙行置中) .top-bar { position fixed; top 0; left 0; width 100%; background-color var(--primary-color); padding 10px 0; text-align center; box-shadow 0 2px 10px rgba(0,0,0,0.5); z-index 1000; } .top-bar .company-name { color var(--accent-color); font-size 1.1rem; font-weight bold; } .top-bar .developer-name { color var(--accent-color); font-size 0.8rem; opacity 0.9; } 網絡斷線動態提示條 .status-toast { background-color var(--warning-bar); color #000; text-align center; padding 6px; font-size 0.85rem; font-weight bold; position fixed; top 65px; left 0; width 100%; z-index 999; display none; } .main-container { flex 1; padding 15px; max-width 600px; margin 0 auto; width 100%; } .app-header { text-align center; margin 15px 0; } .app-header h1 { color var(--accent-color); font-size 2.2rem; } ☕ 轉數快打賞 .coffee-box { background linear-gradient(135deg, #2c1f1f, #1f1414); border 2px dashed var(--accent-color); border-radius 12px; padding 15px; text-align center; margin-bottom 20px; } .fps-code { display inline-block; background-color var(--primary-color); color var(--accent-color); padding 6px 12px; font-size 1.2rem; font-weight bold; border-radius 6px; cursor pointer; } 角色登入區 .login-section { background-color var(--panel-bg); border 1px solid #333; border-radius 12px; padding 20px; margin-bottom 20px; } .login-section h2 { color var(--accent-color); margin-bottom 15px; font-size 1.3rem; text-align center; } .phone-input { width 100%; padding 12px; background-color #000; border 1px solid #444; color #fff; font-size 1.1rem; border-radius 8px; margin-bottom 15px; text-align center; } .btn-login-group { display flex; flex-direction column; gap 12px; } .btn-universal { background-color var(--primary-color); color var(--accent-color); padding 14px; border 1px solid var(--accent-color); border-radius 8px; font-size 1.05rem; font-weight bold; cursor pointer; transition background-color 0.1s; } .btn-universalactive { background-color #551313; } 🔒 司機未授權攔截 .approval-waiting-panel { background-color #2c1a1a; border 2px solid var(--danger-color); border-radius 12px; padding 25px; text-align center; margin-bottom 20px; display none; } .approval-waiting-panel h3 { color var(--danger-color); margin-bottom 15px; } 工作台主區 .core-workspace { display none; } .matrix-title { color var(--accent-color); font-size 1.2rem; margin-bottom 12px; border-left 5px solid var(--primary-color); padding-left 10px; font-weight bold; } 路線配置操作區 .route-config-panel { background-color var(--panel-bg); border 1px solid #333; border-radius 12px; padding 15px; margin-bottom 20px; } .route-select-box { width 100%; padding 12px; background-color #000; border 2px solid var(--primary-color); color #fff; font-size 1.1rem; border-radius 8px; margin-bottom 12px; font-weight bold; } .custom-route-input { width 100%; padding 10px; background-color #000; border 1px solid #555; color #fff; border-radius 6px; margin-bottom 12px; display none; } 大輝哥超級指揮總台 .super-admin-panel { background linear-gradient(135deg, #3a0d0d, #1e1e1e); border 2px solid var(--accent-color); border-radius 12px; padding 20px; margin-bottom 25px; display none; } .super-grid { display grid; grid-template-columns repeat(2, 1fr); gap 12px; margin-top 15px; } .btn-super-power { background-color #000; color var(--accent-color); border 1px solid var(--accent-color); padding 12px 10px; font-size 0.9rem; font-weight bold; border-radius 6px; cursor pointer; text-align center; } 🚖 司機端工作台 .driver-seats-panel { background-color #1a252f; border 1px solid #34495e; border-radius 12px; padding 15px; margin-bottom 25px; display none; } .seat-config-row { display flex; gap 10px; margin-bottom 15px; } .btn-seat-choice { flex 1; padding 10px; background-color #2c3e50; color #fff; border 1px solid #7f8c8d; border-radius 6px; font-weight bold; cursor pointer; } .btn-seat-choice.active { background-color var(--accent-color); color #000; border-color var(--accent-color); } .counter-row { display flex; justify-content space-between; align-items center; background-color #000; padding 15px; border-radius 8px; margin-bottom 15px; } .counter-display { font-size 1.8rem; font-weight bold; color var(--accent-color); line-height 1.3; } .counter-btn-group { display flex; gap 10px; } .btn-counter { width 55px; height 55px; border-radius 8px; border none; font-size 1.8rem; font-weight bold; cursor pointer; background-color var(--primary-color); color var(--accent-color); } .btn-full-trigger { background-color var(--success-color); color #fff; width 100%; padding 14px; border none; border-radius 8px; font-size 1.1rem; font-weight bold; cursor pointer; transition all 0.2s ease; } .btn-full-trigger.is-full { background-color var(--danger-color) !important; } 👤 乘客端看板 .passenger-view-panel { display none; } .live-status-card { background-color var(--panel-bg); border 1px solid #333; border-radius 12px; padding 20px; text-align center; box-shadow 0 4px 6px rgba(0,0,0,0.3); margin-bottom 20px; } .live-route-display { font-size 1.2rem; font-weight bold; color var(--accent-color); margin-bottom 15px; } .live-seats-display { font-size 2.2rem; font-weight bold; margin-bottom 15px; } @keyframes pulse-gps { 0% { transform scale(1); box-shadow 0 0 0 0 rgba(46, 204, 113, 0.7); } 70% { transform scale(1.02); box-shadow 0 0 0 10px rgba(46, 204, 113, 0); } 100% { transform scale(1); box-shadow 0 0 0 0 rgba(46, 204, 113, 0); } } .btn-gps-active { background-color var(--success-color) !important; color #fff !important; animation pulse-gps 1.5s infinite; } 西鐵群組真實通訊攻略 .comm-guide-grid { display grid; grid-template-columns repeat(2, 1fr); gap 12px; margin-bottom 25px; } .comm-card { background-color #1e1e1e; border 1px solid #444; border-radius 10px; padding 15px; text-align center; } .comm-card h4 { color var(--accent-color); margin-bottom 8px; font-size 1.1rem; } .comm-card p { font-size 0.8rem; color #aaa; margin-bottom 10px; } .debug-console { background-color #000; border 1px solid #222; border-radius 8px; padding 12px; font-family monospace; font-size 0.8rem; color #39ff14; height 110px; overflow-y auto; margin-top 15px; } 底部導航 .bottom-nav { position fixed; bottom 0; left 0; width 100%; background-color #1a1a1a; border-top 1px solid #333; display flex; justify-content space-around; padding-top 12px; padding-bottom calc(12px + env(safe-area-inset-bottom)); z-index 1000; } .nav-item { background none; border none; color #888; font-size 0.95rem; font-weight bold; cursor pointer; } .nav-item.active { color var(--accent-color); } .logout-box { text-align right; margin-bottom 10px; } .btn-logout { background none; border none; color #aaa; font-size 0.85rem; text-decoration underline; cursor pointer; } style head body div class=top-bar div class=company-name浚鍵管理有限公司div div class=developer-name開發者-大輝div div div class=status-toast id=statusToast📡 正在連接西鐵紅van通實時中樞...div div class=main-container div class=app-header h1西鐵紅van通h1 div div class=coffee-box p☕ 如果覺得 App 好用,請大輝飲杯咖啡啦!p div class=fps-code onclick=copyFPS()轉數快碼 122891914div div div class=login-section id=loginSection h2系統角色登入驗證h2 input type=number class=phone-input id=phoneInput placeholder=請輸入香港手機號碼 div class=btn-login-group button class=btn-universal onclick=doLogin('Passenger')👤 乘客安全登入button button class=btn-universal onclick=doLogin('Driver')🚖 司機審批登入button button class=btn-universal onclick=doLogin('SuperAdmin')⚡ 超級版主大輝入口button div div div class=approval-waiting-panel id=approvalWaitingPanel h3🚖 浚鍵管理安全系統提示h3 p style=line-height 1.6; margin-bottom 15px;您的帳號正在審核中,目前【未獲授權】。br請耐心等待版主大輝批准後方可開工使用。p button class=btn-universal style=width 100%; padding 10px; font-size 0.9rem; onclick=doLogout(true)返回登入主頁button div div class=core-workspace id=coreWorkspace div class=logout-box button class=btn-logout onclick=doLogout()[ 🔄 登出 切換角色 ]button div div class=super-admin-panel id=superAdminPanel div style=display flex; justify-content space-between; align-items center; margin-bottom 10px; span style=font-weight bold; color var(--accent-color); font-size 1.2rem;⚡ 大輝超級指揮總台span div div style=background-color#000; padding10px; border-radius6px; font-size0.9rem; margin-bottom10px; 📋 申請開工司機:span id=pendingDriverDisplay style=colorvar(--accent-color); font-weightbold;暫無新申請span button id=btnApproveDriver class=btn-universal style=padding4px 10px; font-size0.8rem; floatright; margin-top-3px; displaynone; onclick=approveDriverAction()親自批准開工button div div class=super-grid button class=btn-super-power onclick=superAction('RESET_ALL')🔄 全線數據強制歸零button button class=btn-super-power onclick=superAction('BLOCK_USER')🚫 強制永久封鎖用家button button class=btn-super-power onclick=superAction('CALC_PAYROLL')💰 計算司機當班薪酬button button class=btn-super-power onclick=superAction('BROADCAST')📢 全港車隊緊急廣播button div div div class=workspace-role-header id=workspaceTitle style=font-weight bold; color var(--accent-color); margin-bottom 15px; font-size 1.1rem; text-align center;實時智慧工作台div div class=route-config-panel div style=font-weight bold; margin-bottom 8px; color var(--accent-color);🗺️ 當班營運路線配置div select class=route-select-box id=routeSelect onchange=handleRouteSelectChange() option value=ROUTE_01大棠黃泥墩 ⇄ 元朗西鐵站option option value=ROUTE_02錦田水流田 ⇄ 元朗西鐵站option option value=ROUTE_CUSTOM➕ [自由路線輸入]option select input type=text class=custom-route-input id=customRouteInput placeholder=請手動輸入自訂起點及終點 (如 屯門 ⇄ 旺角) oninput=syncLiveDisplay() button class=btn-universal style=width100%; padding 10px; font-size 0.95rem; id=btnReverseRoute onclick=reverseRoute()🔄 起點與終點對調按鈕button div div class=driver-seats-panel id=driverSeatsPanel div style=font-weight bold; margin-bottom 8px; color var(--accent-color);🚖 司機座位實時申報系統div div class=seat-config-row button class=btn-seat-choice active id=btnSeat16 onclick=setTotalSeats(16)16 座舊款車button button class=btn-seat-choice id=btnSeat19 onclick=setTotalSeats(19)19 座新款車button div div class=counter-row div div style=font-size0.85rem; color#aaa;已上車乘客 (從0開始)div div class=counter-display id=passengerCountDisplay style=color #fff;0 人div div div div style=font-size0.85rem; color#aaa;實時賸餘空位div div class=counter-display id=emptySeatsDisplay16 個位div div div class=counter-btn-group button class=btn-counter onclick=adjustPassengers(-1)-button button class=btn-counter onclick=adjustPassengers(1)+button div div button class=btn-full-trigger id=btnFullHouse onclick=triggerFullHouse()申報滿座button div div class=passenger-view-panel id=passengerViewPanel div style=font-weight bold; margin-bottom 8px; color var(--accent-color);👤 實時紅VAN當班狀態看板div div class=live-status-card div class=live-route-display id=liveRouteName大棠黃泥墩 ⇄ 元朗西鐵站div div class=live-seats-display id=liveSeatsText🚺 剩餘空位 16div button class=btn-universal style=width100%; transition all 0.3s; id=btnReservePassenger onclick=triggerPassengerGpsRadar(this)📡 我在此上車button div div div class=matrix-title💬 西鐵紅van通群組通訊攻略div div class=comm-guide-grid div class=comm-card h4西鐵 A 群組h4 p車務調度留位中心p button class=btn-universal style=padding 8px 12px; font-size 0.9rem; width 100%; onclick=joinTrueGroup('httpschat.whatsapp.comBAK4sPyQjDP61OXfTXxxdT')進入 A 群button div div class=comm-card h4西鐵 B 群組h4 p車務調度留位中心p button class=btn-universal style=padding 8px 12px; font-size 0.9rem; width 100%; onclick=joinTrueGroup('httpschat.whatsapp.comDP7vMUnUEQtC63BB4Xel4S')進入 B 群button div div class=comm-card h4西鐵 C 群組h4 p車務調度留位中心p button class=btn-universal style=padding 8px 12px; font-size 0.9rem; width 100%; onclick=joinTrueGroup('httpschat.whatsapp.comFGWXQ7MbxlpK9zxLp2Cxk4')進入 C 群button div div class=comm-card h4西鐵 D 群組h4 p車務調度留位中心p button class=btn-universal style=padding 8px 12px; font-size 0.9rem; width 100%; onclick=joinTrueGroup('httpschat.whatsapp.comGJQxt5dxf2qJugAODTDB1M')進入 D 群button div div div class=matrix-title系統實時日誌div div class=debug-console id=debugConsole[系統提示] 請先完成角色登入。div div div nav class=bottom-nav button class=nav-item activespan[ 主頁 ]spanbutton button class=nav-item onclick=window.open('httpswww.google.commaps@22.3954,113.9749,16z', '_blank')span[ 地圖 ]spanbutton button class=nav-item onclick=window.open('httpsapi.whatsapp.comsendphone=&text=你好,大輝哥!我想查詢西鐵紅van通群組調度事宜。', '_blank')span[ 通訊 ]spanbutton nav script let state = { role '', phone '', currentRouteTitle '大棠黃泥墩 ⇄ 元朗西鐵站', totalSeats 16, passengers 0, isReversed false }; const NetworkHub = { socket null, 💡 大輝哥!放上 Cloudflare 後,將下面呢行換成你專屬嘅真 Workers wss 網址即可! wsUrl 'wssyour-van-worker.dahui.workers.dev', init function() { if(state.role === '') return; logToConsole(`🌐 正在建立全港實時數據連動 (WebSocket)...`); document.getElementById('statusToast').style.display = 'block'; document.getElementById('statusToast').innerText = 📡 正在同步雲端車務數據中...; try { this.socket = new WebSocket(this.wsUrl); this.socket.onopen = () = { logToConsole(⚡ [網絡對接] 成功連通雲端總台!實時零延遲同步解鎖。); document.getElementById('statusToast').style.display = 'none'; this.broadcastToServer({ type 'auth', userId state.phone, role state.role }); }; this.socket.onmessage = (event) = { try { const data = JSON.parse(event.data); this.handleIncomingBroadcast(data); } catch (e) {} }; this.socket.onclose = () = { document.getElementById('statusToast').style.display = 'block'; document.getElementById('statusToast').innerText = ⚠️ 訊號微弱!正在發動 Tunnel-Proof 全自動重連保護...; logToConsole(⚠️ 網絡連線斷開,5秒後全自動重新對接後端...); setTimeout(() = this.init(), 5000); }; } catch (err) { console.log(WS 異常,切換至沙盒沙箱環境。); } }, broadcastToServer function(msgObj) { if (this.socket && this.socket.readyState === WebSocket.OPEN) { this.socket.send(JSON.stringify(msgObj)); } }, handleIncomingBroadcast function(data) { if (data.type === SEAT_SYNC && state.role === Passenger) { state.totalSeats = data.totalSeats; state.passengers = data.passengers; state.currentRouteTitle = data.routeTitle; logToConsole(`🔔 [即時更新] 司機已動態更新座位!剩餘空位:${data.totalSeats - data.passengers}`); syncUI(false); } if (data.type === SYSTEM_SHUTDOWN) { alert(data.message); doLogout(true); } if (data.type === EMERGENCY_ALERT) { alert(`【大輝哥全線緊急公告】nn${data.message}`); logToConsole(`📢 收到全體公告 ${data.message}`); } } }; let passengerGpsWatchId = null; if(localStorage.getItem('van_realtime_state')) { state = JSON.parse(localStorage.getItem('van_realtime_state')); } let approvedDriversList = JSON.parse(localStorage.getItem('van_approved_drivers')) []; let pendingDriverPhone = localStorage.getItem('van_pending_driver') ''; function saveState(triggerNetworkBroadcast = true) { localStorage.setItem('van_realtime_state', JSON.stringify(state)); syncUI(); if (triggerNetworkBroadcast && (state.role === 'Driver' state.role === 'SuperAdmin')) { NetworkHub.broadcastToServer({ type 'SEAT_SYNC', totalSeats state.totalSeats, passengers state.passengers, routeTitle state.currentRouteTitle }); } } function logToConsole(message) { const consoleEl = document.getElementById('debugConsole'); const time = new Date().toLocaleTimeString(); consoleEl.innerHTML += `br[${time}] ${message}`; consoleEl.scrollTop = consoleEl.scrollHeight; } async function copyFPS() { await navigator.clipboard.writeText('122891914'); alert('轉數快碼 122891914 已複製!多謝大輝哥!☕'); } 門戶登入 function doLogin(role, bypassPasswordCheck = false) { let phone = ''; if (bypassPasswordCheck) { phone = state.phone; } else { phone = document.getElementById('phoneInput').value.trim(); if (phone.length 8) { alert('請輸入有效的香港手機號碼!'); return; } state.phone = phone; state.role = role; } if (role === 'Driver') { if (!approvedDriversList.includes(phone)) { pendingDriverPhone = phone; localStorage.setItem('van_pending_driver', phone); document.getElementById('loginSection').style.display = 'none'; document.getElementById('approvalWaitingPanel').style.display = 'block'; logToConsole(`⚠️ 司機 ${phone} 企圖登入,已被攔截!狀態:等待大輝哥審批。`); return; } } if (role === 'SuperAdmin' && !bypassPasswordCheck) { let pwd = prompt(請輸入超級版主大輝的最高權力密碼:); if (pwd !== Fai64989786) { alert(超級權力校驗失敗!); return; } } localStorage.setItem('van_logged_user', JSON.stringify({ role role, phone phone })); document.getElementById('loginSection').style.display = 'none'; document.getElementById('approvalWaitingPanel').style.display = 'none'; document.getElementById('coreWorkspace').style.display = 'block'; if (role === 'SuperAdmin') { document.getElementById('superAdminPanel').style.display = 'block'; refreshSuperAdminApprovalSection(); } const titleMap = { 'Passenger' `👤 乘客看板 (手機 ${state.phone})`, 'Driver' `🚖 司機控制台 (手機 ${state.phone})`, 'SuperAdmin' `⚡ 大輝超級控制台 (最高絕對權限)` }; document.getElementById('workspaceTitle').innerText = titleMap[role]; NetworkHub.init(); if (bypassPasswordCheck) { logToConsole(`⚡ [免驗證自動登入] 歡迎回來!已回復上一次操作狀態。`); } else { logToConsole(`👤 身份儲存成功!下次打開此 App 將自動秒進工作台。`); } saveState(false); } function doLogout(silent = false) { if(silent confirm(確定要登出並清除自動登入紀錄嗎?)) { if(passengerGpsWatchId) { navigator.geolocation.clearWatch(passengerGpsWatchId); } localStorage.removeItem('van_logged_user'); localStorage.removeItem('van_realtime_state'); if(!silent) alert(已成功登出。); window.location.reload(); } } function refreshSuperAdminApprovalSection() { const displayEl = document.getElementById('pendingDriverDisplay'); const btnEl = document.getElementById('btnApproveDriver'); if (pendingDriverPhone) { displayEl.innerText = `${pendingDriverPhone} (等待您批准)`; displayEl.style.color = 'var(--danger-color)'; btnEl.style.display = 'inline-block'; } else { displayEl.innerText = 暫無新司機申請開工; displayEl.style.color = 'var(--success-color)'; btnEl.style.display = 'none'; } } function approveDriverAction() { if (pendingDriverPhone && !approvedDriversList.includes(pendingDriverPhone)) { approvedDriversList.push(pendingDriverPhone); localStorage.setItem('van_approved_drivers', JSON.stringify(approvedDriversList)); logToConsole(`解鎖成功:大輝哥已批准司機 ${pendingDriverPhone} 的開工授權!`); alert(`成功批准司機 ${pendingDriverPhone} 開工!`); pendingDriverPhone = ''; localStorage.removeItem('van_pending_driver'); refreshSuperAdminApprovalSection(); } } 🗺️ 路線配置 function handleRouteSelectChange() { const select = document.getElementById('routeSelect'); const customInput = document.getElementById('customRouteInput'); if(select.value === 'ROUTE_CUSTOM') { customInput.style.display = 'block'; state.currentRouteTitle = customInput.value '自訂自由路線'; } else { customInput.style.display = 'none'; state.currentRouteTitle = select.options[select.selectedIndex].text; } state.passengers = 0; state.isReversed = false; logToConsole(`切換營運路線:${state.currentRouteTitle},乘客數重置。`); saveState(); } function syncLiveDisplay() { state.currentRouteTitle = document.getElementById('customRouteInput').value '自訂自由路線'; saveState(); } 🔄 起點與終點對調 function reverseRoute() { let title = state.currentRouteTitle; if (title.includes('⇄')) { let parts = title.split('⇄'); state.currentRouteTitle = `${parts[1].trim()} ⇄ ${parts[0].trim()}`; state.isReversed = !state.isReversed; logToConsole(`🔄 起點與終點對調完美跳轉為 [${state.currentRouteTitle}]`); saveState(); } else { alert('自訂自由路線請使用 ⇄ 符號分隔起訖點。'); } } 🚖 1619座切換 function setTotalSeats(num) { state.totalSeats = num; if(state.passengers num) { state.passengers = num; } logToConsole(`車型更換:新款 ${num} 座規格車。`); saveState(); } 🚖 手動上客計數 function adjustPassengers(delta) { let targetPassengers = state.passengers + delta; if(targetPassengers 0) { alert('人數不能小於 0!'); return; } if(targetPassengers state.totalSeats) { alert('全車已爆棚滿座!'); return; } state.passengers = targetPassengers; logToConsole(`司機點擊上客:當前車上 ${state.passengers} 人。`); saveState(); } 🚖 宣告滿座快捷按鈕 function triggerFullHouse() { let emptySeats = state.totalSeats - state.passengers; if (emptySeats 0) { state.passengers = state.totalSeats; logToConsole(`🚨 宣告全車爆棚滿座!`); } else { state.passengers = 0; logToConsole(`🔄 清空乘客,重頭數起。`); } saveState(); } 📡 我在此上車 (高精準 GPS 雷達晶片喚醒) function triggerPassengerGpsRadar(btn) { if(!state.phone) { alert('請先登入!'); return; } if (passengerGpsWatchId === null) { if (!navigator.geolocation) { alert(手機不支援 GPS 硬件!); return; } btn.classList.add('btn-gps-active'); btn.innerText = 🛑 取消上車申報; logToConsole(`📡 [雷達啟動] 強行喚醒手機最高精準度 GPS 硬件...`); passengerGpsWatchId = navigator.geolocation.watchPosition( (pos) = { const lat = pos.coords.latitude; const lng = pos.coords.longitude; const accuracy = pos.coords.accuracy; logToConsole(`🛰️ [雷達鎖定成功] 座標:緯度 ${lat.toFixed(5)}, 經度 ${lng.toFixed(5)} (精準度 ${accuracy.toFixed(1)} 米內)`); 將乘客高精準坐標實時上傳廣播池 NetworkHub.broadcastToServer({ type 'LOCATION_UPDATE', userId state.phone, lat lat, lng lng, accuracy accuracy }); }, (err) = { logToConsole(`❌ GPS 硬件搜尋衛星失敗:${err.message}`); }, { enableHighAccuracy true, timeout 10000, maximumAge 0 } ); alert(`【位置已鎖定】n高精準雷達已成功連線!等車位置已即時同步發送。`); } else { navigator.geolocation.clearWatch(passengerGpsWatchId); passengerGpsWatchId = null; btn.classList.remove('btn-gps-active'); btn.innerText = 📡 我在此上車; logToConsole(🛑 GPS 追蹤雷達已關閉,背景零電量消耗。); alert(已取消上車位置申報。); } } function joinTrueGroup(url) { logToConsole(`💬 安全跳轉至真實西鐵群組:${url}`); setTimeout(() = { window.open(url, '_blank'); }, 300); } 👁️ 數據連動中樞 function syncUI(triggerBroadcast = true) { if(!document.getElementById('btnSeat16')) return; if(state.totalSeats === 16) { document.getElementById('btnSeat16').classList.add('active'); document.getElementById('btnSeat19').classList.remove('active'); } else { document.getElementById('btnSeat19').classList.add('active'); document.getElementById('btnSeat16').classList.remove('active'); } let emptySeats = state.totalSeats - state.passengers; document.getElementById('passengerCountDisplay').innerText = `${state.passengers} 人`; document.getElementById('emptySeatsDisplay').innerText = `${emptySeats} 個位`; document.getElementById('liveRouteName').innerText = state.currentRouteTitle; const btnFullHouse = document.getElementById('btnFullHouse'); const btnReservePassenger = document.getElementById('btnReservePassenger'); if (emptySeats === 0) { btnFullHouse.classList.add('is-full'); btnFullHouse.innerText = 滿座; btnFullHouse.style.backgroundColor = var(--danger-color); document.getElementById('liveSeatsText').innerHTML = `span style=colorvar(--danger-color); font-weightbold;🚨 全車滿座 (爆棚)span`; btnReservePassenger.disabled = true; btnReservePassenger.style.backgroundColor = '#444'; btnReservePassenger.style.color = '#aaa'; btnReservePassenger.innerText = '已滿座無法申報'; if(passengerGpsWatchId) { navigator.geolocation.clearWatch(passengerGpsWatchId); passengerGpsWatchId = null; btnReservePassenger.classList.remove('btn-gps-active'); } } else { btnFullHouse.classList.remove('is-full'); btnFullHouse.innerText = 申報滿座; btnFullHouse.style.backgroundColor = var(--success-color); document.getElementById('liveSeatsText').innerHTML = `🚺 當前剩餘空位 span style=colorvar(--accent-color); font-weightbold;${emptySeats}span ${state.totalSeats}`; btnReservePassenger.disabled = false; if(passengerGpsWatchId === null) { btnReservePassenger.style.backgroundColor = 'var(--primary-color)'; btnReservePassenger.style.color = 'var(--accent-color)'; btnReservePassenger.innerText = '📡 我在此上車'; } } } 大輝哥最高絕對特權 function superAction(type) { logToConsole(`⚡ [超級特權發動]:${type}`); if(type === 'RESET_ALL') { NetworkHub.broadcastToServer({ type 'SUPER_ADMIN_COMMAND', authKey 'Fai64989786', action 'REVOKE' }); state.totalSeats = 16; state.passengers = 0; localStorage.clear(); alert(全港所有車隊數據、審批紀錄、自動登入已強行完全歸零清空!); window.location.reload(); } if(type === 'CALC_PAYROLL') { 2026 最新對帳規則:星期六固定 $450,平日正常時薪 $75 港幣 let isSaturday = new Date().getDay() === 6; let pay = isSaturday 450 8 75; alert(`💰 【浚鍵管理有限公司 - 財務動態對帳】n-----------------------------n今日工作型態:${isSaturday '星期六週末定額班' '平日正常時薪計'}n當班司機核算報酬:$${pay} 港幣n-----------------------------n(財務部核實發放 • 浚鍵管理授權)`); } if(type === 'BLOCK_USER') { let num = prompt(請輸入要永久封鎖的乘客電話:); if(num) alert(`號碼 ${num} 已打入全港黑名單!`); } if(type === 'BROADCAST') { let msg = prompt(請輸入全港紅VAN緊急廣播公告:); if(msg) { NetworkHub.broadcastToServer({ type 'SUPER_ADMIN_COMMAND', authKey 'Fai64989786', action 'BROADCAST_MSG', msg msg }); alert(廣播已全自動秒傳推送!); } } } window.onload = function() { syncUI(false); const savedUser = localStorage.getItem('van_logged_user'); if (savedUser) { try { const userData = JSON.parse(savedUser); doLogin(userData.role, true); } catch (e) { console.error(e); } } }; script body html