Files
web-Iot/tmp_cjk_output.txt
2026-08-14 09:02:52 +08:00

220 KiB
Raw Blame History

Total files with CJK: 76 Total CJK lines: 1754
 
### src\api\api.ts (1)
L207: responseType: 'arraybuffer' // 馃憟 鍙渶瑕佸姞杩欎竴琛岋紒
 
### src\api\device.ts (3)
L92: data: data, // 涓婁紶鏂囦欢蹇呴』鐢?data锛屼笉鑳界敤 params
L94: 'Content-Type': 'multipart/form-data' // 涓婁紶鏂囦欢蹇呭姞锛? L418: url: '/iot/workRecord/add', // 淇涓烘纭殑娣诲姞鎺ュ彛
 
### src\api\reportDownloader.ts (7)
L15: [key: string]: string; // 閫傞厤鍓茶崏(妞嶈楂樺害)銆佹竻娲?鐏版崯鐜?鐨勪笉鍚屽瓧娈? L240: <!-- 鏍稿績鎸囨爣 -->
L254: <!-- 鏈€浣充綔涓氱獥鍙?-->
L264: <!-- 浠诲姟鍒楄〃 -->
L281: if (task[key] === '楂?) className = 'priority-high';
L282: else if (task[key] === '涓?) className = 'priority-medium';
L295: <!-- 绠楁硶鎵ц娴佺▼ -->
 
### src\api\request.ts (1)
L8: const message = utils.message; // 浣跨敤鍏ㄥ眬 message
 
### src\components\AgoraRtc.tsx (6)
L52: console.log("RTC鍙傛暟涓嶅叏锛屾棤娉曟挱鏀?);
L61: await destroy(); // 鍏堟竻鐞嗕笂涓€娆? L79: console.error("璁㈤槄澶辫触", err);
L93: console.log("鍔犲叆棰戦亾鎴愬姛");
L95: console.error("鍔犲叆澶辫触", err);
L96: message.error("瑙嗛杩炴帴澶辫触");
 
### src\components\alerts\AlarmHistory.tsx (4)
L192: {/* 璁惧ID */}
L223: {/* 鏃堕棿鑼冨洿 */}
L262: {/* 鍙充晶璇︽儏鎶藉眽 */}
L307: {/* 閫氱煡璁㈤槄妯″潡 */}
 
### src\components\alerts\AlarmOverview.tsx (29)
L179: console.error('鍔犺浇鍥捐〃鍛婅鏁版嵁澶辫触', err);
L263: fetchList(); // 鍒锋柊鍒楄〃
L264: fetchStat(); // 鍒锋柊缁熻
L338: case 1: color = 'orange'; break; // 寰呭鐞? L339: case 2: color = 'green'; break; // 宸插叧闂? L448: console.log('鑱旂郴璐熻矗浜?, currentAlarm);
L454: console.log('娲惧彂宸ュ崟', currentAlarm);
L478: sourceType: 7, // 鏉ユ簮 7=鍛婅
L479: orderType: 5, // 绫诲瀷 5=杩愮淮
L480: priorityLevel: currentAlarm.alarmLevel === 'ERROR' ? 1 : 2, // 淇锛氱瓑绾ф槸瀛楃涓诧紝涓嶆槸鏁板瓧1
L495: orderStatus: 1, // 1-寰呭鐞? L523: {/* 缁熻鍗$墖 */}
L694: const trimVal = e.target.value.trim(); // 鍙竻闄ら灏剧┖鏍? L728: fetchChartAllAlarm(); // 鏂板锛氬埛鏂板浘琛ㄥ叏閲忓憡璀? L731: fetchList(); // 鍒锋柊鍒楄〃
L732: fetchStat(); // 鍒锋柊缁熻
L733: fetchChartAllAlarm(); // 鏂板锛氬埛鏂板浘琛ㄥ叏閲忓憡璀? L747: {/* 琛ㄦ牸 */}
L774: {/* 涓変釜鍥捐〃 */}
L851: {/* 鍛婅璇︽儏鎶藉眽 */}
L865: {/* 鍛婅澶撮儴 */}
L879: {/* 鍛婅鍩虹淇℃伅 */}
L901: {/* 鍛婅鎻忚堪 */}
L906: {/* 鏍瑰洜鍒嗘瀽 */}
L908: {/* 鎺ㄨ崘澶勭悊鎺柦 */}
L925: {/* 澶勭悊鎿嶄綔 */}
L951: {/* 搴曢儴鎸夐挳 */}
L960: {/* ====================== 淇敼鍛婅寮圭獥 ====================== */}
L1027: {/* ========== 鏂板锛氱敓鎴愬伐鍗曞脊绐?========== */}
 
### src\components\alerts\AlarmRealtime.tsx (2)
L95: {/* 琛ㄦ牸 */}
L104: {/* 鍛婅璇︽儏寮圭獥 */}
 
### src\components\alerts\AlarmSubscription.tsx (10)
L16: { id: 1, name: i18n.t('alerts.mockSubOps'), deviceType: 'all', level: 'all', channels: ['鐭俊'] },
L17: { id: 2, name: i18n.t('alerts.mockSubAdmin'), deviceType: 'sensor', level: 'error', channels: ['鐭俊', '閭欢'] },
L18: { id: 3, name: i18n.t('alerts.mockSubDevice'), deviceType: 'camera', level: 'warn', channels: ['APP鎺ㄩ€?] },
L31: '鐭俊': t('alerts.sms'),
L32: '閭欢': t('alerts.email'),
L33: 'APP鎺ㄩ€?: t('alerts.appPush'),
L134: {/* 鏂板/缂栬緫 寮圭獥 */}
L167: <Option value="鐭俊">{t('alerts.sms')}</Option>
L168: <Option value="閭欢">{t('alerts.email')}</Option>
L169: <Option value="APP鎺ㄩ€?>{t('alerts.appPush')}</Option>
 
### src\components\devices\DeviceControl.tsx (105)
L87: const [selectedRoute, setSelectedRoute] = useState(null); // 鉁?鏂板
L90: const [isConnecting, setIsConnecting] = useState(false); // 杩炴帴涓姸鎬? L126: const [isModalOpen, setIsModalOpen] = useState(false);//鏉冮檺璇锋眰鐨勫脊绐? L127: const [hasControlRight, setHasContronRight] = useState(false);//鏄惁鏈夋帶鍒舵潈闄? L288: console.log("鑾峰彇鐩存挱鐨勮澶囦俊鎭?, selectedDevice);
L325: console.log("鎺ュ彈鐨勬帹閫佷俊鎭?, message);
L336: case 'AUTH'://杩炴帴澶辫触 閲嶆柊杩炴帴
L343: case 'switchResult'://杩炴帴澶辫触 閲嶆柊杩炴帴
L352: console.log("鏉冮檺鍒囨崲缁撴灉");
L354: case 'switchPermission'://杩炴帴澶辫触 閲嶆柊杩炴帴
L355: console.log("骞冲彴璇锋眰鏉冮檺", message.platform)
L358: console.log("妫€娴嬪埌web骞冲彴锛屾墽琛宺eturn缁堟閫昏緫");
L359: return; // 杩欓噷鐨剅eturn浼氱粓姝㈡暣涓猦andleMessage鍑芥暟鐨勬墽琛? L369: case 'detectionReport'://杩炴帴澶辫触 閲嶆柊杩炴帴
L375: console.log("鏀跺埌闅滅鐗╂娴嬫姤鍛?122", type, isSecure);
L383: console.log("鏀跺埌闅滅鐗╂娴嬫姤鍛?122333");
L446: console.log(res, "鑾峰彇浠诲姟鏁版嵁")
L453: console.error(err, "鑾峰彇浠诲姟鍑洪敊");
L465: console.log("鑾峰彇杩滅▼閬ユ帶鏉冮檺鎴愬姛");
L503: setWsDeviceInfo([]);//娓呯┖璁惧淇℃伅
L511: console.error("鐢ㄦ埛淇℃伅瑙f瀽澶辫触", e);
L549: console.error("鏉冮檺鏍¢獙澶辫触", err);
L610: console.log('鉁?椤甸潰鍒囧洖鍓嶅彴锛屽己鍒堕噸杩?WebSocket');
L631: console.log('馃攧 鍚庡彴淇濇椿锛氬皾璇曢噸杩?WebSocket');
L634: }, 8000); // 8绉掑悗鍙颁繚娲? L692: console.log("鍙戦€佺殑鏉冮檺璇锋眰鏁版嵁", wsdata);
L709: console.log("鍚屾剰鏉冮檺缁欏叾浠栧钩鍙?)
L715: console.log("鍚屾剰鏉冮檺璇锋眰");
L722: console.log("鍚屾剰鏉冮檺璇锋眰鍏抽棴");
L761: setPoints([]); // 馃敟 鍏抽敭锛氭竻绌轰笂涓€涓澶囩殑杞ㄨ抗
L790: console.error('璺嚎瑙f瀽澶辫触', e);
L945: setWaylineList(_list || []); // 鍙杔ist鏁扮粍
L1000: setSelectedRoute(route); // 鉁?鍔犱笂杩欏彞
L1039: /* if (!wsRef.current || // 1. WebSocket 鏄惁瀛樺湪
L1040: wsRef.current.readyState !== WebSocket.OPEN || // 2. 杩炴帴鏄惁鎵撳紑
L1041: !controlRef.current) { // 3. 鏄惁鏈夋帶鍒舵潈闄? L1052: type: "remoteControl", // 娑堟伅绫诲瀷
L1053: remoteData: data, // 鍘熷鎵嬫焺鏁版嵁
L1054: token: token, // 璁よ瘉浠ょ墝
L1063: console.log("鏄剧ず寮圭獥", content, type);
L1086: setSelectedRoute(work); // 鉁?鍔犱笂杩欏彞
L1093: console.log(res, "鑾峰彇鍗曠嫭鍒楄〃鏁版嵁");
L1101: console.warn("璺緞鏁版嵁瑙f瀽澶辫触", e);
L1123: console.error("鑾峰彇鏁版嵁澶辫触", err);
L1155: {/* 鍓茶崏鏈鸿瑙掑垏鎹?*/}
L1183: {/* 宸℃鏈哄櫒浜猴細3璺棰?鈫?绱у噾妯悜锛屼笉婊氬姩锛屽叏閮ㄥ彲瑙?*/}
L1190: {/* 涓荤敾闈細灏忎竴鐐?*/}
L1208: {/* 鍓茶崏鏈哄崟璺?*/}
L1255: {/* 鉁?淇锛氬壊鑽夋満4璺棰?鈥斺€?缁濅笉鍘嬫墎锛屼繚鎸?6:9 */}
L1278: {/* 涓?*/}
L1283: {/* 宸?+ 涓?+ 鍙?*/}
L1296: {/* 涓?*/}
L1304: {/* 涓?*/}
L1309: {/* 宸?+ 涓?+ 鍙?*/}
L1322: {/* 涓?*/}
L1329: {/*鍏朵粬璁惧
L1342: {selectedDevice?.name}锝滃疄鏃惰棰? L1352: {/* 宸︿晶璁惧鍒楄〃 */}
L1369: <p className="text-xs text-[#9ca3af] mb-1">浠诲姟鎬佸娍</p>
L1395: <MapPin className="w-3 h-3 text-[#9ca3af]" />鍖哄煙: {device?.area}
L1415: {/* 涓棿鎿嶄綔鍖?*/}
L1429: {/* 鏃犱汉鏈虹姸鎬佹瑙?*/}
L1487: <p className="text-xs text-[#9ca3af] mb-1.5">褰撳墠浣嶇疆</p>
L1497: <p className="text-xs text-[#9ca3af] mb-1.5">褰撳墠妯″紡</p>
L1498: <p className="text-sm font-bold text-white">{selectedDevice?.type === 'plane' ? '鏃犱汉鏈哄緟鍛? : selectedDevice?.type === 'mower' ? '鍓茶崏寰呭懡' : '寰呭懡'}</p>
L1501: <p className="text-xs text-[#9ca3af] mb-1.5">鐢甸噺/鑸悜</p>
L1509: <span className="text-xs text-[#9ca3af]">鍚敤閬ユ帶</span>
L1526: {/* 閬ユ帶涓庢€佸娍 - 銆愪慨鏀?銆戯細鎶婅棰戝祵鍏ュ埌杩欓噷 */}
L1529: {/* 瑙嗛鍖哄煙 - 鐙珛澶х獥鍙?*/}
L1536: {/* 鐘舵€佸崱鐗囪 */}
L1539: <p className="text-xs text-[#9ca3af] mb-1.5">TCP閾捐矾</p>
L1543: <p className="text-xs text-[#9ca3af] mb-1.5">閬ユ帶鎺ョ</p>
L1547: <p className="text-xs text-[#9ca3af] mb-1.5">瑙勫垝鎬佸娍</p>
L1556: {/* 鎺у埗鍖猴細宸﹁疆 + Xbox + 鍙宠疆 鈥斺€?绱у噾甯冨眬 */}
L1558: {/* 宸﹁疆閫熷害闈㈡澘 - 缂╁皬 */}
L1561: {/* 椤堕儴鏍囬 */}
L1569: {/* 浠〃鐩橈紙灞呬腑鏀惧ぇ锛?*/}
L1582: {/* 閫熷害 + 鐢垫祦 涓€浣撳寲鍗$墖锛堟牳蹇冭瑙夛級 */}
L1584: {/* 閫熷害 */}
L1593: {/* 鐢垫祦 */}
L1605: {/* Xbox 鎵嬫焺 - 缂╁皬銆佸眳涓?*/}
L1615: {/* 鍙宠疆閫熷害闈㈡澘 - 缂╁皬 */}
L1618: {/* 椤堕儴鏍囬 + 鐘舵€?*/}
L1626: {/* 浠〃鐩橈紙灞呬腑浼樺寲锛?*/}
L1639: {/* 鏍稿績鏁版嵁鍗$墖锛氶€熷害 + 鐩爣鍊硷紙骞插噣瀵圭О锛?*/}
L1641: {/* 瀹炴椂閫熷害 */}
L1650: {/* 閫熷害杈撳嚭 */}
L1665: {/* GPS瑙勫垝 */}
L1735: {/* 鐘舵€佹爣绛撅紙鍜屼綘鍘熺増瀹屽叏涓€鏍凤級 */}
L1841: <Send className="w-4 h-4" /> 涓嬪彂浠诲姟
L1845: {taskRunning ? t('video.pause') : "鎵ц"}
L1848: <Square className="w-4 h-4" /> 鍋滄
L1851: {/* 鏃犱汉鏈轰笓鐢ㄤ换鍔℃帶鍒舵寜閽?*/}
L1854: {/* 鍔ㄦ€佹寜閽細鎵ц涓?鈫?鎸傝捣 / 宸叉寕璧?鈫?缁х画 */}
L1875: {/* 鏆傚仠 / 鎭㈠ */}
L1895: {/* 鍔ㄦ€侊細杩旇埅 / 鍙栨秷杩旇埅 */}
L1936: {/* 鍙充晶瑙嗛闈㈡澘锛堥仴鎺ч〉闅愯棌锛? 淇濇寔涓嶅彉 */}
L1951: {/* 璁惧绫诲瀷锛氭満鍣ㄤ汉 鈫?鏄剧ず 4 璺棰?*/}
L2005: {/* 璁惧绫诲瀷锛氬壊鑽夋満 鈫?鏄剧ず 1 璺棰?*/}
L2068: {/* 璁惧绫诲瀷锛氭棤浜烘満 鈫?閬嶅巻鏄剧ず瑙嗛娴?*/}
L2091: {/* 銆愪慨鏀?銆戯細鍒犻櫎鍘熸潵鐨勬偓娴棰戠獥鍙d唬鐮?*/}
L2183: {/* 鏃嬭浆鍔犺浇鍦?*/}
L2239: {/* 椋炶鍙傛暟 */}
L2317: {/* 鏃堕棿閫夋嫨 */}
L2344: {/* 閲嶅浠诲姟 */}
 
### src\components\devices\deviceController.js (19)
L20: this.currentDevice = null; // 淇濆瓨褰撳墠璁惧
L32: this.keepAliveInterval = null; // 鍚庡彴淇濇椿瀹氭椂鍣? L69: console.log('馃攲 椤甸潰鍒囧悗鍙帮紝鍏抽棴 WebSocket');
L80: console.log('鉁?椤甸潰鍒囧洖鍓嶅彴锛岃嚜鍔ㄩ噸杩?WebSocket');
L95: console.log('馃攧 鍚庡彴淇濇椿锛氬皾璇曢噸杩?WebSocket');
L178: this.messageApi.warning('鍏朵粬绔鍦ㄦ帶鍒?);
L187: this.messageApi.error('鏉冮檺鏍¢獙澶辫触');
L210: this.messageApi.warning('鏃犳帶鍒舵潈闄?);
L219: content: '璇锋眰鎺у埗涓?..',
L231: this.messageApi.error('鎺у埗璇锋眰瓒呮椂');
L255: console.log('馃摠 鏀跺埌娑堟伅锛?, msg);
L283: this.messageApi.error({ key: 'control', content: msg.message || '鎺у埗澶辫触' });
L288: this.messageApi.success({ key: 'control', content: '鎺у埗鎴愬姛' });
L294: console.log('馃攲 鎺у埗缁撴灉浠诲姟鍙樻洿,', msg);
L302: console.log('馃攲 鍒拌揪瀹屾垚鐐?', msg);
L313: title: '鏉冮檺璇锋眰',
L314: content: `${msg.platform} 璇锋眰鎺у埗璁惧`,
L325: const types = { 0: t('constants.locationUnknown'), 1: '浜?, 2: '杞﹁締', 3: '鍥存爮', 4: '鍧戞礊', 5: '鑽変笡' };
L328: content: `妫€娴嬪埌 ${types[type] ?? '鏈煡鐗?}锛岃窛绂?${distance}m`,
 
### src\components\devices\DeviceOverviewPage.tsx (16)
L130: console.error('鏁版嵁璇锋眰澶辫触', err);
L175: console.error('淇敼鍒悕鎶ラ敊', err);
L218: console.error('鑾峰彇鏃犱汉鏈轰换鍔$粺璁″け璐?, err);
L232: return true; // 榛樿閮界畻
L241: console.error('鑾峰彇鏈哄櫒浜轰换鍔$粺璁″け璐?, err);
L248: console.error('鑾峰彇浠诲姟缁熻澶辫触', err);
L277: }, [selectedDevice]); // 鍙湁鍒囪澶囨墠鍙?鈫?瑙嗛涓嶉棯
L396: console.error('MQTT瑙f瀽澶辫触', err);
L458: const activeMowers = devices?.filter(d => d.feStatus == 1).length || 0; // 浣滀笟涓姸鎬佹暟閲? L567: console.error('鑾峰彇鏃犱汉鏈虹姸鎬佸け璐?, err);
L590: {/* 宸︿晶鏂囧瓧鍖哄煙 */}
L598: {/* 搴曢儴鐜瘮/澶囨敞 */}
L604: {/* 鍙充晶鍦嗗舰鍥炬爣鍖哄煙 */}
L864: {/* 鉁?鍏抽敭锛歷ideoDevice 缁濅笉闅廙QTT鏇存柊锛岃棰戞案涓嶉棯鐑?*/}
L1075: {/* 鏈哄櫒浜虹紪杈戝埆鍚嶅脊绐?*/}
L1113: {/* 璁惧鍙傛暟鏌ョ湅涓庝慨鏀瑰脊绐楋紙閫氱敤缁勪欢锛?*/}
 
### src\components\devices\DeviceParamModal.tsx (1)
L244: {/* 鍔犺浇鏃惰〃鍗曞尯鍩熺畝鍗曢伄缃╂彁绀猴紙鎵撳紑寮圭獥鎷夊彇鍙傛暟鏃剁殑loading鍙嶉锛?*/}
 
### src\components\devices\DeviceStatusPage.tsx (39)
L73: const [persistentDroneData, setPersistentDroneData] = useState(null); // 鎸佷箙鍖栨棤浜烘満鏁版嵁
L74: const [persistentHostData, setPersistentHostData] = useState(null); // 鎸佷箙鍖栨満鍦烘暟鎹? L78: const [arrivedPoint, setArrivedPoint] = useState(null);//瀹屾垚鐐? L101: const [queryTimeRange, setQueryTimeRange] = useState([]); // 鏃堕棿鑼冨洿
L102: const [startTimestamp, setStartTimestamp] = useState(''); // 寮€濮嬫椂闂存埑
L103: const [endTimestamp, setEndTimestamp] = useState(''); // 缁撴潫鏃堕棿鎴? L118: const [markedPoints, setMarkedPoints] = useState([]); // 鏍囪鐨勭偣
L119: const [completeFlag, setCompleteFlag] = useState(false); // 鏄惁瀹屾垚璺緞瑙勫垝
L120: const [savePath, setSavePath] = useState(null); // 淇濆瓨鐨勮矾寰勬暟鎹? L121: const [isSaveModalVisible, setIsSaveModalVisible] = useState(false); // 淇濆瓨妯℃€佹鍙鎬? L122: const [plotName, setPlotName] = useState(''); // 鍦板潡鍚嶇О
L123: const [isSaving, setIsSaving] = useState(false); // 鏄惁姝e湪淇濆瓨
L124: const mapRef = useRef(null); // 鍦板浘 ref
L128: const urlSn = queryParams.get('sn'); // 鎷垮埌璺敱涓婄殑sn
L135: console.log('褰撳墠浣滀笟鏂瑰紡锛氬洖瀛?);
L137: console.log('褰撳墠浣滀笟鏂瑰紡锛氬崟鐐?);
L179: console.error('鏁版嵁璇锋眰澶辫触', err);
L353: console.error('DeviceStatusPage MQTT 娑堟伅瑙f瀽澶辫触:', err);
L506: console.error('鑾峰彇鏃犱汉鏈虹姸鎬佸け璐?, err);
L555: console.error('鑾峰彇鎵ц涓换鍔¤建杩瑰け璐?, err);
L596: ...currentDroneData, // 鎸佷箙鍖栨暟鎹渶鍚庤鐩栵紝纭繚浼樺厛鏄剧ず
L708: path: path, // 瀛樺偍杩斿洖鐨勮矾寰勭粨鏋? L722: console.error('璺緞瑙勫垝澶辫触:', error);
L736: path: positionPoints, // 瀛樺偍杩斿洖鐨勮矾寰勭粨鏋? L814: console.error('淇濆瓨澶辫触:', error);
L844: {/* 椤甸潰椤堕儴鎸夐挳鍖哄煙 */}
L954: {/* 鏃犱汉鏈轰笓鐢ㄥ竷灞€ */}
L957: {/* 宸︿晶锛氭満鍦鸿棰?+ 鍦板浘 */}
L959: {/* 鏃犱汉鏈哄満瑙嗛 + 鏈哄満鐘舵€?*/}
L984: {/* 鍦板浘 */}
L1035: {/* 鍙充晶锛氭棤浜烘満瑙嗛 + 鏃犱汉鏈虹姸鎬?*/}
L1037: {/* 鏃犱汉鏈鸿棰?+ 鏃犱汉鏈虹姸鎬?*/}
L1153: {/* 瑙嗛灞傦細鍋滄鏃朵笉娓叉煋 / 鏈挱鏀炬椂涓虹┖锛屼笉褰卞搷鐘舵€侀潰鏉?*/}
L1183: {/* 瑙嗛鏈姞杞?/ 鍋滄鎾斁鐨勫崰浣?*/}
L1201: {/* 鍗曡棰戯紙闈炲叏鏅級妯″紡鐘舵€佸彔鍔犲眰锛氬缁堟覆鏌擄紝鍜岃棰戝眰瑙h€?*/}
L1268: {/* 鍙宠竟 - 鍗?鏍硷紝涓婇儴鍦板浘锛屼笅閮ㄨ繙绋嬫帶鍒?*/}
L1270: {/* 鍦板浘 */}
L1320: {/* 杩滅▼鎺у埗闈㈡澘 */}
L1356: {/* 淇濆瓨璺緞妯℃€佹 */}
 
### src\components\devices\DraggablePanel.jsx (2)
L95: {/* 鎷栨嫿鎵嬫焺 */}
L119: {/* 瀛愬唴瀹?*/}
 
### src\components\devices\DroneVideoPlayer.tsx (11)
L47: const [selectedCamera, setSelectedCamera] = useState<'indoor' | 'outdoor'>('outdoor'); // 榛樿閫夋嫨瀹ゅ
L48: const [selectedLens, setSelectedLens] = useState<'wide' | 'zoom' | 'ir'>(''); // 榛樿閫夋嫨骞胯
L65: const cameraIndex = device?.gateway_camera_list[0]?.camera_index || ""; // 鐩墠鍏堥粯璁ょ敤绗竴涓憚鍍忓ご
L83: console.error('鍒囨崲鏈哄満鎽勫儚澶村け璐?, err);
L118: console.error('鍒囨崲鏃犱汉鏈洪暅澶村け璐?, err);
L198: hasLoadedRef.current.drone = false; // 閲嶇疆鍙︿竴杈圭殑鍔犺浇鐘舵€? L205: hasLoadedRef.current.station = false; // 閲嶇疆鍙︿竴杈圭殑鍔犺浇鐘舵€? L253: minWidth: dualVideo ? '300px' : 'auto' // 纭繚鍦ㄥ弻瑙嗛妯″紡涓嬫湁鏈€灏忓搴? L255: {/* 瑙嗛鎺у埗鎸夐挳 */}
L354: {/* 鐘舵€佽鎯呭彔鍔犲眰 - 宸︿笂瑙?*/}
L408: {/* 搴曢儴淇℃伅鍙犲姞 - 鏄剧ず缁忕含搴?*/}
 
### src\components\devices\mowerAllView.jsx (9)
L10: gap: 8, // 涓夊垪涔嬮棿闂磋窛
L15: {/* ========== 宸﹀垪锛氬乏瑙?========== */}
L41: <div style={{ position: 'absolute', top: 4, left: 8, color: '#fff', fontSize: 12, background: '#0006', padding: '2px 6px', borderRadius: 4 }}>宸﹁</div>
L45: {/* ========== 涓垪锛氫笂-鍓嶈 涓?鍚庤 ========== */}
L52: {/* 鍓嶈 */}
L69: <div style={{ position: 'absolute', top: 4, left: 8, color: '#fff', fontSize: 12, background: '#0006', padding: '2px 6px', borderRadius: 4 }}>鍓嶈</div>
L71: {/* 鍚庤 */}
L88: <div style={{ position: 'absolute', top: 4, left: 8, color: '#fff', fontSize: 12, background: '#0006', padding: '2px 6px', borderRadius: 4 }}>鍚庤</div>
L118: <div style={{ position: 'absolute', top: 4, left: 8, color: '#fff', fontSize: 12, background: '#0006', padding: '2px 6px', borderRadius: 4 }}>鍙宠</div>
 
### src\components\devices\RobotTaskPage.tsx (63)
L63: const [execute, setExecute] = useState(false); // 鏄惁鎵ц浠诲姟
L65: const [arrivedPoint, setArrivedPoint] = useState(null);//瀹屾垚鐐? L90: const [runningPoolTask, setRunningPoolTask] = useState(null);//姝e湪鎵ц鐨勪换鍔? L95: const [showVideo, setShowVideo] = useState(false); // 鎺у埗瑙嗛缁勪欢鏄剧ず
L102: const [activeTab, setActiveTab] = useState('pool'); // 'task' for 浠诲姟鍒楄〃, 'pool' for 浠诲姟姹? 'history' for 鍘嗗彶浠诲姟
L134: dateRange: null, // 鏃堕棿鑼冨洿
L135: taskStatus: null, // 浠诲姟鐘舵€? L136: robot: null // 鏈哄櫒浜鸿澶? L142: setShowVideo(false); // 浠诲姟瀹屾垚鍏抽棴瑙嗛
L172: console.error('瑙f瀽浠诲姟璺緞鏁版嵁澶辫触锛?, err);
L177: console.error('鑾峰彇浠诲姟璺緞澶辫触锛?, err);
L182: console.log('鍒犻櫎鑸嚎锛?, route);
L204: console.error('鍒犻櫎鑸嚎鎺ュ彛鎶ラ敊锛?, err);
L222: console.warn('鏈壘鍒颁换鍔″搴旂殑璁惧');
L230: console.log('鉁?浠诲姟浣跨敤鐩稿悓璁惧锛屾棤闇€閲嶆柊杩炴帴');
L235: console.log('馃攧 鐐瑰嚮浠诲姟鍒囨崲璁惧杩炴帴', targetDevice);
L238: setClearNavLine(v => v + 1); // 娓呯┖鍦板浘杞ㄨ抗
L267: setClearNavLine(v => v + 1); // 娓呯┖鍦板浘杞ㄨ抗
L294: console.log('馃攧 妫€娴嬪埌姝e湪鎵ц浠诲姟鐨勬柊璁惧锛屽紑濮嬭繛鎺?, targetDevice);
L295: setRunningPoolTask(runningTask); // 璁剧疆褰撳墠浠诲姟
L298: setClearNavLine(v => v + 1); // 娓呯┖鍦板浘杞ㄨ抗
L343: console.error('鏁版嵁璇锋眰澶辫触', err);
L401: let method = '';//0寮撳瓙 2 鍥炲瓙
L414: console.error('瑙f瀽璺嚎鏁版嵁澶辫触锛?, err);
L433: console.error('鑾峰彇璺嚎璇︽儏澶辫触锛?, err);
L462: setClearNavLine(v => v + 1); // 娓呯┖鍦板浘杞ㄨ抗
L528: console.error('瑙f瀽璺嚎鏁版嵁澶辫触锛?, err);
L539: console.error('妫€鏌ヨ矾绾垮け璐ワ細', err);
L570: setShowVideo(true); // 杩炴帴鎴愬姛鍚庤嚜鍔ㄦ墦寮€瑙嗛
L580: console.error('鎵ц浠诲姟澶辫触锛?, err);
L621: console.error('鑾峰彇浠诲姟姹犲け璐?', err);
L651: console.error('鑾峰彇鍘嗗彶浠诲姟澶辫触:', err);
L680: console.error('鍙栨秷浠诲姟澶辫触:', err);
L703: console.error('鏆傚仠浠诲姟澶辫触:', err);
L725: console.error('鎭㈠浠诲姟澶辫触:', err);
L905: width: 100, // 鍔犲涓€鐐? L966: const status = record.taskStaus; // 鍘熷鐘舵€佸€? L1125: minWidth: 0, // flex 瀛愬厓绱犳敹缂╁厹搴曪紝瓒呴暱鏃跺厑璁稿帇缂╂崲琛? L1137: <Space size={4} wrap> {/* Space寮€鍚嚜鍔ㄦ崲琛岋紝灏忓睆鎸夐挳鑷姩鎶樿 */}
L1142: <Button size="small" icon={<NodeIndexOutlined />} style={{ borderRadius: 4 }}>浼樺寲</Button>
L1165: {/* 鏈哄櫒浜虹姸鎬佹偓娴潰鏉?- 缁濆瀹氫綅宸︿笂瑙?*/}
L1171: left: 10, // 閬垮紑宸︿晶鍥句緥闈㈡澘锛岄槻姝㈤噸鍙? L1179: maxWidth: 360, // 闄愬埗鏈€澶у搴︼紝涓嶄細鏃犻檺鎷夐暱
L1219: {/* 瑙嗛寮€鍏?*/}
L1236: {/* 鏈哄櫒浜轰换鍔℃ā鍧楋紝甯ab鍒囨崲 */}
L1283: {/* 浠诲姟鍒楄〃Tab */}
L1348: {/* 浠诲姟姹燭ab */}
L1405: {/* 鍘嗗彶浠诲姟Tab */}
L1624: {/* 璺嚎淇℃伅 */}
L1633: {/* 鍒犻櫎鎸夐挳 */}
L1658: {/* 鎵ц鎸夐挳 */}
L1726: {/* 馃敟 浼犻€?routeList 缁欏脊绐?*/}
L1739: {/* 鎵ц浠诲姟寮圭獥 */}
L1942: {/* 浠诲姟鍚嶇О */}
L1952: {/* 鎵ц璺嚎 */}
L1975: {/* 閫夋嫨璁惧 */}
L1998: {/* 閲嶅璁″垝 */}
L2012: {/* 鍛ㄩ€夋嫨 */}
L2029: {/* 鏈堥€夋嫨 */}
L2045: {/* 鎸夊ぉ锛氶€夋嫨鏃ユ湡 */}
L2057: {/* 鏃堕棿 */}
L2066: {/* 鎵ц鍛ㄦ湡 */}
L2076: {/* 搴曢儴鎸夐挳 */}
 
### src\components\devices\WayLinePage.tsx (25)
L56: const [persistentDroneData, setPersistentDroneData] = useState(null); // 鎸佷箙鍖栨棤浜烘満鏁版嵁
L57: const [persistentHostData, setPersistentHostData] = useState(null); // 鎸佷箙鍖栨満鍦烘暟鎹? L86: console.error('鏁版嵁璇锋眰澶辫触', err);
L202: console.error('WayLinePage MQTT 娑堟伅瑙f瀽澶辫触:', err);
L246: console.error('鑾峰彇鍒楄〃鏃犱汉鏈哄疄鏃剁姸鎬佸け璐?, err);
L283: console.error('鑾峰彇鏃犱汉鏈轰綅缃け璐?, err);
L307: const [waylineList, setWaylineList] = useState([]); // 鑸嚎鍒楄〃
L553: setWaylineDrone(planedevices[0]); // 鑸嚎鍒楄〃榛樿閫変腑绗竴涓? L678: sn: waylineDrone.gateway_sn, // 鉁?浣跨敤鑸嚎鍒楄〃鏃犱汉鏈? L857: {/* 鍦板浘鍗$墖 */}
L914: {/* 鐙珛绛涢€?- 璁惧浠诲姟鍒楄〃 */}
L1116: {/*{selectedTask?.status === 'suspended' ? '缁х画浠诲姟' : t('devices.executeTask')}*/}
L1224: {/* 搴曢儴鍐呭鍖?*/}
L1231: {/* 鉁?鑸嚎鍒楄〃鐙珛鏃犱汉鏈虹瓫閫?*/}
L1287: {/* 鉁?鎵ц鎸夐挳鏀逛负鍥炬爣 */}
L1439: {/* 浠诲姟鍚嶇О锛氳嚜鍔ㄦ崲琛?*/}
L1444: {/* 璁惧 & 鏃堕棿锛氳嚜鍔ㄦ崲琛?*/}
L1471: {/* 鍒涘缓浠诲姟寮圭獥 */}
L1582: {/* 鏃堕棿閫夋嫨 */}
L1608: {/* 閲嶅浠诲姟閰嶇疆 repeat_option 瀵硅薄缁戝畾 */}
L1641: {/* 姣忓懆 */}
L1666: {/* 鎸夋湀鏃ユ湡 */}
L1683: {/* 鎸夋湀鏄熸湡 */}
L1738: {/* 鎸夐挳 */}
L1746: {/* 鎵ц鑸嚎璁剧疆杩旇埅楂樺害 Modal */}
 
### src\components\devices\XboxController.tsx (10)
L48: onGamepadUpdate(state); // 鉁?鍙湁杩欓噷鎵嶅彂
L75: }, []); // 鉁?绌轰緷璧? L80: navigator.getGamepads(); // 馃敟 寮哄埗瑙﹀彂涓€娆? L82: }, [/* 椤甸潰鍒囨崲渚濊禆 */]);
L119: console.log("鐐瑰嚮浜嗘棤鎺у埗鏉冮檺锛屽彂璧锋潈闄愯姹?);
L138: '鏈繛鎺ヨ澶?
L140: '鍏朵粬 Web 绔凡杩炴帴'
L142: '璇锋眰鎺у埗涓?..'
L144: '鎺у埗涓?
L146: '鐐瑰嚮鑾峰彇鎺у埗鏉冮檺'
 
### src\components\Draggable.tsx (5)
L26: handle=".drag-header" // 浠呮爣棰樻爮鍙嫋鎷斤紝鍐呭鍖轰笉瑙﹀彂鎷栨嫿
L32: 'border-[8px] border-slate-200 top-[8px] right-[8px] w-[800px] h-[580px] ' // 鏁翠綋8px澶栬竟妗? L35: {/* 鎷栨嫿鏍囬鏍?+ 鍏抽棴鎸夐挳 */}
L41: {/* 鍏抽棴鎸夐挳锛岄樆姝㈡嫋鎷藉啋娉?*/}
L53: {/* 浼犲叆鐨勮棰戝唴瀹?*/}
 
### src\components\Empty.tsx (2)
L7: /** 鑷畾涔夋枃妗?*/
L9: /** 缁勪欢楂樺害 */
 
### src\components\LanguageSwitcher.tsx (2)
L16: 涓枃
L42: {currentLng === 'zh' ? '涓枃' : 'EN'}
 
### src\components\Map.jsx (23)
L39: const planLineRef = useRef(null); // points 瑙勫垝鑸嚎
L40: const navLineRef = useRef(null); // 瀹屾垚鐐瑰疄鏃惰建杩? L41: const markedPointsRef = useRef([]); // 鏍囪鐐瑰疄浣? L50: const followCarEntityRef = useRef(null); // 璺熼殢灏忚溅鐨勫疄渚? L64: const realtimeCartesianRef = useRef([]); // 鐩存帴瀛?Cartesian3锛堟€ц兘鏈€楂橈級
L199: viewer.scene.requestRender(); // 寮哄埗鍒锋柊锛? L405: .catch(error => console.error('鑾峰彇鍥惧眰澶辫触:', error));
L426: console.log('=== 鑾峰彇鍥惧眰鑼冨洿寮€濮?===');
L451: console.log('鎵惧埌鍥惧眰鑼冨洿:', layerBbox);
L464: console.log('鍦板浘宸插畾浣嶅埌鍥惧眰鑼冨洿');
L466: console.error('鍦板浘瀹氫綅澶辫触:', error);
L469: console.warn('鏈壘鍒板浘灞傝寖鍥达紝浣跨敤榛樿浣嶇疆');
L475: console.error('鑾峰彇鍥惧眰鑼冨洿澶辫触:', error);
L628: console.log('璇诲彇鍒板浘灞俠box', targetBbox);
L635: console.warn('璇ュ浘灞傛湭鎵惧埌BoundingBox锛屾棤娉曢琛?, layerIdentifier);
L649: pitch: window.Cesium.Math.toRadians(-90), // 鍨傜洿淇
L656: console.error('鑾峰彇WMS Capabilities澶辫触', err);
L770: viewer.scene.requestRenderMode = true; // 馃憟 鍔犺繖涓紙鍙湪闇€瑕佹椂娓叉煋锛? L1182: device?.type === "plane" ? planeImg : // 椋炴満
L1183: device?.type === "drone" ? planeImg : // 鏃犱汉鏈? L1184: device?.type === "mower" ? carImg : // 鍓茶崏
L1185: device?.type === "robot" ? droneInspectImg : // 宸℃
L1186: carImg; // 榛樿杞?
### src\components\recharts.jsx (10)
L209: { month: '1鏈?, uv: 400, pv: 240, amt: 240 },
L210: { month: '2鏈?, uv: 300, pv: 456, amt: 300 },
L211: { month: '3鏈?, uv: 500, pv: 139, amt: 200 },
L212: { month: '4鏈?, uv: 278, pv: 390, amt: 278 },
L213: { month: '5鏈?, uv: 189, pv: 480, amt: 189 },
L233: name: '璁块棶閲?,
L239: name: '娴忚閲?,
L245: name: '鎴愪氦閲?,
L260: name: '璁块棶閲?,
L265: name: '娴忚閲?,
 
### src\components\SystemSetting\AlarmSettingsManagement.tsx (34)
L28: getErrorListAllApi, // 閿欒缂栫爜涓嬫媺鏁版嵁婧? L29: getWorkOrderModelListApi // 宸ュ崟妯″瀷涓嬫媺鏁版嵁婧? L69: utils.message.error('鑾峰彇鍛婅妯″瀷鍒楄〃澶辫触');
L89: console.error('鎷夊彇閿欒缂栫爜澶辫触', err);
L106: console.error('鎷夊彇宸ュ崟妯″瀷澶辫触', err);
L137: title: '纭鍒犻櫎',
L138: content: '鎮ㄧ‘瀹氳鍒犻櫎杩欐潯鍛婅妯″瀷鍚楋紵',
L158: message.warning('璇峰厛鍕鹃€夎鍒犻櫎鐨勬暟鎹?);
L162: title: '鎵归噺鍒犻櫎纭',
L163: content: `鎮ㄧ‘瀹氳鍒犻櫎閫変腑鐨?${selectedRowKeys.length} 鏉″憡璀︽ā鍨嬪悧锛熷垹闄ゅ悗涓嶅彲鎭㈠锛乣,
L171: message.success('鎵归噺鍒犻櫎鎴愬姛');
L175: message.error('鎵归噺鍒犻櫎澶辫触');
L197: message.success(editingItem ? '鏇存柊鎴愬姛' : t('common.addSuccess'));
L209: { title: '閿欒缂栫爜', dataIndex: 'errorCode', key: 'errorCode' },
L211: title: '閿欒鏉ユ簮',
L217: title: '鍏宠仈宸ュ崟妯″瀷',
L226: title: '鑷姩鐢熸垚宸ュ崟',
L229: render: (val: boolean) => val ? '鏄? : '鍚?
L253: <Button type="primary" icon={<PlusOutlined />} onClick={handleAdd}>鏂板鍛婅妯″瀷</Button>
L261: 鎵归噺鍒犻櫎{selectedRowKeys.length ? `(${selectedRowKeys.length})` : ''}
L275: title={editingItem ? '缂栬緫鍛婅妯″瀷' : '鏂板鍛婅妯″瀷'}
L282: {/* 閿欒缂栫爜锛堝叧鑱旈敊璇鐞嗭級 */}
L284: label="閿欒缂栫爜"
L286: rules={[{ required: true, message: '璇烽€夋嫨閿欒缂栫爜' }]}
L288: <Select placeholder="璇烽€夋嫨閿欒缂栫爜" options={errorCodeOptions} allowClear />
L291: {/* 宸ュ崟妯″瀷ID锛堝叧鑱斿伐鍗曟ā鍨嬶級 */}
L293: label="鍏宠仈宸ュ崟妯″瀷"
L295: rules={[{ required: true, message: '璇烽€夋嫨宸ュ崟妯″瀷' }]}
L297: <Select placeholder="璇烽€夋嫨宸ュ崟妯″瀷" options={modelOptions} allowClear />
L301: label="閿欒鏉ユ簮"
L303: rules={[{ required: true, message: '璇烽€夋嫨閿欒鏉ユ簮' }]}
L305: <Select placeholder="璇烽€夋嫨閿欒鏉ユ簮" options={errorSourceOptions} allowClear />
L309: {/* 鏄惁鑷姩鐢熸垚宸ュ崟 */}
L311: label="鑷姩鐢熸垚宸ュ崟"
 
### src\components\SystemSetting\AllDeviceManagement.tsx (21)
L24: { id: 1, code: 'CAM-01', name: '鎽勫儚澶?CAM-01', type: 'CAMERA', online: 'ONLINE', status: 'NORMAL' },
L25: { id: 2, code: 'CAM-02', name: '鎽勫儚澶?CAM-02', type: 'CAMERA', online: 'OFFLINE', status: 'FAULT' },
L26: { id: 3, code: 'CAM-03', name: '鎽勫儚澶?CAM-03', type: 'CAMERA', online: 'ONLINE', status: 'NORMAL' },
L27: { id: 4, code: 'CLEAN-01', name: '娓呮礂鏈哄櫒浜?CLEAN-01', type: 'CLEANING_DEVICE', online: 'ONLINE', status: 'IDLE' },
L28: { id: 5, code: 'CMB-A01', name: '姹囨祦绠?CMB-A01', type: 'COMBINER_BOX', online: 'ONLINE', status: 'WARNING' },
L29: { id: 6, code: 'CMB-A02', name: '姹囨祦绠?CMB-A02', type: 'COMBINER_BOX', online: 'ONLINE', status: 'NORMAL' },
L30: { id: 7, code: 'INV-A01', name: '閫嗗彉鍣?INV-A01', type: 'INVERTER', online: 'ONLINE', status: 'NORMAL' },
L31: { id: 8, code: 'INV-A02', name: '閫嗗彉鍣?INV-A02', type: 'INVERTER', online: 'ONLINE', status: 'WARNING' },
L32: { id: 9, code: 'INV-B01', name: '閫嗗彉鍣?INV-B01', type: 'INVERTER', online: 'ONLINE', status: 'NORMAL' },
L33: { id: 10, code: 'METER-01', name: '鐢佃〃 METER-01', type: 'METER', online: 'ONLINE', status: 'NORMAL' },
L34: { id: 11, code: 'ROBOT-01', name: '杩愮淮鏈哄櫒浜?ROBOT-01', type: 'ROBOT', online: 'ONLINE', status: 'IDLE' },
L35: { id: 12, code: 'DRONE-01', name: '鏃犱汉鏈?DRONE-01', type: 'DRONE', online: 'OFFLINE', status: 'FAULT' },
L36: { id: 13, code: 'WEATHER-01', name: '姘旇薄绔?WEATHER-01', type: 'WEATHER_STATION', online: 'ONLINE', status: 'NORMAL' },
L47: { title: '璁惧缂栫爜', dataIndex: 'code', key: 'code' },
L57: title: '杩愯', dataIndex: 'status', key: 'status',
L104: title: '缂栬緫璁惧',
L105: content: `缂栬緫璁惧锛?{record.name}`,
L111: title: '纭鍒犻櫎',
L112: content: `纭畾瑕佸垹闄よ澶?${record.name} 鍚楋紵`,
L124: <Input placeholder="璇疯緭鍏ヨ澶囧悕绉? style={{ width: 220 }} />
L147: showTotal: (total) => `鍏?${total} 鏉,
 
### src\components\SystemSetting\BasicSettings.tsx (78)
L75: message.success('璁剧疆宸蹭繚瀛?);
L81: title: '褰撳墠鐗堟湰',
L83: tag: '鏈€鏂扮増',
L97: title: '鍛婅閫氶亾',
L105: title: '鏁版嵁澶囦唤鐘舵€?,
L113: title: '鏈€杩戞洿鏂?,
L123: title: '瓒呯骇绠$悊鍛?,
L126: tags: ['鍏ㄩ儴鏉冮檺', '绯荤粺绠$悊'],
L132: title: '杩愮淮宸ョ▼甯?,
L135: tags: [t('router.devices'), '宸ュ崟绠$悊'],
L141: title: '宸℃涓荤',
L144: tags: ['宸℃绠$悊', '鍛婅澶勭悊'],
L150: title: '鏁版嵁鍒嗘瀽甯?,
L153: tags: ['鏁版嵁鍒嗘瀽', '鎶ヨ〃鏌ョ湅'],
L164: { name: '姘旇薄绔?, count: '1/1', status: t('roles.normal') },
L168: { name: 'API鎺ュ彛', count: t('roles.normal'), status: t('roles.normal') },
L179: {/* 椤堕儴缁熻鍗$墖 */}
L203: {/* 宸︿晶 */}
L205: {/* 鍩虹閰嶇疆 */}
L207: title={<Space><SettingOutlined style={{ color: '#1677ff' }} /><b>鍩虹閰嶇疆</b></Space>}
L220: <Form.Item label="榛樿鐢电珯" name="defaultSite" style={{ marginBottom: 12 }}>
L242: <Form.Item label="棣栭〉榛樿椤甸潰" name="defaultPage" style={{ marginBottom: 12 }}>
L249: <Form.Item label="鏁版嵁鍒锋柊棰戠巼" name="refreshRate" style={{ marginBottom: 12 }}>
L251: <Select.Option value="5min">5 鍒嗛挓</Select.Option>
L256: <Form.Item label="鍦板浘鏈嶅姟" name="mapService" style={{ marginBottom: 12 }}>
L258: <Select.Option value="gaode">楂樺痉鍦板浘</Select.Option>
L265: <span style={{ fontSize: fontSmall }}>宸ュ崟鑷姩缂栧彿</span>
L269: <span style={{ fontSize: fontSmall }}>AI寤鸿鑷姩鐢熸垚</span>
L273: <span style={{ fontSize: fontSmall }}>绉诲姩绔悓姝?/span>
L280: <Button type="primary" size="small" onClick={handleSave} style={{ width: 100, borderRadius: 6 }}>淇濆瓨璁剧疆</Button>
L281: <Button size="small" style={{ marginLeft: 8, borderRadius: 6 }}>鎭㈠榛樿</Button>
L286: {/* 閫氱煡涓庡憡璀︾瓥鐣?*/}
L288: title={<Space><BellOutlined style={{ color: '#1677ff' }} /><b>閫氱煡涓庡憡璀︾瓥鐣?/b></Space>}
L295: { label: '鐭俊', icon: <Smartphone size={16} />, color: '#52c41a', status: '宸插惎鐢? },
L296: { label: '閭欢', icon: <Mail size={16} />, color: '#1677ff', status: '宸插惎鐢? },
L297: { label: 'Telegram', icon: <Send size={16} />, color: '#13c2c2', status: '宸插惎鐢? },
L298: { label: '绯荤粺閫氱煡', icon: <BellOutlined style={{ fontSize: 16 }} />, color: '#fa8c16', status: '宸插惎鐢? },
L315: <Col xs={24} sm={12} md={8}><Space size={8}><span style={{ fontSize: fontSmall }}>涓ラ噸鍛婅绔嬪嵆閫氱煡</span><Switch size="small" defaultChecked /></Space></Col>
L316: <Col xs={24} sm={12} md={8}><Space size={8}><span style={{ fontSize: fontSmall }}>鍙戠數涓嬮檷瓒呰繃 15%</span><Switch size="small" defaultChecked /></Space></Col>
L317: <Col xs={24} sm={12} md={8}><Space size={8}><span style={{ fontSize: fontSmall }}>閫氫俊涓柇閫氱煡</span><Switch size="small" defaultChecked /></Space></Col>
L318: <Col xs={24} sm={12} md={8}><Space size={8}><span style={{ fontSize: fontSmall }}>姣忔棩姹囨€绘帹閫?/span><Switch size="small" defaultChecked /></Space></Col>
L321: <span style={{ fontSize: fontSmall }}>澶滈棿鍏嶆墦鎵?/span>
L329: {/* 鐢ㄦ埛涓庢潈闄愰瑙?*/}
L331: title={<Space><Users size={16} style={{ color: '#1677ff' }} /><b>鐢ㄦ埛涓庢潈闄愰瑙?/b></Space>}
L343: pagination={{ size: 'small', total: 4, pageSize: 4, showTotal: (total) => `鍏?${total} 鏉 }}
L345: { title: '鐢ㄦ埛鍚?, dataIndex: 'name', key: 'name', fixed: 'left', width: 80 },
L353: '瓒呯骇绠$悊鍛?: { color: '#1677ff', bg: '#e6f4ff' },
L354: '杩愮淮宸ョ▼甯?: { color: '#52c41a', bg: '#f6ffed' },
L355: '宸℃涓荤': { color: '#fa8c16', bg: '#fff7e6' },
L356: '鏁版嵁鍒嗘瀽甯?: { color: '#722ed1', bg: '#f9f0ff' },
L383: 鏌ョ湅
L388: { name: '寮犺繍缁?, role: '瓒呯骇绠$悊鍛?, phone: '138****0001', email: 'zhangyw@pvsmart.com', status: t('devices.online') },
L389: { name: '鏉庡伐绋嬪笀', role: '杩愮淮宸ョ▼甯?, phone: '139****0002', email: 'li.gongcheng@pvsmart.com', status: t('devices.online') },
L390: { name: '鐜嬬彮闀?, role: '宸℃涓荤', phone: '137****0003', email: 'wang.banzhang@pvsmart.com', status: t('devices.online') },
L391: { name: '璧靛垎鏋愬笀', role: '鏁版嵁鍒嗘瀽甯?, phone: '136****0004', email: 'zhao.fx@pvsmart.com', status: t('devices.online') },
L397: {/* 鍙充晶 */}
L399: {/* 瑙掕壊鏉冮檺姒傝 */}
L401: title={<Space><Users size={16} style={{ color: '#1677ff' }} /><b>瑙掕壊鏉冮檺姒傝</b></Space>}
L416: 鐢ㄦ埛 {role.users} | 鏉冮檺 {role.perms}
L429: {/* 璁惧鎺ュ叆鐘舵€?*/}
L431: title={<Space><ApiOutlined style={{ color: '#1677ff' }} /><b>璁惧鎺ュ叆鐘舵€?/b></Space>}
L432: extra={<Button type="link" size="small" style={{ fontSize: 11, padding: 0 }}>璇︽儏 <RightOutlined style={{ fontSize: 9 }} /></Button>}
L471: { x: 160, y: 80, icon: <Wind size={10} />, label: '姘旇薄绔? },
L474: { x: 40, y: 80, icon: <Zap size={10} />, label: '鎺ュ彛' },
L489: {/* 鏁版嵁涓庡畨鍏?*/}
L498: { label: '鏁版嵁淇濈暀', value: '3 骞?, icon: <DatabaseOutlined style={{ color: '#1677ff' }} /> },
L499: { label: '鐧诲綍瀹¤', value: '宸插紑鍚?, icon: <CheckCircleOutlined style={{ color: '#52c41a' }} />, color: '#52c41a' },
L500: { label: '鑷姩澶囦唤', value: '02:00', icon: <RefreshCw size={12} color="#1677ff" /> },
L501: { label: 'API 瀵嗛挜', value: t('roles.normal'), icon: <Key size={12} color="#52c41a" />, color: '#52c41a' },
L502: { label: '鏈€杩戝浠?, value: '2025-05-24 02:00', icon: <CalendarOutlined style={{ color: '#1677ff' }} /> },
L503: { label: 'SSL 璇佷功', value: '鏈夋晥鏈熻嚦 2026-12-31', icon: <SafetyCertificateOutlined style={{ color: '#fa8c16' }} /> },
L504: { label: '鍙屽洜绱犺璇?, value: '宸插紑鍚?, icon: <Lock size={12} color="#52c41a" />, color: '#52c41a' },
L519: {/* 绯荤粺缁存姢 */}
L522: extra={<Button type="link" size="small" danger style={{ fontSize: 10, padding: 0 }}>绠$悊鏉冮檺</Button>}
L529: { label: '娓呯悊缂撳瓨', icon: <DeleteOutlined />, color: '#1677ff' },
L530: { label: '閲嶅惎鏈嶅姟', icon: <RefreshCw size={16} />, color: '#1677ff' },
L531: { label: '澶囦唤涓嬭浇', icon: <DownloadOutlined />, color: '#1677ff' },
L532: { label: '鏃ュ織瀵煎嚭', icon: <FileTextOutlined />, color: '#1677ff' },
 
### src\components\SystemSetting\CameraManagement.tsx (63)
L35: name: '涓滈棬鍏ュ彛鎽勫儚澶?,
L39: location: '鍥尯涓滈棬',
L40: type: '楂樻竻鐞冩満',
L41: manufacturer: '娴峰悍濞佽',
L49: name: '瑗块棬鍏ュ彛鎽勫儚澶?,
L53: location: '鍥尯瑗块棬',
L54: type: '楂樻竻鏋満',
L55: manufacturer: '澶у崕',
L63: name: '鍋滆溅鍦烘憚鍍忓ご',
L67: location: '鍦颁笅鍋滆溅鍦築1',
L68: type: '楂樻竻鐞冩満',
L69: manufacturer: '娴峰悍濞佽',
L77: name: '鍔炲叕妤煎ぇ鍫傛憚鍍忓ご',
L81: location: '鍔炲叕妤?灞傚ぇ鍫?,
L82: type: '鍗婄悆鎽勫儚鏈?,
L83: manufacturer: '瀹囪',
L91: name: '浠撳簱鐩戞帶鎽勫儚澶?,
L95: location: '鐗╂枡浠撳簱',
L96: type: '楂樻竻鏋満',
L97: manufacturer: '娴峰悍濞佽',
L115: { title: '璁惧缂栫爜', dataIndex: 'code', key: 'code', width: 120 },
L118: { title: '鎽勫儚澶寸被鍨?, dataIndex: 'type', key: 'type', width: 120 },
L119: { title: '鍝佺墝', dataIndex: 'manufacturer', key: 'manufacturer', width: 120 },
L120: { title: '鍒嗚鲸鐜?, dataIndex: 'resolution', key: 'resolution', width: 100 },
L131: title: '浜戝彴', dataIndex: 'ptz', key: 'ptz', width: 80,
L132: render: (ptz) => ptz ? <Tag color="blue">鏀寔</Tag> : <Tag color="default">涓嶆敮鎸?/Tag>
L135: title: '澶滆', dataIndex: 'nightVision', key: 'nightVision', width: 80,
L136: render: (nv) => nv ? <Tag color="green">鏀寔</Tag> : <Tag color="default">涓嶆敮鎸?/Tag>
L164: <Button type="link" icon={<VideoCameraOutlined />} onClick={() => handleView(record)}>棰勮</Button>
L205: title: `${record.name} - 瑙嗛棰勮`,
L220: <span>瑙嗛棰勮鍗犱綅 - {record.name}</span>
L236: title: '纭鍒犻櫎',
L237: content: `纭畾瑕佸垹闄ゆ憚鍍忓ご ${record.name} 鍚楋紵`,
L264: <div style={{ color: '#86909C', fontSize: 12 }}>鎽勫儚澶存€绘暟</div>
L312: <div style={{ color: '#86909C', fontSize: 12 }}>绂荤嚎/鏁呴殰</div>
L338: <Input placeholder="璇疯緭鍏ュ悕绉?缂栫爜/IP" style={{ width: 240 }} prefix={<SearchOutlined />} />
L341: <Select placeholder="鐘舵€佺瓫閫? style={{ width: 140 }} allowClear>
L354: <Button type="primary" icon={<PlusOutlined />} onClick={handleAdd}>鏂板鎽勫儚澶?/Button>
L369: showTotal: (total) => `鍏?${total} 鏉,
L375: title={currentCamera ? '缂栬緫鎽勫儚澶? : '鏂板鎽勫儚澶?}
L387: <Form.Item label="璁惧缂栫爜" name="code" rules={[{ required: true, message: '璇疯緭鍏ヨ澶囩紪鐮? }]}>
L388: <Input placeholder="璇疯緭鍏ヨ澶囩紪鐮? />
L392: <Form.Item label={t('devices.deviceName')} name="name" rules={[{ required: true, message: '璇疯緭鍏ヨ澶囧悕绉? }]}>
L393: <Input placeholder="璇疯緭鍏ヨ澶囧悕绉? />
L397: <Form.Item label={t('systemSetting.ipAddress')} name="ip" rules={[{ required: true, message: '璇疯緭鍏P鍦板潃' }]}>
L398: <Input placeholder="渚嬪: 192.168.1.100" />
L402: <Form.Item label="鎽勫儚澶寸被鍨? name="type" rules={[{ required: true }]}>
L403: <Select placeholder="璇烽€夋嫨绫诲瀷">
L404: <Select.Option value="楂樻竻鐞冩満">楂樻竻鐞冩満</Select.Option>
L405: <Select.Option value="楂樻竻鏋満">楂樻竻鏋満</Select.Option>
L406: <Select.Option value="鍗婄悆鎽勫儚鏈?>鍗婄悆鎽勫儚鏈?/Select.Option>
L407: <Select.Option value="鍏ㄦ櫙鎽勫儚鏈?>鍏ㄦ櫙鎽勫儚鏈?/Select.Option>
L412: <Form.Item label="鍝佺墝" name="manufacturer">
L413: <Select placeholder="璇烽€夋嫨鍝佺墝">
L414: <Select.Option value="娴峰悍濞佽">娴峰悍濞佽</Select.Option>
L415: <Select.Option value="澶у崕">澶у崕</Select.Option>
L416: <Select.Option value="瀹囪">瀹囪</Select.Option>
L422: <Form.Item label="鍒嗚鲸鐜? name="resolution">
L423: <Select placeholder="璇烽€夋嫨鍒嗚鲸鐜?>
L432: <Form.Item label="瀹夎浣嶇疆" name="location">
L433: <Input placeholder="璇疯緭鍏ュ畨瑁呬綅缃? prefix={<EnvironmentOutlined />} />
L437: <Form.Item label="浜戝彴鎺у埗" name="ptz" valuePropName="checked">
L442: <Form.Item label="澶滆鍔熻兘" name="nightVision" valuePropName="checked">
 
### src\components\SystemSetting\DeviceAccessPage.tsx (155)
L36: const [deviceList, setDeviceList] = useState([]); // 馃憟 鏇挎崲杩欒
L76: { id: 2, code: 'record_status', name: '褰曞儚鐘舵€?, type: 'string', rw: 'r', isAlarm: false, unit: '', required: true, defaultValue: null },
L78: events: [{ id: 1, code: 'alarm_perimeter', name: '鍛ㄧ晫鍏ヤ镜鍛婅' }],
L84: { id: 2, code: 'humi', name: '婀垮害', type: 'float', rw: 'r', isAlarm: true, unit: '%', required: true, defaultValue: null },
L86: events: [{ id: 1, code: 'temp_over', name: '瓒呮俯鍛婅' }],
L92: { id: 2, code: 'voltage', name: '鐢靛帇', type: 'float', rw: 'r', isAlarm: true, unit: 'V', required: true, defaultValue: null },
L94: events: [{ id: 1, code: 'low_power', name: '浣庣數閲忓憡璀? }],
L162: fetchModelPageList(); // 銆愪紭鍖栥€戝垹闄ゅ悗鍒锋柊
L164: messageApi.error('鍒犻櫎澶辫触锛? + res.msg);
L173: fetchProductPageList(); // 銆愪紭鍖栥€戝垹闄ゅ悗鍒锋柊
L175: messageApi.error('鍒犻櫎澶辫触锛? + res.msg);
L226: actionConfig = record.thingsModels[modelId].actions || {}; // 馃憟 琛屼负閰嶇疆鍥炴樉
L284: id: editData?.id, // 缂栬緫鎵嶆湁
L285: deviceName: values.name, // 璁惧鍚嶇О
L288: modelId: values.modelId || 10, // 榛樿缁欎竴涓? L294: remark: values.remark || '闃靛垪鍖虹洃鎺ц澶?,
L301: res = await updateIotDevice(submitData); // 缂栬緫
L303: res = await addIotDevice(submitData); // 鏂板
L307: messageApi.success(editData ? '缂栬緫璁惧鎴愬姛' : '鏂板璁惧鎴愬姛');
L310: messageApi.error(res.msg || '鎿嶄綔澶辫触');
L358: messageApi.success(editData ? '浜у搧缂栬緫鎴愬姛' : '浜у搧鏂板鎴愬姛');
L446: { title: t('devices.deviceName'), dataIndex: 'deviceName' }, // 馃憟 鏀规垚 deviceName
L448: { title: '浜у搧ID', dataIndex: 'productId' },
L449: { title: '妯″瀷ID', dataIndex: 'modelId' },
L451: { title: '绔彛', dataIndex: 'port' },
L452: { title: '璐﹀彿', dataIndex: 'username' },
L464: 缂栬緫
L471: { title: '妯″瀷鍚嶇О', dataIndex: 'name' },
L472: { title: '杩炴帴鍗忚', dataIndex: 'connectType' },
L474: title: '灞炴€у垪琛?, width: 300, render: (record) => {
L476: if (list.length === 0) return <span style={{ color: '#999' }}>鏃犲睘鎬?/span>;
L481: title: '鎸囦护鍒楄〃', width: 300, render: (record) => {
L483: if (list.length === 0) return <span style={{ color: '#999' }}>鏃犳寚浠?/span>;
L491: <Popconfirm title="纭畾瑕佸垹闄よ鐗╂ā鍨嬪悧锛? onConfirm={() => handleDeleteModel(r.id)} okText={t('common.ok')} cancelText={t('common.cancel')}>
L507: <TabPane tab={<span><ProductOutlined />浜у搧绠$悊</span>} key="product" />
L508: <TabPane tab={<span><AppstoreOutlined />鐗╂ā鍨嬬鐞?/span>} key="model" />
L512: {activeTab === 'device' && <Card><Space className="mb-3"><Button type="primary" icon={<PlusOutlined />} onClick={() => openModal('device')}>鏂板璁惧</Button></Space>
L529: <Form.Item name="code" label="浜у搧缂栫爜">
L530: <Input placeholder="璇疯緭鍏ョ紪鐮? allowClear />
L532: <Form.Item name="name" label="浜у搧鍚嶇О">
L533: <Input placeholder="璇疯緭鍏ュ悕绉? allowClear />
L535: <Form.Item name="manufacturer" label="鐢熶骇鍘傚">
L536: <Input placeholder="璇疯緭鍏ュ巶瀹? allowClear />
L539: <Form.Item name="protocolCode" label="鍗忚缂栫爜">
L540: <Select placeholder="璇烽€夋嫨鍗忚" allowClear style={{ width: 140 }}>
L546: <Form.Item name="transport" label="浼犺緭鏂瑰紡">
L547: <Select placeholder="浼犺緭鏂瑰紡" allowClear style={{ width: 120 }}>
L555: <Option value={0}>绂佺敤</Option>
L564: 鏂板浜у搧
L572: { title: '浜у搧缂栫爜', dataIndex: 'code', width: 120 },
L573: { title: '浜у搧鍚嶇О', dataIndex: 'name', width: 160 },
L574: { title: '鐢熶骇鍘傚', dataIndex: 'manufacturer', width: 130 },
L575: { title: '鍗忚', dataIndex: 'protocolCode', width: 100 },
L576: { title: '浼犺緭鏂瑰紡', dataIndex: 'transport', width: 100 },
L577: { title: '涓婃姤Topic', dataIndex: 'uploadTopic', ellipsis: true },
L578: { title: '璁㈤槄Topic', dataIndex: 'subscribeTopic', ellipsis: true },
L583: render: (s) => <Tag color={s === 1 ? 'green' : 'red'}>{s === 1 ? t('common.enable') : '绂佺敤'}</Tag>
L589: <Button type="text" icon={<SwapOutlined />} onClick={() => openMappingModal()}>瀛楁鏄犲皠</Button>
L591: title="纭畾瑕佸垹闄よ浜у搧鍚楋紵"
L608: showTotal: (total) => `鍏?${total} 鏉
L621: <Form.Item name="name" label="妯″瀷鍚嶇О">
L624: <Form.Item name="connectType" label="杩炴帴鍗忚">
L625: <Select placeholder="鍗忚" allowClear style={{ width: 160 }}>
L636: <Button type="primary" icon={<PlusOutlined />} onClick={() => openModal('model')}>鏂板鐗╂ā鍨?/Button>
L646: title={modalType === 'device' ? '璁惧閰嶇疆' : modalType === 'product' ? '浜у搧閰嶇疆' : '鐗╂ā鍨嬮厤缃?}>
L653: rules={[{ required: true, message: '璇疯緭鍏ヨ澶囧悕绉? }]}
L655: <Input placeholder="璇疯緭鍏ヨ澶囧悕绉? />
L659: label="璁惧SN"
L661: rules={[{ required: true, message: '璇疯緭鍏ヨ澶嘢N' }]}
L663: <Input placeholder="璇疯緭鍏ヨ澶嘢N" />
L667: label="鍏宠仈浜у搧"
L669: rules={[{ required: true, message: '璇烽€夋嫨鍏宠仈浜у搧' }]}
L672: placeholder="璇烽€夋嫨鍏宠仈浜у搧"
L708: {/* ONVIF 閰嶇疆 */}
L711: <Form.Item label="IP 鍦板潃" name="ip">
L712: <Input placeholder="渚嬪锛?92.168.1.65" />
L714: <Form.Item label="绔彛" name="port">
L715: <InputNumber className="w-full" placeholder="榛樿 80" />
L717: <Form.Item label="鐧诲綍璐﹀彿" name="username">
L718: <Input placeholder="璁惧鐧诲綍璐﹀彿" />
L720: <Form.Item label="鐧诲綍瀵嗙爜" name="password">
L721: <Input.Password placeholder="璁惧鐧诲綍瀵嗙爜" />
L726: {/* RTSP 閰嶇疆 */}
L728: <Form.Item label="RTSP 鍦板潃" name="rtspUrl">
L733: {/* MQTT 閰嶇疆 */}
L736: <Form.Item label="MQTT 鏈嶅姟鍦板潃" name="mqttServer">
L739: <Form.Item label="MQTT 绔彛" name="mqttPort">
L743: <Input placeholder="瀹㈡埛绔敮涓€鏍囪瘑" />
L745: <Form.Item label="MQTT 鐢ㄦ埛鍚? name="mqttUsername">
L746: <Input placeholder="MQTT 璐﹀彿锛堥€夊~锛? />
L748: <Form.Item label="MQTT 瀵嗙爜" name="mqttPassword">
L749: <Input.Password placeholder="MQTT 瀵嗙爜锛堥€夊~锛? />
L754: {/* 鍛婅闃堝€奸厤缃?*/}
L755: <Divider>鍛婅闃堝€奸厤缃?/Divider>
L761: label={`${item.name} 涓婇檺`}
L765: <InputNumber className="w-full" placeholder="涓婇檺鍊? />
L768: label={`${item.name} 涓嬮檺`}
L772: <InputNumber className="w-full" placeholder="涓嬮檺鍊? />
L777: <Empty description="褰撳墠鐗╂ā鍨嬫湭璁剧疆鍛婅灞炴€э紝鏃犳硶閰嶇疆闃堝€? />
L785: <Form.Item label="浜у搧缂栧彿" name="code" rules={[{ required: true }]}>
L788: <Form.Item label="浜у搧鍚嶇О" name="name" rules={[{ required: true }]}>
L789: <Input placeholder="鏅鸿兘缃戝叧" />
L791: <Form.Item label="鍘傚晢" name="manufacturer">
L792: <Input placeholder="杩堟绉戞妧" />
L798: <Form.Item label="浼犺緭绫诲瀷" name="transport">
L799: <Select placeholder="浼犺緭鏂瑰紡">
L808: <Option value={0}>绂佺敤</Option>
L813: <Divider>缁戝畾鐗╂ā鍨?/Divider>
L814: <Form.Item label="缁戝畾鐗╂ā鍨? name="modelId">
L816: placeholder="璇烽€夋嫨瑕佺粦瀹氱殑鐗╂ā鍨?
L869: <Divider>鍗忚鑷姩閰嶇疆椤?/Divider>
L871: <Form.Item label="涓婃姤Topic" name="uploadTopic">
L874: <Form.Item label="璁㈤槄Topic" name="subscribeTopic">
L881: {/* ==== 灞炴€ч厤缃紙浣犲師鏉ョ殑锛?==== */}
L882: <Divider>鐗╂ā鍨嬪睘鎬ч厤缃?/Divider>
L890: <Form.Item label="鏈€灏忓€? name={['limitConfig', item.propertyKey, 'min']} style={{ flex: 1 }}>
L891: <InputNumber style={{ width: '100%' }} placeholder="鏈€灏忓€? />
L893: <Form.Item label="鏈€澶у€? name={['limitConfig', item.propertyKey, 'max']} style={{ flex: 1 }}>
L894: <InputNumber style={{ width: '100%' }} placeholder="鏈€澶у€? />
L901: 璇烽€夋嫨鐗╂ā鍨嬩互鏄剧ず灞炴€? L906: {/* ==== 鉁?琛屼负锛堟寚浠わ級閰嶇疆 鏂板 ==== */}
L907: <Divider>鐗╂ā鍨嬭涓猴紙鎸囦护锛夐厤缃?/Divider>
L918: label={`${paramKey} 榛樿鍊糮}
L922: <Input style={{ width: '100%' }} placeholder="榛樿鍊? />
L945: 璇ョ墿妯″瀷鏆傛棤鎸囦护
L957: <Form.Item label="妯″瀷鍚嶇О" name="name" rules={[{ required: true }]}><Input /></Form.Item>
L960: <Form.Item label="杩炴帴鍗忚" name="connectType" initialValue="MQTT">
L970: <Divider>灞炴€?/Divider>
L973: { title: '缂栫爜', dataIndex: 'code' },
L976: { title: '鍗曚綅', dataIndex: 'unit' },
L977: { title: '榛樿鍊?, dataIndex: 'defaultValue' },
L989: <Divider>鎸囦护</Divider>
L996: { title: '鎸囦护缂栫爜', dataIndex: 'actionId' },
L997: { title: '鎸囦护鍚嶇О', dataIndex: 'actionName' },
L998: { title: '鍙傛暟', render: r => Object.keys(r.params || []).join(',') || '鏃? },
L1033: {/* 灞炴€у脊绐?*/}
L1034: <Modal open={itemModal} width={580} zIndex={1001} destroyOnClose onCancel={() => setItemModal(false)} onOk={saveItem} title="閰嶇疆灞炴€?>
L1037: <Form.Item label="灞炴€х紪鐮? name="code" rules={[{ required: true }]}><Input placeholder="濡?temp" /></Form.Item>
L1038: <Form.Item label="灞炴€у悕绉? name="name" rules={[{ required: true }]}><Input placeholder="濡?娓╁害" /></Form.Item>
L1046: <Form.Item label="鍗曚綅" name="unit"><Input placeholder="鈩冦€?銆乂" /></Form.Item>
L1047: <Form.Item label="榛樿鍊? name="defaultValue"><Input /></Form.Item>
L1048: <Form.Item label="鍛婅鍙傛暟" name="isAlarm" valuePropName="checked"><Switch /></Form.Item>
L1052: {/* 鎸囦护寮圭獥 */}
L1053: <Modal title="閰嶇疆鎸囦护" open={actionModal} zIndex={1002} onCancel={() => setActionModal(false)}
L1069: <Input placeholder="鎸囦护缂栫爜" value={currentAction?.actionId} onChange={e => setCurrentAction({ ...currentAction, actionId: e.target.value })} style={{ flex: 1 }} />
L1070: <Input placeholder="鎸囦护鍚嶇О" value={currentAction?.actionName} onChange={e => setCurrentAction({ ...currentAction, actionName: e.target.value })} style={{ flex: 1 }} />
L1072: <Divider>鎸囦护鍙傛暟</Divider>
L1074: <Input placeholder="鍙傛暟鍚? value={paramList[0]?.paramKey || ''} onChange={e => setParamList([{ ...paramList[0], paramKey: e.target.value }])} />
L1081: <Input placeholder="榛樿鍊? value={paramList[0]?.defaultValue || ''} onChange={e => setParamList([{ ...paramList[0], defaultValue: e.target.value }])} />
L1082: <Input placeholder="鏋氫妇(,鍒嗛殧)" value={(paramList[0]?.enum || []).join(',')} onChange={e => setParamList([{ ...paramList[0], enum: e.target.value.split(',').map(s => s.trim()) }])} />
L1086: {/* 瀛楁鏄犲皠 */}
L1087: <Modal open={mappingModal} width={600} zIndex={1002} destroyOnClose onCancel={() => setMappingModal(false)} onOk={saveMapping} title="瀛楁鏄犲皠">
L1090: <Form.Item label="鏍囧噯瀛楁" name="standardCode" rules={[{ required: true }]}>
L1093: <Form.Item label="鍘傚晢鍘熷瀛楁" name="sourceField" rules={[{ required: true }]}><Input /></Form.Item>
L1094: <Form.Item label="杞崲瑙勫垯" name="convertRule"><Input /></Form.Item>
 
### src\components\SystemSetting\DeviceManagement.tsx (5)
L39: console.error('鍒濆鍖栧叏閲忔暟鎹け璐?, err);
L92: { key: 'drone', label: '鏃犱汉鏈虹鐞? },
L93: { key: 'smart', label: '鏅鸿兘瑁呭' },
L94: { key: 'camera', label: '鎽勫儚澶寸鐞? },
L95: { key: 'serialGenerate', label: '鏈哄櫒浜虹敓鎴? },
 
### src\components\SystemSetting\DroneManagement.tsx (42)
L91: utils.message.error('鑾峰彇鏃犱汉鏈哄垪琛ㄥけ璐?);
L105: console.error('鑾峰彇缁勭粐鍒楄〃澶辫触', err);
L146: return utils.message.warning('璇峰厛鍦ㄥ垪琛ㄤ腑閫変腑闇€瑕佺粦瀹氱殑鏃犱汉鏈?);
L213: utils.message.success('缁戝畾鎴愬姛');
L220: utils.message.error(res.msg || '缁戝畾澶辫触');
L223: utils.message.error('鎿嶄綔寮傚父');
L232: return utils.message.warning('鏈€夋嫨鏈夋晥璁惧锛屾棤娉曡В缁?);
L234: const typeText = { 1: '浜哄憳', 2: '鍦虹珯', 3: '缁勭粐' }[type];
L236: title: '纭瑙g粦',
L237: content: `纭畾瑕佷负閫変腑鐨勬棤浜烘満娓呴櫎${typeText}缁戝畾鍚楋紵`,
L244: utils.message.success('瑙g粦鎴愬姛');
L249: utils.message.error(res.msg || '瑙g粦澶辫触');
L252: utils.message.error('鎿嶄綔寮傚父');
L261: { title: '鏈哄満SN', width: 150, dataIndex: 'gateway_sn', key: 'gsn' },
L263: title: '鎵€灞炵粍缁?, width: 150, key: 'orgName',
L266: return org ? (org.orgName || org.name) : <Text type="secondary">鏈粦瀹?/Text>;
L270: title: '鎵€灞炲満绔?, width: 150, key: 'siteName',
L273: return site ? (site.siteName || site.name) : <Text type="secondary">鏈粦瀹?/Text>;
L280: return user ? (user.nickName || user.userName) : <Text type="secondary">鏈粦瀹?/Text>;
L291: <Tooltip title="浜哄憳瑙g粦">
L292: <Button size="small" icon={<DisconnectOutlined />} onClick={() => handleUnbind([record.gateway_sn], 1)}>鐢ㄦ埛</Button>
L294: <Tooltip title="鍦虹珯瑙g粦">
L295: <Button size="small" icon={<DisconnectOutlined />} onClick={() => handleUnbind([record.gateway_sn], 2)}>鍦虹珯</Button>
L297: <Tooltip title="缁勭粐瑙g粦">
L298: <Button size="small" icon={<DisconnectOutlined />} onClick={() => handleUnbind([record.gateway_sn], 3)}>缁勭粐</Button>
L324: placeholder="鏈哄満SN"
L341: <Button type="primary" icon={<LinkOutlined />} onClick={openBindModal}>缁戝畾鏃犱汉鏈?/Button>
L342: <Button disabled={selectedDroneKeys.length === 0} onClick={() => handleUnbind(selectedDroneKeys, 1)}>鎵归噺瑙g粦(鐢ㄦ埛)</Button>
L343: <Button disabled={selectedDroneKeys.length === 0} onClick={() => handleUnbind(selectedDroneKeys, 2)}>鎵归噺瑙g粦(鍦虹珯)</Button>
L344: <Button disabled={selectedDroneKeys.length === 0} onClick={() => handleUnbind(selectedDroneKeys, 3)}>鎵归噺瑙g粦(缁?</Button>
L359: showTotal: t => `鍏?${t} 鏉,
L372: <span style={{ fontWeight: 600 }}>缁戝畾鏃犱汉鏈?/span>
L388: <Form.Item label={<>宸查€夋棤浜烘満锛坽selectedDroneKeys.length}鍙帮級SN</>} name="sns" rules={[{ required: true, message: '璇疯緭鍏?SN' }]}>
L389: <Input.TextArea placeholder="渚嬪: SN001, SN002" rows={2} disabled style={{ resize: 'none', background: '#fafafa' }} />
L394: <span>鎵€灞炵粍缁?/span>
L397: name="orgId" rules={[{ required: true, message: '璇烽€夋嫨缁勭粐' }]}
L400: placeholder="璇烽€夋嫨缁勭粐"
L418: <span>鎵€灞炲満绔?/span>
L421: name="siteId" rules={[{ required: !siteFieldDisabled, message: '璇烽€夋嫨鍦虹珯' }]}
L424: placeholder="璇峰厛閫夋嫨缁勭粐"
L439: <Form.Item label={t('systemSetting.leader')} name="userId" rules={[{ required: true, message: '璇烽€夋嫨璐熻矗浜? }]}>
L441: placeholder="璇峰厛閫夋嫨鍦虹珯鍚庨€夋嫨璐熻矗浜?
 
### src\components\SystemSetting\ErrorManagement.tsx (11)
L134: console.log('鎻愪氦琛ㄥ崟鏁版嵁', values);
L157: console.log('鎻愪氦琛ㄥ崟鏁版嵁', submitData);
L190: console.log('鍒犻櫎璇锋眰鍙傛暟', data);
L365: {/* 鎼滅储鍖哄煙瀹屽叏涓嶅彉 */}
L416: {/* 鏂板/缂栬緫/鏌ョ湅寮圭獥锛堟牳蹇冧紭鍖栧尯鍩燂級 */}
L453: {/* 绗竴琛岋細鍩虹缂栫爜鍚嶇О */}
L467: {/* 绗簩琛岋細鏉ユ簮銆佺瓑绾с€佹牎楠屽瓧娈?*/}
L494: {/* 绗笁琛岋細瀵规瘮绫诲瀷 + 瀵规瘮鍊硷紙鑷姩鍒囨崲鍗曡緭鍏?鍖洪棿鍙岃緭鍏ワ級 */}
L505: {/* 鍖洪棿绫诲瀷锛欱ETWEEN / NOT_BETWEEN 鏄剧ず涓や釜杈撳叆妗?*/}
L528: {/* 閿欒鎻忚堪 */}
L533: {/* 澶勭悊寤鸿 */}
 
### src\components\SystemSetting\FlvPlayer.tsx (22)
L45: setError('褰撳墠娴忚鍣ㄤ笉鏀寔 FLV MSE鎾斁锛岃涓嬭浇鏂囦欢鏌ョ湅');
L58: stashInitialSize: 4 * 1024 * 1024, // 4MB 閫傞厤4K
L59: lazyLoad: true, // 鉁呭叧閿細澶ф枃浠剁偣鎾笉鑳絝alse锛屽惁鍒欎竴娆℃€у叏閮ㄤ笅杞界珛鍒诲叧闂璏SE
L69: console.log('鉁?canplaythrough 濯掍綋灏辩华');
L75: console.warn('鈿狅笍 video stalled 缂撳啿鍖哄崱椤?);
L81: setError('瑙嗛缂栫爜涓嶅彈娴忚鍣∕SE鏀寔锛岃涓嬭浇鏂囦欢鏈湴鎾斁');
L85: setError('濯掍綋婧愪笉鏀寔');
L104: console.log('鉁?flv 鏂囦欢鍏ㄩ儴鍔犺浇瀹屾垚');
L109: let msg = 'FLV鎾斁寮傚父锛屽缓璁笅杞芥枃浠舵湰鍦版挱鏀?;
L111: msg = '缃戠粶閿欒锛岃妫€鏌ヨ棰戝湴鍧€';
L113: msg = '濯掍綋瑙g爜閿欒锛岃FLV鏂囦欢鍙兘涓嶅吋瀹规祻瑙堝櫒MSE';
L123: setError('鍔犺浇瓒呮椂锛屾祻瑙堝櫒MSE瑙f瀽澶辫触锛岃涓嬭浇鏂囦欢鏈湴鎾斁');
L133: setError('鎾斁鍣ㄥ垵濮嬪寲澶辫触锛岃閲嶈瘯');
L147: setError('瑙嗛鍔犺浇澶辫触锛岃妫€鏌ュ湴鍧€鎴栦笅杞?);
L154: if (!mediaReady) console.warn('鈴板師鐢熻棰戝姞杞芥參');
L182: console.warn('鎵嬪姩鎾斁澶辫触', e);
L189: <Alert message="鎾斁澶辫触" description={error} type="error" showIcon style={{ marginBottom: 16 }} />
L191: <Button icon={<ReloadOutlined />} onClick={handleRetry}>閲嶈瘯</Button>
L193: 涓嬭浇瑙嗛
L209: 鐐瑰嚮鎵嬪姩鎾斁瑙嗛
L225: {isFlv(fileName) && <span>馃挕 FLV 浣跨敤 flv.js(MSE)瑙g爜锛岄儴鍒嗙壒娈婄紪鐮丗LV娴忚鍣ㄦ棤娉曟覆鏌擄紝寤鸿涓嬭浇鏈湴鎾斁</span>}
L226: {!isFlv(fileName) && <span>馃挕 闈濬LV浣跨敤娴忚鍣ㄥ師鐢熸挱鏀?/span>}
 
### src\components\SystemSetting\LogManagement.tsx (22)
L27: { id: 1, time: '2026-08-10 13:02:11', level: 'info', source: '绯荤粺', operator: '绯荤粺', message: '鏈哄櫒浜烘櫤鎱ф湇鍔$郴缁?Alpha 涓夋湇鍔★紙鎺ュ叆/鐘舵€?鍛戒护锛夊惎鍔ㄥ畬鎴? },
L28: { id: 2, time: '2026-08-10 12:58:40', level: 'action', source: '鍛戒护鏈嶅姟', operator: '寮犺繍缁?, message: '鍚?ROBOT-001 涓嬪彂绉诲姩鍛戒护锛坰eq=d6b5d545锛夛紝鎵ц缁撴灉锛氭垚鍔? },
L29: { id: 3, time: '2026-08-10 12:51:22', level: 'action', source: t('router.users'), operator: '寮犺繍缁?, message: '鏂板杩愮淮宸ョ▼甯堣处鍙枫€屾潕宸ャ€嶏紝瑙掕壊锛氳繍缁村伐绋嬪笀' },
L30: { id: 4, time: '2026-08-10 12:40:05', level: 'warning', source: t('systemSetting.deviceAccess'), operator: '绯荤粺', message: 'DRONE-001 蹇冭烦瓒呮椂锛?60s锛夛紝宸茶嚜鍔ㄧ疆涓虹绾? },
L31: { id: 5, time: '2026-08-10 12:33:18', level: 'error', source: '鍛戒护鏈嶅姟', operator: '绯荤粺', message: 'ROBOT-002 鎵ц銆岃嚜涓诲贰妫€銆嶈秴鏃讹紝宸茶嚜鍔ㄩ噸璇?1 娆″悗浠嶅け璐? },
L32: { id: 6, time: '2026-08-10 12:20:09', level: 'action', source: t('router.systemSetting'), operator: '寮犺繍缁?, message: '淇敼绯荤粺鍚嶇О涓庢暟鎹埛鏂伴鐜囷紙5min 鈫?1min锛? },
L33: { id: 7, time: '2026-08-10 11:55:44', level: 'info', source: '鐘舵€佹湇鍔?, operator: '绯荤粺', message: '璁惧 ROBOT-001 涓婃姤鐘舵€侊細鐢甸噺 85%锛屾ā寮?patrol' },
L34: { id: 8, time: '2026-08-10 11:30:02', level: 'warning', source: t('router.alerts'), operator: '绯荤粺', message: '閫嗗彉鍣?INV-03 杈撳嚭鍔熺巼杈冩槰鏃ヤ笅闄?16%锛岃Е鍙戦璀? },
L35: { id: 9, time: '2026-08-10 10:48:37', level: 'action', source: t('router.videoManage'), operator: '鐜嬬彮闀?, message: '璋冩暣 CAM-04 鐑垚鍍忛€氶亾鐮佺巼鍙傛暟' },
L36: { id: 10, time: '2026-08-10 10:12:15', level: 'info', source: '绯荤粺', operator: '绯荤粺', message: '姣忔棩鑷姩澶囦唤瀹屾垚锛屽浠芥枃浠讹細backup-20260810-0200.tar' },
L37: { id: 11, time: '2026-08-10 09:40:50', level: 'error', source: t('systemSetting.deviceAccess'), operator: '绯荤粺', message: '鏈煡璁惧灏濊瘯娉ㄥ唽锛坰ecret 鏍¢獙澶辫触锛夛紝宸叉嫆缁濓紝鏉ユ簮 IP锛?0.0.12.45' },
L38: { id: 12, time: '2026-08-10 09:05:23', level: 'action', source: t('router.roles'), operator: '寮犺繍缁?, message: '涓恒€屾暟鎹垎鏋愬笀銆嶈鑹叉巿鏉冦€屾姤琛ㄤ腑蹇?瀵煎嚭銆嶆潈闄? },
L63: message.success('鏃ュ織宸插埛鏂?);
L74: const header = '鏃堕棿,绾у埆,鏉ユ簮,鎿嶄綔浜?娑堟伅\n';
L80: a.download = `绯荤粺鏃ュ織_${dayjs().format('YYYYMMDD_HHmmss')}.csv`;
L83: message.success(`宸插鍑?${filtered.length} 鏉℃棩蹇梎);
L89: title: '绾у埆', dataIndex: 'level', key: 'level', width: 80,
L97: { title: '娑堟伅', dataIndex: 'message', key: 'message', ellipsis: true },
L104: <Text type="secondary" style={{ fontSize: 12 }}>绯荤粺杩愯銆佽澶囨帶鍒朵笌绠$悊鍛樻搷浣滄祦姘达紝浠呰秴绾х鐞嗗憳鍙煡鐪?/Text>
L115: { value: 'all', label: '鍏ㄩ儴绾у埆' },
L125: size="small" allowClear placeholder="鎼滅储娑堟伅 / 鎿嶄綔浜?/ 鏉ユ簮"
L152: pagination={{ size: 'small', pageSize: 10, showTotal: (t) => `鍏?${t} 鏉 }}
 
### src\components\SystemSetting\MenuList.tsx (13)
L70: messageApi.error('鑿滃崟鍔犺浇澶辫触');
L171: 鏂板瀛愯彍鍗? L201: }}>鏂板鑿滃崟</Button>
L208: pagination={false} // 鍏抽棴鍒嗛〉
L215: {/* 鑿滃崟寮圭獥 */}
L217: title={editMenu ? '缂栬緫鑿滃崟' : '鏂板鑿滃崟'}
L226: <Select placeholder="鏃狅紙涓€绾ц彍鍗曪級">
L227: <Option value={0}>鏃狅紙涓€绾ц彍鍗曪級</Option>
L235: <Input placeholder="璇疯緭鍏ヨ彍鍗曞悕绉? />
L244: <Form.Item label="鏄剧ず鎺掑簭" name="orderNum">
L245: <InputNumber min={0} style={{ width: '100%' }} placeholder="鏁板瓧瓒婂皬瓒婇潬鍓? />
L250: {/* 鍥炬爣閫夋嫨寮圭獥 */}
L252: title="閫夋嫨鑿滃崟鍥炬爣"
 
### src\components\SystemSetting\OnlineUser.tsx (33)
L18: dept: '鐮斿彂閮ㄩ棬',
L20: location: '鍐呯綉IP',
L29: dept: '鐮斿彂閮ㄩ棬',
L31: location: '鍐呯綉IP',
L40: const [activeTab, setActiveTab] = useState('onlineUser'); // 榛樿閫変腑鍦ㄧ嚎鐢ㄦ埛
L54: message.success('鎼滅储瀹屾垚');
L62: message.info('宸查噸缃悳绱㈡潯浠?);
L67: message.info(`宸插悜浼氳瘽 ${record.sessionId} 鍙戦€佸己閫€鎸囦护`);
L72: { title: '搴忓彿', dataIndex: 'id', width: 60 },
L73: { title: '浼氳瘽缂栧彿', dataIndex: 'sessionId', ellipsis: true },
L74: { title: '鐧诲綍鍚嶇О', dataIndex: 'loginName' },
L75: { title: '鎵€灞為儴闂?, dataIndex: 'dept' },
L76: { title: '涓绘満', dataIndex: 'host' },
L77: { title: '鐧诲綍鍦扮偣', dataIndex: 'location' },
L78: { title: '鎿嶄綔绯荤粺', dataIndex: 'os' },
L79: { title: '娴忚鍣?, dataIndex: 'browser' },
L80: { title: '鐧诲綍鏃堕棿', dataIndex: 'loginTime' },
L85: 寮洪€€
L94: <Typography.Title level={4} style={{ margin: 0, fontSize: 'clamp(14px, 1.2vw, 18px)' }}>绯荤粺鐩戞帶</Typography.Title>
L96: {/* ====================== 椤堕儴 Tabs ====================== */}
L103: <TabPane tab="鍏朵粬鐩戞帶" key="other" />
L106: {/* ====================== Tab 1锛氬湪绾跨敤鎴?====================== */}
L109: {/* 鎼滅储鏍?*/}
L112: <span>鐧诲綍鍦板潃</span>
L114: placeholder="璇疯緭鍏ョ櫥褰曞湴鍧€"
L123: placeholder="璇疯緭鍏ョ敤鎴峰悕绉?
L130: 鎼滅储
L133: 閲嶇疆
L137: {/* 鍦ㄧ嚎鐢ㄦ埛琛ㄦ牸 */}
L147: showTotal: (total) => `鍏?${total} 鏉,
L155: {/* ====================== Tab 2锛氬叾浠栭〉闈紙浣犲彲浠ラ殢渚挎敼鍐呭锛?====================== */}
L158: <h2>鍏朵粬鐩戞帶鍐呭</h2>
L159: <p>杩欓噷鍙互鏀炬湇鍔$姸鎬併€丆PU鐩戞帶銆佸唴瀛樼洃鎺с€佹帴鍙g洃鎺х瓑鍐呭</p>
 
### src\components\SystemSetting\Organization.tsx (17)
L144: <Popconfirm title="纭畾鍒犻櫎璇ョ粍缁囷紵" onConfirm={() => handleDelete(r.id)}>
L162: 鏂板缁勭粐
L166: {/* 琛ㄦ牸 + 缁熶竴鍒嗛〉 */}
L176: showTotal: (total) => `鍏?${total} 鏉
L185: title={editRecord ? '缂栬緫缁勭粐' : '鏂板缁勭粐'}
L194: <Input placeholder="璇疯緭鍏ョ粍缁囧悕绉? />
L197: {/*<Form.Item name="orgCode" label="缁勭粐缂栫爜" rules={[{ required: true }]}>
L198: <Input placeholder="璇疯緭鍏ョ粍缁囩紪鐮? />
L201: <Form.Item name="manager" label={t('systemSetting.leader')} rules={[{ required: true, message: '璇疯緭鍏ヨ礋璐d汉' }]}>
L202: <Input placeholder="璇疯緭鍏ヨ礋璐d汉" />
L205: <Form.Item name="phone" label={t('systemSetting.contact')} rules={[{ required: true, message: '璇疯緭鍏ヨ仈绯荤數璇? }]}>
L206: <Input placeholder="璇疯緭鍏ヨ仈绯荤數璇? />
L210: <Input placeholder="璇疯緭鍏ラ偖绠? />
L213: <Form.Item name="address" label="鍦板潃">
L214: <Input placeholder="璇疯緭鍏ュ湴鍧€" />
L218: <Input.TextArea rows={3} placeholder="璇疯緭鍏ュ娉? />
L224: <Option value={0}>绂佺敤</Option>
 
### src\components\SystemSetting\SerialNumGenerate.jsx (45)
L150: message.warning('璇烽€夋嫨瑕佸垹闄ょ殑鏁版嵁');
L155: messageApi.success('鎵归噺鍒犻櫎鎴愬姛');
L158: messageApi.error('鎵归噺鍒犻櫎澶辫触');
L235: if (!qrUrl) return messageApi.warning('璇峰厛鐢熸垚');
L244: if (!serialNumber) return messageApi.warning('璇峰厛鐢熸垚');
L271: messageApi.error('淇濆瓨澶辫触锛? + res?.msg);
L296: messageApi.warning('鏈煡璇㈠埌鏁版嵁');
L299: messageApi.error('鏌ヨ澶辫触');
L329: title: '搴忓彿',
L334: { title: '搴忓垪鍙?, width: 380, dataIndex: 'serialNumber', key: 'sn', ellipsis: true },
L336: title: '鍨嬪彿',
L345: title: '閰嶇疆',
L363: title: '鍥藉',
L368: title: '鐪佷唤',
L373: title: '浜岀淮鐮?,
L391: 鍒犻櫎
L411: title="鏈哄櫒浜轰簩缁寸爜绠$悊"
L415: <Button onClick={() => setManageVisible(true)}>鏁版嵁绠$悊</Button>
L416: <Popconfirm title="纭畾鍒犻櫎閫変腑椤癸紵" onConfirm={handleBatchDelete}>
L423: {/* 绛涢€夋爮 */}
L425: <Form.Item name="serialNumber" label="搴忓垪鍙?>
L426: <Input placeholder="璇疯緭鍏ュ簭鍒楀彿" allowClear style={{ width: '100%', minWidth: 260, maxWidth: 420 }} />
L436: {/* 鍒楄〃 鈥斺€?瀹屽叏鑷€傚簲 + 鍙充晶鍥哄畾 + 涓嶆孩鍑?*/}
L451: {/* 鏂板寮圭獥 */}
L453: title="鐢熸垚鏈哄櫒浜轰簩缁寸爜"
L469: <Form.Item name="model" label="鍨嬪彿" rules={[{ required: true }]}>
L470: <Select placeholder="閫夋嫨鍨嬪彿" showSearch>
L474: <Form.Item name="config" label="閰嶇疆" rules={[{ required: true }]}>
L475: <Select placeholder="閫夋嫨閰嶇疆" showSearch>
L480: <Select placeholder="閫夋嫨绫诲瀷" showSearch>
L484: <Form.Item name="country" label="鍥藉">
L485: <Select placeholder="閫夋嫨鍥藉" showSearch allowClear onChange={handleCountryChange}>
L489: <Form.Item name="province" label="鐪佷唤">
L490: <Select placeholder="璇峰厛閫夋嫨鍥藉" showSearch allowClear disabled={provinces.length === 0}>
L495: <Button type="primary" onClick={generateQRCode} block>鐢熸垚搴忓垪鍙?& 浜岀淮鐮?/Button>
L504: <Text strong>搴忓垪鍙凤細{serialNumber}</Text>
L510: <div style={{ color: '#999', padding: '60px 0' }}>璇峰厛鐢熸垚浜岀淮鐮?/div>
L521: {/* 鏌ョ湅浜岀淮鐮?*/}
L522: <Modal open={viewModal} title="浜岀淮鐮佽鎯? onCancel={() => setViewModal(false)} footer={null} width={400}>
L526: <div style={{ marginTop: 16 }}>搴忓垪鍙凤細{viewRecord.serialNumber}</div>
L531: {/* 鏁版嵁绠$悊 */}
L532: <Modal open={manageVisible} title="鏁版嵁绠$悊" width="90%" style={{ maxWidth: 900 }} onCancel={() => setManageVisible(false)} footer={<Button onClick={() => setManageVisible(false)}>{t('common.close')}</But
L533: <DictManager title="鏈哄櫒浜虹被鍨? data={types} fields={[{ name: 'displayName', label: '绫诲瀷鍚嶇О', required: true }, { name: 'storeValue', label: '瀛樺偍鍊?, required: true }, { name: 'remark', label: t('roles.remark'
L534: <DictManager title="鏈哄櫒浜哄瀷鍙? data={models} fields={[{ name: 'displayName', label: '鍨嬪彿鍚嶇О', required: true }, { name: 'storeValue', label: '瀛樺偍鍊?, required: true }]} onAdd={handleAddModel} onUpdate={handle
L535: <DictManager title="閰嶇疆" data={configs} fields={[{ name: 'displayName', label: '閰嶇疆鍚嶇О', required: true }, { name: 'storeValue', label: '瀛樺偍鍊?, required: true }]} onAdd={handleAddConfig} onUpdate={handleU
 
### src\components\SystemSetting\SmartDeviceManagement.tsx (63)
L105: utils.message.error('鑾峰彇鏅鸿兘瑁呭鍒楄〃澶辫触');
L119: console.error('鑾峰彇缁勭粐鍒楄〃澶辫触', err);
L175: utils.message.success('瑁呭缂栬緫鎴愬姛');
L200: utils.message.error('鏃犳潈闄?);
L214: utils.message.success('淇濆瓨鍙傛暟鎴愬姛');
L217: utils.message.error(res.msg || '鎺堟潈澶辫触');
L220: utils.message.error('鎿嶄綔寮傚父');
L226: return utils.message.warning('璇峰厛鍦ㄥ垪琛ㄤ腑閫変腑闇€瑕佺粦瀹氱殑鏅鸿兘瑁呭');
L274: utils.message.success('缁戝畾鎴愬姛');
L280: utils.message.error('缁戝畾澶辫触');
L283: utils.message.error('鎿嶄綔寮傚父');
L290: return utils.message.warning('鏈€夋嫨鏈夋晥璁惧锛屾棤娉曡В缁?);
L292: const typeText = { 1: '浜哄憳', 2: '鍦虹珯', 3: '缁勭粐' }[type as number];
L294: title: '纭瑙g粦',
L295: content: `纭畾瑕佷负閫変腑鐨勬櫤鑳借澶囨竻闄?{typeText}缁戝畾鍚楋紵`,
L302: utils.message.success('瑙g粦鎴愬姛');
L307: utils.message.error(res.msg || '瑙g粦澶辫触');
L310: utils.message.error('鎿嶄綔寮傚父');
L318: { title: '璁惧鐮?, width: 280, dataIndex: 'serialNumber', key: 'sn' },
L320: title: '鎵€灞炵粍缁?, width: 150, key: 'orgName',
L323: return org ? (org.orgName || org.name) : <Text type="secondary">鏈粦瀹?/Text>;
L327: title: '鎵€灞炲満绔?, width: 150, key: 'siteName',
L330: return site ? (site.siteName || site.name) : <Text type="secondary">鏈粦瀹?/Text>;
L337: return user ? (user.nickName || user.userName) : <Text type="secondary">鏈粦瀹?/Text>;
L345: <Tooltip title="娓呴櫎浜哄憳缁戝畾">
L346: <Button size="small" icon={<DisconnectOutlined />} onClick={() => handleUnbindSmart([record.serialNumber], 1)}>鐢ㄦ埛</Button>
L348: <Tooltip title="娓呴櫎鍦虹珯缁戝畾">
L349: <Button size="small" icon={<DisconnectOutlined />} onClick={() => handleUnbindSmart([record.serialNumber], 2)}>鍦虹珯</Button>
L351: <Tooltip title="娓呴櫎缁勭粐缁戝畾">
L352: <Button size="small" icon={<DisconnectOutlined />} onClick={() => handleUnbindSmart([record.serialNumber], 3)}>缁勭粐</Button>
L354: <Button size="small" icon={<EditOutlined />} onClick={() => openParamModal(record)}>鍙傛暟</Button>
L355: {userInfo?.userId == 1 && <Button size="small" icon={<EditOutlined />} onClick={() => openParamModal1(record)}>鎺堟潈</Button>}
L381: placeholder="璁惧鐮?
L388: <Button type="primary" icon={<LinkOutlined />} onClick={openBindSmartModal}>缁戝畾瑁呭</Button>
L389: <Button disabled={selectedSmartKeys.length === 0} onClick={() => handleUnbindSmart(selectedSmartKeys, 1)}>鎵归噺瑙g粦(鐢ㄦ埛)</Button>
L390: <Button disabled={selectedSmartKeys.length === 0} onClick={() => handleUnbindSmart(selectedSmartKeys, 2)}>鎵归噺瑙g粦(鍦虹珯)</Button>
L391: <Button disabled={selectedSmartKeys.length === 0} onClick={() => handleUnbindSmart(selectedSmartKeys, 3)}>鎵归噺瑙g粦(缁勭粐)</Button>
L407: showTotal: (t) => `鍏?${t} 鏉,
L420: <span style={{ fontWeight: 600 }}>缁戝畾鏅鸿兘瑁呭</span>
L436: <Form.Item label={<>宸查€夋櫤鑳借澶囷紙{selectedSmartKeys.length}鍙帮級ID</>} name="deviceIds" rules={[{ required: true, message: '璇烽€夋嫨瑁呭' }]}>
L437: <Input.TextArea placeholder="渚嬪: ID001, ID002" rows={2} disabled style={{ resize: 'none', background: '#fafafa' }} />
L442: <span>鎵€灞炵粍缁?/span>
L445: name="orgId" rules={[{ required: true, message: '璇烽€夋嫨缁勭粐' }]}
L448: placeholder="璇烽€夋嫨缁勭粐"
L466: <span>鎵€灞炲満绔?/span>
L469: name="siteId" rules={[{ required: !siteFieldDisabled, message: '璇烽€夋嫨鍦虹珯' }]}
L472: placeholder="璇峰厛閫夋嫨缁勭粐"
L487: <Form.Item label={t('systemSetting.leader')} name="userId" rules={[{ required: true, message: '璇烽€夋嫨璐熻矗浜? }]}>
L489: placeholder="璇峰厛閫夋嫨鍦虹珯鍚庨€夋嫨璐熻矗浜?
L506: title="缂栬緫鏅鸿兘瑁呭淇℃伅"
L517: <Form.Item label={t('devices.deviceName')} name="deviceAlias" rules={[{ required: true, message: '璇峰~鍐欒澶囧悕绉? }]}>
L518: <Input placeholder="璇疯緭鍏ヨ澶囧悕绉? />
L520: <Form.Item label="璁惧搴忓垪鍙? name="serialNumber" rules={[{ required: true, message: '璇峰~鍐欒澶囩爜' }]}>
L521: <Input placeholder="璇疯緭鍏ヨ澶囧簭鍒楀彿" />
L523: <Form.Item label={t('devices.onlineStatus')} name="onlineStatus" rules={[{ required: true, message: '璇烽€夋嫨鍦ㄧ嚎鐘舵€? }]}>
L524: <Select placeholder="閫夋嫨鍦ㄧ嚎鐘舵€?>
L542: <span style={{ fontWeight: 600 }}>璁惧鎺堟潈</span>
L572: <span>璁剧疆璁惧鎿嶄綔鎺堟潈锛屾巿鏉冨埌鏈熷悗璁惧灏嗗け鍘诲搴旀搷浣滄潈闄?/span>
L576: label={<span style={{ fontWeight: 500 }}>鎺堟潈鏃堕棿(min)</span>}
L579: { required: true, message: '璇疯緭鍏ユ巿鏉冨墿浣欐椂闂? },
L580: { type: 'number', min: 0, message: '鎺堟潈鏃堕棿涓嶈兘灏忎簬0' }
L586: placeholder="璇疯緭鍏ユ巿鏉冨墿浣欐椂闂?
L592: <Button type="primary" htmlType="submit" style={{ borderRadius: 8, padding: '4px 24px' }}>淇濆瓨鎺堟潈</Button>
 
### src\components\SystemSetting\StationManage.tsx (43)
L250: title: '鎵€灞炵粍缁?,
L257: { title: '鍦板潃', dataIndex: 'address' },
L264: <Button icon={<BgColorsOutlined />} onClick={() => handleOpenArea(record)}>鍒嗗尯璁剧疆</Button>
L265: <Button onClick={() => handleOpenMap(record)}>杈圭晫缁樺埗</Button>
L286: placeholder="璇烽€夋嫨缁勭粐绛涢€?
L300: 鏂板鍦虹珯
L314: showTotal: (total) => `鍏?${total} 鏉
L322: {/* 鍦虹珯寮圭獥 */}
L324: title={editRecord ? '缂栬緫鍦虹珯' : '鏂板鍦虹珯'}
L339: <Form.Item name="orgId" label="鎵€灞炵粍缁? rules={[{ required: true }]}>
L340: <Select placeholder="璇烽€夋嫨鎵€灞炵粍缁? allowClear>
L364: <Form.Item name="address" label="璇︾粏鍦板潃">
L365: <Input placeholder="鍦板潃" />
L368: <Divider orientation="left">娑堟伅鎺ㄩ€侀厤缃?/Divider>
L372: <Form.Item name="dingTalkPush" label="閽夐拤鍛婅鎺ㄩ€? valuePropName="checked">
L373: <Switch checkedChildren="寮€鍚? unCheckedChildren={t('common.close')} />
L377: <Form.Item name="dingTalkOrderPush" label="閽夐拤宸ュ崟鎺ㄩ€? valuePropName="checked">
L378: <Switch checkedChildren="寮€鍚? unCheckedChildren={t('common.close')} />
L382: <Form.Item name="emailPush" label="閭欢鎺ㄩ€? valuePropName="checked">
L383: <Switch checkedChildren="寮€鍚? unCheckedChildren={t('common.close')} />
L387: <Form.Item name="alertPush" label="鍛婅寮圭獥鎺ㄩ€? valuePropName="checked">
L388: <Switch checkedChildren="寮€鍚? unCheckedChildren={t('common.close')} />
L393: {/* 閽夐拤寮€鍏冲紑鍚墠鏄剧ずToken銆佸瘑閽?*/}
L399: label="閽夐拤鏈哄櫒浜篢oken"
L401: { required: true, message: '寮€鍚拤閽夋帹閫佹椂蹇呴』濉啓Token' }
L404: <Input placeholder="璇疯緭鍏ラ拤閽夋満鍣ㄤ汉Webhook Token" />
L410: label="閽夐拤鍔犲瘑瀵嗛挜"
L412: { required: true, message: '寮€鍚拤閽夋帹閫佹椂蹇呴』濉啓鍔犲瘑瀵嗛挜' }
L415: <Input placeholder="閽夐拤鏈哄櫒浜哄姞绛惧瘑閽? />
L431: {/* 鍒嗗尯寮圭獥 */}
L433: title={`銆?{currentStation?.siteName}銆戝垎鍖鸿缃甡}
L442: <Form.Item name="regionName" label="鍒嗗尯鍚嶇О" rules={[{ required: true }]}>
L447: <Form.Item name="regionCode" label="鍒嗗尯缂栫爜" rules={[{ required: true }]}>
L454: <Form.Item name="type" label="鍒嗗尯绫诲瀷">
L455: <Select><Option value="娓呮壂鍖?>娓呮壂鍖?/Option><Option value="宸℃鍖?>宸℃鍖?/Option></Select>
L465: <Button type="primary" onClick={handleSaveRegion}>淇濆瓨鍒嗗尯</Button>
L474: { title: '鍒嗗尯鍚嶇О', dataIndex: 'regionName' },
L475: { title: '缂栫爜', dataIndex: 'regionCode' },
L493: {/* 鍦板浘缁樺埗寮圭獥 */}
L495: title={`銆?{currentStation?.siteName}銆戣竟鐣岀粯鍒禶}
L502: 鍦板浘鍖哄煙缁樺埗锛堝彲鑷鎺ュ叆楂樺痉/鐧惧害鍦板浘锛? L504: <Button type="primary">寮€濮嬬粯鍒?/Button>
L505: <Button>淇濆瓨杈圭晫</Button>
 
### src\components\SystemSetting\SystemMaintain.tsx (3)
L38: <TabPane tab={<span><ExclamationCircleOutlined />閿欒绠$悊</span>} key="error" />
L39: <TabPane tab={<span><AlertOutlined />鍛婅妯″瀷绠$悊</span>} key="alarm" />
L40: <TabPane tab={<span><FormOutlined />宸ュ崟妯″瀷绠$悊</span>} key="workOrder" />
 
### src\components\SystemSetting\UserPage.tsx (7)
L408: {/* 鐢ㄦ埛绠$悊 */}
L495: {/* 瑙掕壊绠$悊 */}
L537: {/*{r.roleKey == "admin1" && <Tag color="red">瓒呯骇绠$悊鍛?/Tag>}*/}
L552: showTotal={(t) => `鍏?${t} 鏉}
L567: {/* 瑙掕壊寮圭獥 */}
L617: {/* 鐢ㄦ埛寮圭獥 */}
L651: {/* ====== 鑷姩閫傚簲甯冨眬锛氶殣钘忚鑹叉椂锛岀姸鎬佽嚜鍔ㄥ崰婊′竴琛?====== */}
 
### src\components\SystemSetting\VideoManagement.tsx (20)
L72: message.warning(data.error || '璇诲彇閫氶亾澶辫触');
L76: message.error('鏃犳硶杩炴帴瑙嗛鏈嶅姟');
L138: if (data.code !== 200) message.warning(data.error || '璇诲彇鏂囦欢澶辫触');
L139: } catch { setFiles([]); message.error('璇诲彇鏂囦欢澶辫触'); }
L147: message.warning('璇峰厛閫夋嫨瀹屾暣鐨勬椂闂磋矾寰?);
L158: { title: '澶у皬', dataIndex: 'sizeFormatted', key: 'sizeFormatted', width: 120 },
L186: 褰曞儚閫氶亾涓庡洖鏀剧鐞?路 鍏?{channels.length} 涓€氶亾
L193: <Text style={{ fontSize: 12, color: '#666' }}>閫氶亾</Text>
L195: size="small" style={{ width: '100%' }} placeholder="閫夋嫨璁惧閫氶亾"
L203: <Text style={{ fontSize: 12, color: '#666' }}>骞?/Text>
L205: size="small" style={{ width: '100%' }} placeholder="骞?
L211: <Text style={{ fontSize: 12, color: '#666' }}>鏈?/Text>
L213: size="small" style={{ width: '100%' }} placeholder="鏈?
L219: <Text style={{ fontSize: 12, color: '#666' }}>鏃?/Text>
L221: size="small" style={{ width: '100%' }} placeholder="鏃?
L234: <Empty description="璇峰厛閫夋嫨瑙嗛閫氶亾" style={{ padding: 40 }} />
L236: <Empty description="璇烽€夋嫨 骞?/ 鏈?/ 鏃?鍔犺浇褰曞儚" image={Empty.PRESENTED_IMAGE_SIMPLE} style={{ padding: 40 }} />
L238: <Empty description="璇ユ棩鏆傛棤褰曞儚鏂囦欢" style={{ padding: 40 }} />
L242: pagination={{ size: 'small', pageSize: 10, showTotal: (t) => `鍏?${t} 涓枃浠禶 }}
L249: title={`棰勮: ${preview?.fileName || ''}`}
 
### src\components\SystemSetting\WorkOrderSettingsManagement.tsx (34)
L110: console.error('鑾峰彇璁惧鍒楄〃澶辫触', e);
L128: console.error('鑾峰彇棰勮璺緞澶辫触', e);
L146: console.error('鑾峰彇鏃犱汉鏈鸿埅绾垮け璐?, e);
L164: utils.message.error('鑾峰彇宸ュ崟妯″瀷鍒楄〃澶辫触');
L214: title: '纭鍒犻櫎',
L215: content: '鎮ㄧ‘瀹氳鍒犻櫎杩欐潯宸ュ崟妯″瀷鍚楋紵',
L235: message.warning('璇峰厛鍕鹃€夎鍒犻櫎鐨勬暟鎹?);
L239: title: '鎵归噺鍒犻櫎纭',
L240: content: `鎮ㄧ‘瀹氳鍒犻櫎閫変腑鐨?${selectedRowKeys.length} 鏉″伐鍗曟ā鍨嬪悧锛熷垹闄ゅ悗涓嶅彲鎭㈠锛乣,
L248: message.success('鎵归噺鍒犻櫎鎴愬姛');
L252: message.error('鎵归噺鍒犻櫎澶辫触');
L277: message.success(editingItem ? '鏇存柊鎴愬姛' : t('common.addSuccess'));
L301: { title: '宸ュ崟鍚嶇О', dataIndex: 'orderName', key: 'orderName' },
L309: title: '閿欒绛夌骇',
L314: const text = { 1: '杞诲井', 2: t('constants.general'), 3: t('constants.critical') }[val] || val;
L319: title: '璁惧',
L329: title: '璺緞/鑸嚎',
L342: title: '鑷姩鐢熸垚浠诲姟',
L345: render: (val: boolean) => val ? '鏄? : '鍚?
L369: <Button type="primary" icon={<PlusOutlined />} onClick={handleAdd}>鏂板宸ュ崟妯″瀷</Button>
L377: 鎵归噺鍒犻櫎{selectedRowKeys.length ? `(${selectedRowKeys.length})` : ''}
L391: title={editingItem ? '缂栬緫宸ュ崟妯″瀷' : '鏂板宸ュ崟妯″瀷'}
L398: <Form.Item label="宸ュ崟鍚嶇О" name="orderName" rules={[{ required: true, message: '璇疯緭鍏ュ伐鍗曞悕绉? }]}>
L399: <Input placeholder="璇疯緭鍏ュ伐鍗曞悕绉? />
L404: <Form.Item label="閿欒绛夌骇" name="errorLevel" rules={[{ required: true, message: '璇烽€夋嫨閿欒绛夌骇' }]}>
L405: <Select placeholder="璇烽€夋嫨閿欒绛夌骇" options={errorLevelOptions} />
L407: <Form.Item label="璁惧" name="deviceId" rules={[{ required: true, message: '璇烽€夋嫨璁惧' }]}>
L409: placeholder="璇烽€夋嫨璁惧"
L416: {/* 鏍规嵁璁惧绫诲瀷鏄剧ず涓嶅悓鐨勮矾寰勯€夋嫨 */}
L418: <Form.Item label="棰勮璺緞" name="routeId" rules={[{ required: true, message: '璇烽€夋嫨棰勮璺緞' }]}>
L419: <Select placeholder="璇烽€夋嫨棰勮璺緞" options={routeOptions} />
L424: <Form.Item label="鏃犱汉鏈鸿埅绾? name="waylineId" rules={[{ required: true, message: '璇烽€夋嫨鏃犱汉鏈鸿埅绾? }]}>
L425: <Select placeholder="璇烽€夋嫨鏃犱汉鏈鸿埅绾? options={waylineOptions} />
L429: {/*<Form.Item label="鑷姩鐢熸垚浠诲姟" name="autoGenerateTask" valuePropName="checked">
 
### src\components\useWebRTCStream.tsx (3)
L67: console.error('鎾斁閿欒', deviceId, url, err);
L74: console.error('鍒濆鍖栧け璐?, e);
L81: }, [deviceId, url]); // 馃敟 蹇呴』鍔?url
 
### src\components\VideoCanvas.tsx (4)
L42: if (title.includes('鍓?) || title.includes('front')) {
L60: if (title.includes('鍚?) || title.includes('back')) {
L76: if (title.includes('宸?) || title.includes('left')) {
L86: if (title.includes('鍙?) || title.includes('right')) {
 
### src\components\VideoPlayer.tsx (2)
L28: const viewTitles = ['鍓嶈鍥?, '鍚庤鍥?, '宸﹁鍥?, '鍙宠鍥?];
L32: return <Empty description="瑙嗛婧愯繛鎺ュけ璐? />;
 
### src\components\VolcRtcPlayer.jsx (1)
L47: console.error("RTC 鍙傛暟缂哄け");
 
### src\components\Weather\WeatherSunny.jsx (1)
L5: const angle = i * 30; // 姣忔牴 30掳
 
### src\components\WebSocketManager.ts (4)
L64: console.log("鍒涘缓寮€濮?);//ws://192.168.2.56:9002/ws/
L90: console.log("serialNumber 鏄┖/绌虹櫧锛屽仠姝㈡墽琛?);
L104: console.error('鐢ㄦ埛淇℃伅鏈壘鍒帮紝鏃犳硶鍙戦€佽璇佸寘');
L112: console.log("寮€濮嬪彂閫佽璇佸寘");//ws://192.168.2.56:9002/ws/
 
### src\hooks\useMqtt.ts (1)
L46: /* 浣跨敤 */
 
### src\lib\TracePoint\circQueue.js (44)
L40: this.capacity = capacity; /* 闃熷垪瀹归噺 (鏈€澶氬瓨鍌ㄩ」鐩暟) */
L41: this.buffer = new Array(capacity); /* 闃熷垪瀛樺偍鍖猴紝浣跨敤鏁扮粍瀛樹换鎰忓璞?*/
L42: this.head = 0; /* 闃熷ご绱㈠紩 */
L43: this.tail = 0; /* 闃熷熬绱㈠紩 */
L44: this.isFull = false; /* 闃熸弧鏍囧織 */
L46: this.deepCopy = options.deepCopy ?? true; /* 鏄惁鍚敤娣辨嫹璐?(榛樿鍚敤) */
L47: this.maxMemoryBytes = options.maxMemoryBytes ?? Infinity; /* 闃熷垪鏈€澶у唴瀛橀檺鍒?(鍗曚綅锛氬瓧鑺? */
L48: this.currentMemoryBytes = 0; /* 褰撳墠宸蹭娇鐢ㄥ唴瀛樺ぇ灏?(鍗曚綅锛氬瓧鑺? */
L51: /* 鍒ゆ柇闃熷垪鏄惁涓虹┖ */
L57: /* 鍒ゆ柇闃熷垪鏄惁宸叉弧 */
L63: /* 浼扮畻瀵硅薄澶у皬 (浠?JSON 瀛楃涓茬殑 UTF-8 缂栫爜闀垮害浣滀负杩戜技鍊? */
L68: return Buffer.byteLength(JSON.stringify(obj), 'utf8'); /* Node.js 涓敤浜庤绠楀瓧鑺傞暱搴?*/
L72: return 0; /* 鑻ュ璞′笉鍙簭鍒楀寲锛岃繑鍥?0 (閬垮厤鍑洪敊) */
L76: /* 娣辨嫹璐濆璞?(鍩轰簬 JSON 鐨勬柟寮忥紝浠呮敮鎸佸彲搴忓垪鍖栧璞? */
L82: /* 鍏ラ槦鎿嶄綔锛氬皢瀵硅薄鏀惧叆闃熷熬 */
L85: const itemSize = this._estimateSize(item); /* 浼扮畻椤圭洰鍐呭瓨澶у皬 */
L88: return false; /* 鑻ラ槦婊℃垨瓒呰繃鍐呭瓨闄愬埗鍒欏叆闃熷け璐?*/
L91: const clone = this._deepClone(item); /* 娣辨嫹璐濆叆闃熸暟鎹?(閬垮厤澶栭儴淇敼褰卞搷闃熷垪) */
L92: this.buffer[this.tail] = clone; /* 瀛樺叆闃熷熬 */
L93: this.tail = (this.tail + 1) % this.capacity; /* 鐜舰澧為暱 tail */
L94: this.currentMemoryBytes += itemSize; /* 澧炲姞褰撳墠鍐呭瓨浣跨敤 */
L96: if (this.tail === this.head) this.isFull = true; /* 鑻ュ熬杩藉ご锛岃〃绀洪槦婊?*/
L100: /* 鍑洪槦鎿嶄綔锛氫粠闃熷ご鍙栧嚭涓€涓璞? 杩斿洖娣辨嫹璐?*/
L103: if (this.isEmpty()) return null; /* 闃熺┖杩斿洖 null */
L105: const item = this.buffer[this.head]; /* 璇诲彇闃熷ご椤圭洰 */
L106: this.currentMemoryBytes -= this._estimateSize(item); /* 鏇存柊鍐呭瓨浣跨敤 */
L107: this.head = (this.head + 1) % this.capacity; /* 鐜舰澧為暱 head */
L108: this.isFull = false; /* 鍑洪槦蹇呯劧闃熶笉婊?*/
L109: return this._deepClone(item); /* 杩斿洖娣辨嫹璐濓紝淇濇姢闃熷垪鍐呴儴鏁版嵁 */
L112: /* 涓㈠純鏁版嵁锛氫粠闃熷熬鍚戝墠涓㈠純 len 椤?(鍙嶅悜绉诲姩 tail) */
L117: if (this.isEmpty()) return false; /* 闃熺┖鍒欎笉鑳界户缁涪寮?*/
L119: /* 瀹氫綅鏈€鍚庝竴椤?*/
L121: this.currentMemoryBytes -= this._estimateSize(item); /* 鍑忓幓鍐呭瓨澶у皬 */
L122: this.tail = (this.tail - 1 + this.capacity) % this.capacity; /* tail 鍥為€€ */
L128: /* 鑾峰彇褰撳墠闃熷垪涓厓绱犱釜鏁?*/
L145: /* 寰幆鐩村埌鎴愬姛鍏ラ槦鎴栬秴鏃?*/
L148: if (Date.now() - start >= timeoutMs) return false; /* 瓒呮椂閫€鍑?*/
L149: await new Promise(resolve => setTimeout(resolve, 1)); /* 寮傛杞, 鑷棆鍔?sleep 鎸傝捣 1ms */
L166: if (item !== null) return item; /* 鎴愬姛鍙栧嚭鍒欒繑鍥?*/
L167: if (Date.now() - start >= timeoutMs) return null; /* 瓒呮椂閫€鍑?*/
L168: await new Promise(resolve => setTimeout(resolve, 1)); /* 寮傛杞, 鑷棆鍔?sleep 鎸傝捣 1ms */
L172: /* JSON 搴忓垪鍖栨帴鍙o紝鐢ㄤ簬 JSON.stringify(queue) */
L180: result.push(this._deepClone(this.buffer[i])); /* 澶嶅埗姣忎釜鍏冪礌 */
L181: i = (i + 1) % this.capacity; /* 绉诲姩鍒颁笅涓€涓厓绱?*/
 
### src\lib\TracePoint\tracePoint.js (91)
L7: /* Symbol 闃叉鍊奸噸澶?*/
L65: /* 鎴愬憳鍙橀噺(绉佹湁) */
L66: #queue; /* 寰幆闃熷垪, 鐢ㄤ簬瀛樻斁绛夊緟澶勭悊鐨勭偣 */
L67: #tracePoint; /* 杞ㄨ抗鐐规暟缁? 瀛樻斁宸插畬鎴愮偣 + 褰撳墠鐐?*/
L68: #completePointIndex; /* 瀹屾垚鐐圭储寮? 鎸囧悜褰撳墠鐐逛箣鍓嶇殑鏈€鍚庝竴涓鎻掑叆鐨勫畬鎴愮偣鐨勪綅缃?*/
L69: #lock; /* 閿? 鐢ㄤ簬闃叉澶氱嚎绋嬪悓鏃舵洿鏂?*/
L70: #mode; /* 妯″紡绠$悊鍣?*/
L85: /* 鏋勯€犲嚱鏁?*/
L89: maxMemoryBytes: 1024 * 1024, /* 1MB 闄愬埗 */
L93: this.#tracePoint = []; /* 瀛樻斁杞ㄨ抗, 宸插畬鎴愮偣 + 褰撳墠鐐?*/
L94: this.#completePointIndex = 0; /* 瀹屾垚鐐圭储寮?*/
L95: this.#lock = new TryLock(); /* 閿? 鐢ㄤ簬闃叉澶氱嚎绋嬪悓鏃舵洿鏂?*/
L96: this.#mode = TPMode.LOCATION; /* 榛樿涓哄畾浣嶆ā寮?*/
L99: /* 澶嶄綅 */
L101: /* 閲嶇疆杞ㄨ抗鐐?*/
L104: this.#queue.clear(); /* 娓呯┖闃熷垪 */
L105: this.#tracePoint = []; /* 娓呯┖杞ㄨ抗鐐规暟缁?*/
L106: this.#completePointIndex = 0; /* 閲嶇疆瀹屾垚鐐圭储寮?*/
L107: this.#mode = TPMode.LOCATION; /* 閲嶇疆涓哄畾浣嶆ā寮?*/
L108: this.#lock.release(); /* 閲婃斁閿?*/
L146: /* 鑾峰彇杞ㄨ抗 */
L148: /* 灏濊瘯閿佸畾, 闃叉澶氱嚎绋嬪悓鏃舵洿鏂?*/
L150: const trace = this.#tracePoint.slice(); /* 娣辨嫹璐? 閬垮厤澶栭儴淇敼瀵艰嚧鍐呴儴鍑洪敊 */
L151: this.#lock.release(); /* 瑙i攣 */
L156: return null; /* 閿佸畾涓? 杩斿洖绌?*/
L160: /* 鏇存柊褰撳墠鐐?*/
L167: /* 灏濊瘯閿佸畾, 闃叉澶氱嚎绋嬪悓鏃舵洿鏂?*/
L178: /* 鍙繚鐣欏畬鎴愮偣閮ㄥ垎, 鍐嶆彃鍏ユ柊鐨勫綋鍓嶇偣 */
L182: /* 瑙﹀彂浜嬩欢 newCurrentPoint, 椹卞姩澶栭儴鏇存柊 */
L187: this.#tracePoint[0] = point; /* JS 鏀寔鑷姩鎵╁睍鏁扮粍 */
L190: this.#lock.release(); /* 瑙i攣 */
L192: /* 濡傛灉杞ㄨ抗鏁扮粍姝e湪鎿嶄綔, 鍏堝瓨鏀捐嚦闃熷垪涓?*/
L199: /* 娣诲姞瀹屾垚鐐?*/
L206: /* 灏濊瘯閿佸畾, 闃叉澶氱嚎绋嬪悓鏃舵洿鏂?*/
L209: /* 鍏堝鐞嗛槦鍒椾腑绉帇鐨勭偣 */
L211: /* 濡傛灉闃熷垪涓嶄负绌? 鍙栧嚭闃熷垪涓殑鐐?*/
L216: /* 娣诲姞瀹屾垚鐐?*/
L219: /* 瑙﹀彂浜嬩欢 newCompletePoint, 椹卞姩澶栭儴鏇存柊 */
L223: /* 閿欒澶勭悊, js 鍙互杈撳嚭鍒?.err 鏂囦欢锛?*/
L225: /* 鎵撳嵃 */
L229: this.#lock.release(); /* 鏃犺鎴愬姛澶辫触閮借В閿? 閬垮厤鏃犳硶浣跨敤 */
L232: /* 濡傛灉杞ㄨ抗鏁扮粍姝e湪鎿嶄綔, 鍏堝瓨鏀捐嚦闃熷垪涓?*/
L246: /* 鑻ュ綋鍓嶇偣瀛樺湪锛岃鏄庡綋鍓嶆暟缁勬湯灏惧凡鎻掑叆涓€涓綋鍓嶇偣, 鎴柇杞ㄨ抗鏁扮粍鍒板綋鍓嶇偣锛屽皢鏂板畬鎴愮偣鎻掑叆鍦ㄥ綋鍓嶇偣涔嬪墠 */
L250: /* 鎴柇閬垮厤澶氭坊鍔犱簡鏃犳晥鐐? 鐒跺悗鍐嶅綋鍓嶇偣涔嬪墠鎻掑叆瀹屾垚鐐?*/
L254: /* 棣栨娣诲姞杞ㄨ抗鐐归渶瑕佸厛灏炬彃 */
L259: /* 鏇存柊褰撳墠鐐圭储寮?*/
L274: this.capacity = capacity; /* 闃熷垪瀹归噺 (鏈€澶氬瓨鍌ㄩ」鐩暟) */
L275: this.buffer = new Array(capacity); /* 闃熷垪瀛樺偍鍖猴紝浣跨敤鏁扮粍瀛樹换鎰忓璞?*/
L276: this.head = 0; /* 闃熷ご绱㈠紩 */
L277: this.tail = 0; /* 闃熷熬绱㈠紩 */
L278: this.isFull = false; /* 闃熸弧鏍囧織 */
L280: this.deepCopy = options.deepCopy ?? true; /* 鏄惁鍚敤娣辨嫹璐?(榛樿鍚敤) */
L281: this.maxMemoryBytes = options.maxMemoryBytes ?? Infinity; /* 闃熷垪鏈€澶у唴瀛橀檺鍒?(鍗曚綅锛氬瓧鑺? */
L282: this.currentMemoryBytes = 0; /* 褰撳墠宸蹭娇鐢ㄥ唴瀛樺ぇ灏?(鍗曚綅锛氬瓧鑺? */
L285: /* 娓呯┖闃熷垪 */
L291: /* 鍒ゆ柇闃熷垪鏄惁涓虹┖ */
L296: /* 鍒ゆ柇闃熷垪鏄惁宸叉弧 */
L301: /* 浼扮畻瀵硅薄澶у皬 (浠?JSON 瀛楃涓茬殑 UTF-8 缂栫爜闀垮害浣滀负杩戜技鍊? */
L307: return 0; /* 鑻ュ璞′笉鍙簭鍒楀寲锛岃繑鍥?0 (閬垮厤鍑洪敊) */
L311: /* 娣辨嫹璐濆璞?(鍩轰簬 JSON 鐨勬柟寮忥紝浠呮敮鎸佸彲搴忓垪鍖栧璞? */
L316: /* 鍏ラ槦鎿嶄綔锛氬皢瀵硅薄鏀惧叆闃熷熬 */
L318: const itemSize = this._estimateSize(item); /* 浼扮畻椤圭洰鍐呭瓨澶у皬 */
L320: return false; /* 鑻ラ槦婊℃垨瓒呰繃鍐呭瓨闄愬埗鍒欏叆闃熷け璐?*/
L323: const clone = this._deepClone(item); /* 娣辨嫹璐濆叆闃熸暟鎹?(閬垮厤澶栭儴淇敼褰卞搷闃熷垪) */
L324: this.buffer[this.tail] = clone; /* 瀛樺叆闃熷熬 */
L325: this.tail = (this.tail + 1) % this.capacity; /* 鐜舰澧為暱 tail */
L326: this.currentMemoryBytes += itemSize; /* 澧炲姞褰撳墠鍐呭瓨浣跨敤 */
L328: if (this.tail === this.head) this.isFull = true; /* 鑻ュ熬杩藉ご锛岃〃绀洪槦婊?*/
L332: /* 鍑洪槦鎿嶄綔锛氫粠闃熷ご鍙栧嚭涓€涓璞? 杩斿洖娣辨嫹璐?*/
L334: if (this.isEmpty()) return null; /* 闃熺┖杩斿洖 null */
L336: const item = this.buffer[this.head]; /* 璇诲彇闃熷ご椤圭洰 */
L337: this.currentMemoryBytes -= this._estimateSize(item); /* 鏇存柊鍐呭瓨浣跨敤 */
L338: this.head = (this.head + 1) % this.capacity; /* 鐜舰澧為暱 head */
L339: this.isFull = false; /* 鍑洪槦蹇呯劧闃熶笉婊?*/
L340: return this._deepClone(item); /* 杩斿洖娣辨嫹璐濓紝淇濇姢闃熷垪鍐呴儴鏁版嵁 */
L343: /* 涓㈠純鏁版嵁锛氫粠闃熷熬鍚戝墠涓㈠純 len 椤?(鍙嶅悜绉诲姩 tail) */
L346: if (this.isEmpty()) return false; /* 闃熺┖鍒欎笉鑳界户缁涪寮?*/
L348: /* 瀹氫綅鏈€鍚庝竴椤?*/
L350: this.currentMemoryBytes -= this._estimateSize(item); /* 鍑忓幓鍐呭瓨澶у皬 */
L351: this.tail = (this.tail - 1 + this.capacity) % this.capacity; /* tail 鍥為€€ */
L357: /* 鑾峰彇褰撳墠闃熷垪涓厓绱犱釜鏁?*/
L372: /* 寰幆鐩村埌鎴愬姛鍏ラ槦鎴栬秴鏃?*/
L374: if (Date.now() - start >= timeoutMs) return false; /* 瓒呮椂閫€鍑?*/
L375: await new Promise(resolve => setTimeout(resolve, 1)); /* 寮傛杞, 鑷棆鍔?sleep 鎸傝捣 1ms */
L390: if (item !== null) return item; /* 鎴愬姛鍙栧嚭鍒欒繑鍥?*/
L391: if (Date.now() - start >= timeoutMs) return null; /* 瓒呮椂閫€鍑?*/
L392: await new Promise(resolve => setTimeout(resolve, 1)); /* 寮傛杞, 鑷棆鍔?sleep 鎸傝捣 1ms */
L396: /* JSON 搴忓垪鍖栨帴鍙o紝鐢ㄤ簬 JSON.stringify(queue) */
L402: result.push(this._deepClone(this.buffer[i])); /* 澶嶅埗姣忎釜鍏冪礌 */
L403: i = (i + 1) % this.capacity; /* 绉诲姩鍒颁笅涓€涓厓绱?*/
L424: /* 閲婃斁閿佽祫婧?*/
 
### src\lib\TracePoint\tryLock.js (2)
L1: /* 鍘熷瓙灏濊瘯閿? 闈為樆濉炰笖绾跨▼瀹夊叏, 鍙敤浜庡紓姝ュ绾跨▼ */
L22: /* 閲婃斁閿佽祫婧?*/
 
### src\lib\utils.ts (15)
L48: 4: { get text() { return i18n.t('constants.locationRTKFixed') }, color: '#52c41a' }, // 鏈€浼? L109: city: "鑻忓窞",
L134: console.error('[WeatherAPI] 鑾峰彇澶╂皵鏁版嵁澶辫触锛?, error);
L135: throw new Error(`澶╂皵鎺ュ彛璋冪敤澶辫触锛?{error.message}`);
L147: if (!weatherText) return "cloudy"; // 鍏滃簳
L152: if (text.includes("鏅?)) {
L158: text.includes("闆?) ||
L159: text.includes("闆?) ||
L160: text.includes("鏆撮洦")
L166: if (text.includes("浜?) || text.includes("闃?)) {
L189: .filter(col => col.title && col.dataIndex) // 鍙彇鏈夋爣棰?鏈夊瓧娈电殑鍒? L200: return String(val).replace(/"/g, '""'); // 杞箟CSV寮曞彿
L347: ERROR: '#FF4D4F', // 閿欒 绾? L348: WARNING: '#FA8C16', // 璀﹀憡 姗? L349: INFO: '#1890FF', // 淇℃伅 钃?
### src\pages\Agri.jsx (16)
L4399: console.error('杞澶辫触', err);
L4821: {/* 杈撳叆棰勮 */}
L4844: {/* 缁撴灉鍥?瑙嗛 */}
L4870: {/* 缁撴灉JSON */}
L4911: {/* 椤堕儴缁熻鍗$墖 */}
L4999: {/* 宸︿晶锛氱粨鏋滃浘 + 鐑偣鏍囪 */}
L5024: <Empty description={<span style={{ color: '#fff' }}>璇蜂笂浼犵儹鎴愬儚鏂囦欢</span>} image={Empty.PRESENTED_IMAGE_SIMPLE} />
L5027: {/* 鐑偣鏍囪鐐?*/}
L5069: {/* 鍙充晶锛氱偣浣嶈鎯?+ 鍒楄〃 */}
L5078: {/* 鎬诲鍣細鍨傜洿甯冨眬锛屽崰婊″崱鐗囧唴瀹瑰尯 */}
L5088: {/* --------------- 涓婂崐閮ㄥ垎锛氱偣浣嶈鎯?50% --------------- */}
L5132: {/* 鍒嗗壊绾?*/}
L5140: {/* --------------- 涓嬪崐閮ㄥ垎锛氱儹鐐?闈㈡澘鍒楄〃 50% --------------- */}
L5199: {/* 宸︿晶锛氱畻娉曞垪琛?*/}
L5236: {/* 涓棿锛氬伐浣滃尯 */}
L5265: {/* 鍙充晶锛氬巻鍙茶褰?*/}
 
### src\pages\AIAnalysis.tsx (104)
L21: { key: '1', measure: '澶勭悊鐑枒缁勪欢', priority: '楂?, expectedGain: '+2.15%', confidence: '92%' },
L22: { key: '2', measure: '鎺掓煡寮傚父缁勪覆', priority: '楂?, expectedGain: '+1.85%', confidence: '90%' },
L23: { key: '3', measure: '娓呮礂鍙楅伄鎸″尯鍩?, priority: '涓?, expectedGain: '+0.45%', confidence: '78%' },
L24: { key: '4', measure: '璺熻釜琛板噺杈冨ぇ缁勪欢', priority: '涓?, expectedGain: '+0.35%', confidence: '86%' },
L25: { key: '5', measure: '鎸佺画鐩戞帶閫嗗彉鍣ㄦ晥鐜?, priority: '浣?, expectedGain: '+0.10%', confidence: '93%' },
L29: { name: '鏂归樀 A-05', temp: '71.5鈩?, id: 'A05', status: 'serious' },
L30: { name: '鏂归樀 A-12', temp: '68.3鈩?, id: 'A12', status: 'warning' },
L31: { name: '鏂归樀 B-03', temp: '64.8鈩?, id: 'B03', status: 'warning' },
L32: { name: '鏂归樀 C-07', temp: '67.2鈩?, id: 'C07', status: 'warning' },
L144: else if (status === '杞诲井') color = '#1677ff';
L152: if (impact === '楂?) color = '#ff4d4f';
L153: else if (impact === '涓?) color = '#fa8c16';
L154: else if (impact === '浣?) color = '#52c41a';
L161: if (priority === '楂?) color = '#ff4d4f';
L162: else if (priority === '涓?) color = '#fa8c16';
L163: else if (priority === '浣?) color = '#52c41a';
L195: AI 鏅鸿兘璇婃柇涓庡垎鏋愪腑蹇? L198: <Button icon={<ReloadOutlined />}>鍒锋柊鏁版嵁</Button>
L199: <Button type="primary">瀵煎嚭鎶ュ憡</Button>
L203: {/* 绗竴鎺掞細椤堕儴缁熻鍗$墖 */}
L206: { title: 'PR鍊?(鎬ц兘姣?', value: '82.6%', trend: '杈冩槰鏃?-1.3%', icon: <RiseOutlined />, color: '#00B42A', bg: '#E8FFEA', trendColor: '#F53F3F', direction: 'down' },
L207: { title: '鍙戠數鍋忓樊鐜?, value: '-4.35%', trend: '杈冩槰鏃?-1.02%', icon: <FallOutlined />, color: '#F53F3F', bg: '#FFF1F0', trendColor: '#F53F3F', direction: 'down' },
L208: { title: '寮傚父缁勪覆鏁伴噺', value: '8', trend: '杈冩槰鏃?+2 鈫?, icon: <AppstoreOutlined />, color: '#1D2129', bg: '#F5F7FA', trendColor: '#F53F3F', direction: 'up' },
L209: { title: '鐑枒鐤戜技鏁伴噺', value: '36', trend: '杈冩槰鏃?+5 鈫?, icon: <BellOutlined />, color: '#F53F3F', bg: '#FFF1F0', trendColor: '#F53F3F', direction: 'up' },
L210: { title: '鐢电珯鍋ュ悍搴﹁瘎鍒?, value: '86.3', unit: '鍒?, trend: '杈冩槰鏃?-1.7', icon: <CheckCircleOutlined />, color: '#00B42A', bg: '#E8FFEA', trendColor: '#F53F3F', direction: 'down' },
L211: { title: '棰勬祴鍙戠數閲?, value: '4,821', unit: t('home.kWh'), trend: '杈冩槰鏃?+2.6% 鈫?, icon: <ThunderboltOutlined />, color: '#165DFF', bg: '#E8F3FF', trendColor: '#00B42A', direction: 'up' },
L244: {/* 绗簩鎺掞細鐑垚鍍忓垎鏋?鍜?缁勪覆寮傚父瀹氫綅 */}
L248: title={<span style={{ fontSize: 15, fontWeight: 700, color: '#1D2129' }}>鏃犱汉鏈虹儹鎴愬儚宸℃鍒嗘瀽<InfoCircleOutlined style={{ marginLeft: 6, color: '#86909C', fontSize: 13 }} /></span>}
L249: extra={<Text type="secondary" style={{ fontSize: 12 }}>宸℃锛?025-05-20 09:30 <CalendarOutlined style={{ marginLeft: 4 }} /></Text>}
L259: {/* 妯℃嫙鐑枒鐐?*/}
L266: {item.status === 'serious' ? '楂樺嵄' : '娉ㄦ剰'}
L276: <span style={{ display: 'flex', alignItems: 'center', color: '#1D2129' }}><AimOutlined style={{ color: '#F53F3F', marginRight: 6 }} />鐑枒鐤戜技鐐?/span>
L277: <span style={{ display: 'flex', alignItems: 'center', color: '#1D2129' }}><div style={{ width: 14, height: 10, border: '1.5px dashed #F53F3F', borderRadius: 2, marginRight: 6 }}></div>楂樻俯鍖哄煙</span>
L280: <span style={{ fontSize: 12, color: '#86909C' }}>娓╁害鍒嗗竷: 25鈩?~ 85鈩?/span>
L288: title={<span style={{ fontSize: 15, fontWeight: 700, color: '#1D2129' }}>缁勪覆瀹炴椂鐘舵€佸畾浣嶅浘<InfoCircleOutlined style={{ marginLeft: 6, color: '#86909C', fontSize: 13 }} /></span>}
L290: <span>鎬荤粍涓? <b style={{ color: '#1D2129' }}>160</b></span>
L291: <span>寮傚父: <b style={{ color: '#F53F3F' }}>8</b></span>
L308: <div style={{ fontSize: 11, color: '#86909C', display: 'flex', alignItems: 'center', fontWeight: 600 }}>{row}鎺?/div>
L310: let color = '#E8F3FF'; // 姝e父
L312: let tooltip = `缁勪覆 ${row}-${col + 1}: 姝e父`;
L315: if (row === 'B' && col === 3) { color = '#F53F3F'; icon = <div style={{ width: 6, height: 6, background: '#fff', borderRadius: '50%' }} />; tooltip = `缁勪覆 ${row}-${col + 1}: 涓ラ噸寮傚父 (鐑枒)`; }
L316: if (row === 'B' && col === 17) { color = '#F53F3F'; icon = <div style={{ width: 6, height: 6, background: '#fff', borderRadius: '50%' }} />; tooltip = `缁勪覆 ${row}-${col + 1}: 涓ラ噸寮傚父 (鏂矾)`; }
L317: if (row === 'C' && col === 15) { color = '#FF7D00'; icon = <div style={{ width: 6, height: 6, background: '#fff', borderRadius: '50%' }} />; tooltip = `缁勪覆 ${row}-${col + 1}: 寮傚父 (鍔熺巼鍋忓樊)`; }
L318: if (row === 'E' && col === 4) { color = '#FF7D00'; icon = <div style={{ width: 6, height: 6, background: '#fff', borderRadius: '50%' }} />; tooltip = `缁勪覆 ${row}-${col + 1}: 寮傚父 (閬尅)`; }
L319: if (row === 'F' && col === 11) { color = '#F7BA1E'; icon = <div style={{ width: 6, height: 6, background: '#fff', borderRadius: '50%' }} />; tooltip = `缁勪覆 ${row}-${col + 1}: 杞诲井寮傚父`; }
L320: if (row === 'G' && col === 1) { color = '#F7BA1E'; icon = <div style={{ width: 6, height: 6, background: '#fff', borderRadius: '50%' }} />; tooltip = `缁勪覆 ${row}-${col + 1}: 杞诲井寮傚父`; }
L321: if (row === 'H' && col === 10) { color = '#86909C'; tooltip = `缁勪覆 ${row}-${col + 1}: 绂荤嚎`; }
L338: { color: '#E8F3FF', label: '杩愯姝e父' },
L339: { color: '#F7BA1E', label: '杞诲井寮傚父' },
L340: { color: '#FF7D00', label: '鍔熺巼寮傚父' },
L341: { color: '#F53F3F', label: '涓ラ噸鏁呴殰' },
L342: { color: '#86909C', label: '璁惧绂荤嚎' },
L354: <WarningOutlined style={{ marginRight: 8, color: '#F53F3F' }} />寮傚父绫诲瀷鍒嗗竷
L358: { label: '涓ラ噸鏁呴殰', value: 2, color: '#F53F3F', percent: '25%' },
L359: { label: '鍔熺巼寮傚父', value: 4, color: '#FF7D00', percent: '50%' },
L360: { label: '杞诲井寮傚父', value: 2, color: '#F7BA1E', percent: '25%' },
L361: { label: '绂荤嚎缁勪覆', value: 0, color: '#86909C', percent: '0%' },
L375: <Button block type="dashed" size="small" style={{ fontSize: 12 }}>鏌ョ湅璇︾粏瀹氫綅琛?/Button>
L383: {/* 绗笁鎺掞細涓変釜涓昏鍒嗘瀽鍖哄煙 */}
L387: title={<span style={{ fontSize: 15, fontWeight: 700, color: '#1D2129' }}>缁勪欢琛板噺瓒嬪娍鍒嗘瀽<InfoCircleOutlined style={{ marginLeft: 6, color: '#86909C', fontSize: 13 }} /></span>}
L393: <span>琛板噺鐜囪秼鍔?(%)</span>
L394: <span style={{ color: '#F53F3F', fontWeight: 600 }}>褰撳墠鍧囧€? -5.32%</span>
L407: name: '骞冲潎琛板噺鐜?,
L413: name: '鏈€浣崇粍浠?,
L419: name: '鏈€宸粍浠?,
L427: <span style={{ color: '#1D2129', fontWeight: 600 }}>琛板噺棰勮:</span>
L428: <span style={{ marginLeft: 4 }}>12鍧楃粍浠惰“鍑忚秴鏍? 寤鸿鎺掓煡銆?/span>
L436: title={<span style={{ fontSize: 15, fontWeight: 700, color: '#1D2129' }}>瀹炴椂鍙戠數琛ㄧ幇娣卞害鍒嗘瀽<InfoCircleOutlined style={{ marginLeft: 6, color: '#86909C', fontSize: 13 }} /></span>}
L443: <div style={{ fontSize: 12, color: '#86909C', marginBottom: 16 }}>鍙戠數閲忓姣斿垎鏋?(kWh)</div>
L455: name: '瀹為檯鍙戠數',
L461: name: '棰勬祴鍙戠數',
L467: name: '鐞嗚鍙戠數',
L475: { label: '褰撴棩瀹為檯鍙戠數', value: '4,752', unit: t('home.kWh'), color: '#165DFF' },
L476: { label: '褰撴棩棰勬祴鍙戠數', value: '4,960', unit: t('home.kWh'), color: '#00B42A' },
L477: { label: '鍙戠數鍋忓樊鐜?, value: '-4.35%', unit: '', color: '#F53F3F' },
L478: { label: '瀹炴椂 PR 鍊?, value: '82.6%', unit: '', color: '#1D2129' },
L496: {/* AI璇婃柇鎬荤粨 */}
L499: <span style={{ fontSize: 14, fontWeight: 700, color: '#1D2129' }}>AI 璇婃柇鎬荤粨</span>
L500: <span style={{ fontSize: 12, color: '#86909C' }}>鏇存柊鏃堕棿: 2025-05-20 09:45</span>
L504: { title: '璇婃柇椤?, dataIndex: 'diagnosis', width: 78 },
L507: { title: '褰卞搷', dataIndex: 'impact', render: renderImpactTag, width: 52 },
L508: { title: '璇︽儏', dataIndex: 'detail', ellipsis: true },
L511: { key: '1', diagnosis: t('aiAnalysis.hotspotDetection'), status: t('home.abnormal'), confidence: '92%', impact: '楂?, detail: '妫€娴嬪埌 36 澶勭儹鏂戠枒浼肩偣' },
L512: { key: '2', diagnosis: '缁勪覆澶遍厤', status: t('home.abnormal'), confidence: '90%', impact: '楂?, detail: '8 涓茬粍涓插瓨鍦ㄥ紓甯? },
L513: { key: '3', diagnosis: '閬尅椋庨櫓', status: '杞诲井', confidence: '78%', impact: '涓?, detail: '灞€閮ㄩ伄鎸″奖鍝?2% 鍙戠數閲? },
L514: { key: '4', diagnosis: '缁勪欢琛板噺', status: t('home.abnormal'), confidence: '86%', impact: '涓?, detail: '骞冲潎琛板噺鐜?-5.32%' },
L515: { key: '5', diagnosis: '閫嗗彉鍣ㄥ紓甯?, status: t('roles.normal'), confidence: '93%', impact: '浣?, detail: '鎵€鏈夐€嗗彉鍣ㄨ繍琛屾甯? },
L528: AI 寤鸿涓庡缃? L532: { title: '寤鸿鎺柦', dataIndex: 'measure', ellipsis: true },
L534: { title: '鏀剁泭', dataIndex: 'gain', render: g => <span style={{ color: '#00B42A', fontWeight: 600 }}>{g}</span>, width: 68 },
L546: {record.isView ? '璇︽儏' : t('workOrder.dispatch')}
L552: { key: '1', measure: '澶勭悊鐑枒缁勪欢', priority: '楂?, gain: '+2.15%', confidence: '92%', isView: false },
L553: { key: '2', measure: '鎺掓煡寮傚父缁勪覆', priority: '楂?, gain: '+1.85%', confidence: '90%', isView: false },
L554: { key: '3', measure: '娓呮礂鍙楅伄鎸″尯鍩?, priority: '涓?, gain: '+0.45%', confidence: '78%', isView: false },
L555: { key: '4', measure: '璺熻釜琛板噺缁勪欢', priority: '涓?, gain: '+0.35%', confidence: '86%', isView: false },
L556: { key: '5', measure: '鐩戞帶閫嗗彉鍣ㄦ晥鐜?, priority: '浣?, gain: '+0.10%', confidence: '93%', isView: true },
L568: {/* 搴曢儴锛氭暟鎹潵婧?*/}
L570: title={<span style={{ fontSize: 15, fontWeight: 700, color: '#1D2129' }}>鍏ㄦ爤鏁版嵁铻嶅悎鏉ユ簮</span>}
L577: { title: '鏃犱汉鏈鸿浇鑽风儹鎴愬儚', time: '2025-05-20 09:30', icon: <ScanOutlined />, status: '鍚屾涓? },
L578: { title: 'SCADA 瀹炴椂閬ユ祴鏁版嵁', time: '2025-05-20 09:45:12', icon: <DatabaseOutlined />, status: t('roles.normal') },
L579: { title: '浜戠姘旇薄鍒嗘瀽绔?, time: '2025-05-20 09:45:00', icon: <CloudOutlined />, status: t('roles.normal') },
L580: { title: '鐢电珯杩愮淮璧勪骇搴?, time: '鏈€杩戞洿鏂? 2025-05-18', icon: <RestOutlined />, status: t('roles.normal') },
L589: <div style={{ fontSize: 12, color: '#86909C', marginTop: 4, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>鏁版嵁鐐? {source.time}</div>
L592: 鐘舵€? {source.status}
 
### src\pages\CleanOptimization.tsx (121)
L41: { id: '璁″垝 01', priority: '楂?, area: '鍖哄潡 15, 01', boost: '4,250 kWh', weather: '88%' },
L42: { id: '璁″垝 02', priority: '楂?, area: '鍖哄潡 02, 11', boost: '3,180 kWh', weather: '85%' },
L43: { id: '璁″垝 03', priority: '涓?, area: '鍖哄潡 05, 12', boost: '2,210 kWh', weather: '80%' },
L44: { id: '璁″垝 04', priority: '涓?, area: '鍖哄潡 07, 03', boost: '1,620 kWh', weather: '78%' },
L45: { id: '璁″垝 05', priority: '浣?, area: '鍖哄潡 17, 13', boost: '1,210 kWh', weather: '82%' },
L49: { area: '鍖哄潡 15', priority: '楂?, duration: '4.0 h', handler: '鏉庡伐', planTime: '2025-05-26 - 05-27', status: '寰呭垱寤? },
L50: { area: '鍖哄潡 01', priority: '楂?, duration: '3.5 h', handler: '鏉庡伐', planTime: '2025-05-26 - 05-27', status: '寰呭垱寤? },
L51: { area: '鍖哄潡 02', priority: '楂?, duration: '2.8 h', handler: '鐜嬪伐', planTime: '2025-05-28 - 05-29', status: '寰呭垱寤? },
L52: { area: '鍖哄潡 11', priority: '楂?, duration: '2.6 h', handler: '鐜嬪伐', planTime: '2025-05-28 - 05-29', status: '寰呭垱寤? },
L53: { area: '鍖哄潡 05', priority: '涓?, duration: '2.2 h', handler: '璧靛伐', planTime: '2025-05-29 - 05-30', status: '寰呭垱寤? },
L70: { date: 'D-7', value: 800, type: '娓呮礂鍓嶅彂鐢甸噺' },
L71: { date: 'D-7', value: 1200, type: '娓呮礂鍚庡彂鐢甸噺' },
L72: { date: 'D-6', value: 850, type: '娓呮礂鍓嶅彂鐢甸噺' },
L73: { date: 'D-6', value: 1250, type: '娓呮礂鍚庡彂鐢甸噺' },
L74: { date: 'D-5', value: 900, type: '娓呮礂鍓嶅彂鐢甸噺' },
L75: { date: 'D-5', value: 1300, type: '娓呮礂鍚庡彂鐢甸噺' },
L76: { date: 'D-4', value: 880, type: '娓呮礂鍓嶅彂鐢甸噺' },
L77: { date: 'D-4', value: 1280, type: '娓呮礂鍚庡彂鐢甸噺' },
L78: { date: 'D-3', value: 920, type: '娓呮礂鍓嶅彂鐢甸噺' },
L79: { date: 'D-3', value: 1320, type: '娓呮礂鍚庡彂鐢甸噺' },
L80: { date: 'D-2', value: 950, type: '娓呮礂鍓嶅彂鐢甸噺' },
L81: { date: 'D-2', value: 1350, type: '娓呮礂鍚庡彂鐢甸噺' },
L82: { date: 'D-1', value: 980, type: '娓呮礂鍓嶅彂鐢甸噺' },
L83: { date: 'D-1', value: 1380, type: '娓呮礂鍚庡彂鐢甸噺' },
L117: { name: '鐏板皹绉疮', value: 6120, color: '#165DFF' },
L118: { name: '楦熺勃閬尅', value: 1480, color: '#F53F3F' },
L119: { name: '娌欏皹娌夌Н', value: 1120, color: '#F7BA1E' },
L125: '楂?: { color: '#ff4d4f', bg: '#fff1f0' },
L126: '涓?: { color: '#faad14', bg: '#fff7e6' },
L127: '浣?: { color: '#52c41a', bg: '#f6ffed' },
L169: title: '姹℃煋鎸囨暟',
L172: tag: '涓瓑',
L174: trend: '杈冩槰鏃?鈻?5.3',
L181: title: '寤鸿娓呮礂鍖哄潡鏁?,
L184: trend: '鍗犳瘮 40%',
L190: title: '棰勮鍙戠數鎻愬崌',
L193: trend: '鍗犲綋鍓嶆棩鍙戠數閲?14.2%',
L199: title: '棰勮鏀剁泭鎻愬崌',
L202: trend: '鎸夌數浠?0.568 鍏?kWh 璁$畻',
L208: title: '涓婃娓呮礂鏃堕棿',
L211: trend: '璺濅粖 12 澶?,
L217: title: '娓呮礂鎴愭湰棰勪及',
L220: trend: '棰勮鍗曟娓呮礂鎬绘垚鏈?,
L280: {/* 鏍囬涓庢搷浣滄爮 */}
L283: <Typography.Title level={4} style={{ margin: 0, fontSize: 'clamp(18px, 1.5vw, 24px)', }}>娓呮礂浼樺寲绠$悊</Typography.Title>
L287: <Text type="secondary" style={{ fontSize: 12 }}><ReloadOutlined /> 鏇存柊鏃堕棿锛?025-05-24 09:30</Text>
L288: <Button icon={<ReloadOutlined />}>鍒锋柊鏁版嵁</Button>
L290: <Option value="7d">鏈€杩?7 澶?/Option>
L291: <Option value="30d">鏈€杩?30 澶?/Option>
L293: <Button type="primary" icon={<DownloadOutlined />}>瀵煎嚭鎶ュ憡</Button>
L298: {/* 宸︿晶锛氬垎鏋愬浘琛?*/}
L300: <Card title={<span style={{ fontSize: 14, fontWeight: 700 }}>姹℃煋瓒嬪娍鍒嗘瀽</span>} bordered={false} style={cardStyle} bodyStyle={{ padding: 16 }}>
L302: <span>姹℃煋鎸囨暟</span>
L304: <span style={{ display: 'flex', alignItems: 'center' }}><div style={{ width: 8, height: 8, background: '#165DFF', marginRight: 4 }}></div>姹℃煋鎸囨暟</span>
L305: <span style={{ display: 'flex', alignItems: 'center' }}><div style={{ width: 8, height: 2, borderBottom: '1px dashed #F53F3F', marginRight: 4 }}></div>闃堝€?/span>
L316: name: '姹℃煋鎸囨暟',
L322: name: '闃堝€?,
L331: <Card title={<span style={{ fontSize: 14, fontWeight: 700 }}>鍙戠數鎹熷け鏋勬垚 <Text type="secondary" style={{ fontWeight: 400, fontSize: 12 }}>(杩?7 澶?</Text></span>} bordered={false} style={cardStyle} bodyStyle
L341: <div style={{ fontSize: 10, color: '#86909C' }}>鎬绘崯澶辩數閲?/div>
L348: <Card title={<span style={{ fontSize: 14, fontWeight: 700 }}>娓呮礂鍓嶅悗瀵规瘮鍒嗘瀽 <Text type="secondary" style={{ fontWeight: 400, fontSize: 12 }}>(杩戜竴娆?</Text></span>} bordered={false} style={cardStyle} bodyStyle
L357: name: '娓呮礂鍓嶅彂鐢甸噺(kWh)',
L362: name: '娓呮礂鍚庡彂鐢甸噺(kWh)',
L369: <Card title={<span style={{ fontSize: 14, fontWeight: 700 }}>娓呮礂鏀剁泭娣卞害娴嬬畻</span>} bordered={false} style={cardStyle} bodyStyle={{ padding: 16 }}>
L372: <div style={{ fontSize: 11, color: '#86909C', marginBottom: 4 }}>棰勮鍙戠數鎻愬崌</div>
L376: <div style={{ fontSize: 11, color: '#86909C', marginBottom: 4 }}>鐢典环 (鍚◣)</div>
L377: <div style={{ fontSize: 15, fontWeight: 800 }}>0.568 <span style={{ fontSize: 11, fontWeight: 400 }}>鍏?kWh</span></div>
L380: <div style={{ fontSize: 11, color: '#86909C', marginBottom: 4 }}>棰勮鍑€鏀剁泭</div>
L381: <div style={{ fontSize: 15, fontWeight: 800, color: '#00B42A' }}>7,286 <span style={{ fontSize: 11, fontWeight: 400 }}>鍏?/span></div>
L384: <div style={{ fontSize: 11, color: '#86909C', marginBottom: 4 }}>ROI (鎶曡祫鍥炴姤)</div>
L390: <span style={{ fontSize: 12, color: '#86909C' }}>鍥炴敹鍛ㄦ湡</span>
L391: <span style={{ fontSize: 18, fontWeight: 800 }}>0.44 <Text style={{ fontSize: 12 }}>澶?/Text></span>
L396: {/* 涓棿锛氬湴鍥惧垎甯冧笌宸ュ崟棰勮 */}
L399: title={<span style={{ fontSize: 15, fontWeight: 700 }}>鐢电珯姹℃煋鍒嗗竷涓庡缓璁竻娲楀尯鍧楀垎甯冨浘</span>}
L406: <span style={{ color: '#86909C' }}>姹℃煋绛夌骇:</span>
L407: <Badge color="#F53F3F" text="浼樺厛娓呮礂 (>75)" />
L408: <Badge color="#FF7D00" text="杈冮珮 (50-75)" />
L409: <Badge color="#F7BA1E" text="涓瓑 (25-50)" />
L410: <Badge color="#D1FF6B" text="杈冧綆 (10-25)" />
L411: <Badge color="#00B42A" text="娓呮磥 (<10)" />
L415: {/* 鍦板浘鑳屾櫙鍥句笌娴姩鏍囩 */}
L419: {/* 妯℃嫙鍖哄潡鍙犲姞灞?*/}
L422: {/* 鍏蜂綋鐨勬薄鏌撳尯鍧楁爣绛?*/}
L438: <div style={{ fontSize: 9, opacity: 0.9 }}>鍖哄潡 {block.id}</div>
L443: {/* 鍙充晶鎮诞鎺у埗鎸夐挳 */}
L455: title={<span style={{ fontSize: 15, fontWeight: 700 }}>娓呮礂宸ュ崟鏅鸿兘棰勮</span>}
L456: extra={<Button type="link" size="small">鏌ョ湅鏇村 <ChevronRight size={14} /></Button>}
L463: { title: '鍖哄潡', dataIndex: 'area', key: 'area' },
L465: { title: '棰勮宸ユ椂', dataIndex: 'duration', key: 'duration' },
L467: { title: '璁″垝鏃堕棿', dataIndex: 'planTime', key: 'planTime' },
L469: { title: t('roles.actions'), key: 'action', render: () => <Button type="primary" size="small" style={{ borderRadius: 4 }}>鍒涘缓宸ュ崟</Button> },
L479: {/* 鍙充晶锛氬喅绛栧缓璁笌鍙傝€?*/}
L481: <Card title={<span style={{ fontSize: 14, fontWeight: 700 }}>鏅鸿兘娓呮礂绛栫暐寤鸿</span>} bordered={false} style={cardStyle} bodyStyle={{ padding: 0 }}>
L483: <Text type="secondary" style={{ fontSize: 11 }}>绠楁硶妯″瀷锛氬鍥犲瓙鍔犳潈缁煎悎浼樺寲妯″瀷 (v2.0)</Text>
L487: { title: '鎺ㄨ崘璁″垝', dataIndex: 'id', key: 'id', width: 85 },
L488: { title: t('workOrder.priority'), dataIndex: 'priority', key: 'priority', render: (p) => <span style={{ color: p === '楂? ? '#F53F3F' : '#F7BA1E', fontWeight: 600 }}>{p}</span>, width: 65 },
L489: { title: '寤鸿鍖哄潡', dataIndex: 'area', key: 'area' },
L490: { title: '棰勮鎻愬崌', dataIndex: 'boost', key: 'boost', render: (b) => <span style={{ color: '#00B42A', fontWeight: 600 }}>{b}</span> },
L491: { title: '澶╂皵閫傚疁搴?, dataIndex: 'weather', key: 'weather', render: (w) => <Space size={4}>{w} <SunOutlined style={{ color: '#F7BA1E' }} /></Space> },
L500: <Card title={<span style={{ fontSize: 14, fontWeight: 700 }}>娓呮礂鎶€鏈柟妗堟帹鑽?/span>} bordered={false} style={cardStyle} bodyStyle={{ padding: 16 }}>
L506: <Text strong style={{ fontSize: 13, color: '#391085' }}>鏅鸿兘鏈哄櫒浜烘柟妗?/Text>
L508: <div style={{ fontSize: 11, color: '#531DAB', marginBottom: 12, lineHeight: 1.5 }}>鍏ㄨ嚜鍔ㄦ竻娲楋紝閫傚悎澶ч潰绉钩鏁村尯鍧楋紝鏁堢巼鏋侀珮銆?/div>
L510: <span style={{ color: '#8c8c8c' }}>棰勮鐢ㄦ按:</span>
L511: <Text strong>18 鍚?/Text>
L519: <Text strong style={{ fontSize: 13, color: '#003A8C' }}>浜哄伐绮剧粏鍖栨柟妗?/Text>
L521: <div style={{ fontSize: 11, color: '#0050B3', marginBottom: 12, lineHeight: 1.5 }}>鐏垫椿澶勭悊閬尅鍙婁弗閲嶆薄鍨㈠尯鍩燂紝閫傚悎澶嶆潅鍦板舰銆?/div>
L523: <span style={{ color: '#8c8c8c' }}>棰勮鐢ㄦ按:</span>
L524: <Text strong>32 鍚?/Text>
L531: <Card title={<span style={{ fontSize: 14, fontWeight: 700 }}>澶╂皵涓庤祫婧愮幆澧冨弬鑰?<Text type="secondary" style={{ fontSize: 12, fontWeight: 400 }}>(璁″垝 01)</Text></span>} bordered={false} style={cardStyle} bodySt
L535: <div style={{ fontSize: 11, color: '#86909C' }}>05-26 (鍛ㄤ竴)</div>
L537: <div style={{ fontSize: 12, fontWeight: 700 }}>澶氫簯 18~28鈩?/div>
L542: <div style={{ fontSize: 11, color: '#86909C' }}>05-27 (鍛ㄤ簩)</div>
L544: <div style={{ fontSize: 12, fontWeight: 700 }}>鏅?19~30鈩?/div>
L550: <Wind size={14} style={{ color: '#86909C' }} /><span style={{ fontSize: 11 }}>椋庨€? <b style={{ color: '#00B42A' }}>2.1m/s (閫傚疁)</b></span>
L553: <CloudRain size={14} style={{ color: '#86909C' }} /><span style={{ fontSize: 11 }}>闄嶆按: <b style={{ color: '#86909C' }}>10% (浣?</b></span>
L556: <Droplets size={14} style={{ color: '#165DFF' }} /><span style={{ fontSize: 11 }}>姘存簮: <b style={{ color: '#165DFF' }}>鍏呰冻 (50t)</b></span>
L563: <Card title={<span style={{ fontSize: 14, fontWeight: 700 }}>娓呮礂浣滀笟褰卞搷缁煎悎璇勪及</span>} bordered={false} style={cardStyle} bodyStyle={{ padding: 16 }}>
L566: { icon: <Droplets size={18} color="#165DFF" />, bg: '#E8F3FF', label: '棰勮鐢ㄦ按閲?, value: '18 鍚?, sub: '鑺傛按 30% (鏈哄櫒浜?', subColor: '#00B42A' },
L567: { icon: <Calendar size={18} color="#165DFF" />, bg: '#E8F3FF', label: '棰勮鎬昏€楁椂', value: '12 灏忔椂', sub: '骞惰浣滀笟 2 缁?, subColor: '#86909C' },
L568: { icon: <Leaf size={18} color="#00B42A" />, bg: '#E8FFEA', label: '纰冲噺鎺掕础鐚?, value: '6.85 鍚?, sub: 'CO鈧?鍑忔帓閲?, subColor: '#86909C' },
L569: { icon: <ShieldCheck size={18} color="#F7BA1E" />, bg: '#FFF7E8', label: '浣滀笟椋庨櫓璇勪及', value: t('aiAnalysis.lowRisk'), valueColor: '#00B42A', sub: '瀹夊叏鍙帶', subColor: '#86909C' },
L586: 浠ヤ笂鍐崇瓥寤鸿鍩轰簬鍘嗗彶鏁版嵁銆佸疄鏃舵皵璞″強鍙戠數鎹熷け妯″瀷缁煎悎璁$畻銆傚疄闄呮墽琛屾晥鏋滃彲鑳藉彈澶╂皵楠ゅ彉銆佺幇鍦虹獊鍙戦殰纰嶇瓑涓嶇‘瀹氬洜绱犲奖鍝嶃€?
### src\pages\Devices.tsx (1)
L43: console.log('鍒囨崲鍒?, key, '褰撳墠閫変腑璁惧SN', selectedSn);
 
### src\pages\Home.tsx (79)
L48: province: "姹熻嫃鐪?,
L49: city: "鍗楅€氬競",
L50: district: "宕囧窛鍖?,
L52: weather: "鏅?,
L55: wind_direction: "瑗垮崡椋?,
L56: wind_power: "2绾?,
L69: console.error("澶╂皵鎺ュ彛璇锋眰澶辫触", err);
L91: { name: t('home.combinerBox'), count: "2/2", status: "寮傚父 1" },
L92: { name: t('home.inverter'), count: "3/3", status: "寮傚父 1" },
L93: { name: "鐢佃〃", count: "1/1", status: t('roles.normal') },
L98: { name: "鍗囧帇绔欏畨闃插贰妫€浠诲姟", device: "UAV-01", status: "鑽夌", time: "04-29T...", person: "寮犺繍缁? },
L99: { name: "B鍖烘竻娲椾换鍔?, device: "CLEAN-01", status: "寰呮墽琛?, time: "04-29T...", person: "寮犺繍缁? },
L100: { name: "A鍖哄贰妫€浠诲姟", device: "ROBOT-01", status: "宸叉淳鍙?, time: "04-29T...", person: "寮犺繍缁? }
L104: { type: "AI鍒嗘瀽", content: "AI鍙戠幇閫嗗彉鍣ㄦ俯搴︿笌缁勪覆鐢垫祦瀛樺湪杞诲井寮傚父锛屽缓璁紭鍏堝鏍窤鍖鸿澶囥€?, desc: "鍙戠幇2澶勭粍浠跺瓨鍦ㄥ紓甯哥儹鏂? },
L105: { type: t('constants.critical'), content: "INV-A02鏁g儹妫€淇缓璁細寤鸿妫€鏌NV-A02鏁g儹椋庢墖銆侀閬撳拰杩愯璐熻浇锛屾寔缁珮娓╂椂杞淮淇伐鍗曘€?, desc: "3涓粍涓插瓨鍦ㄥ彂鐢靛紓甯? },
L106: { type: t('constants.critical'), content: "A05闃靛垪鐑枒澶勭疆寤鸿锛氬缓璁幇鍦哄鏍窹V-A05-018鑷砅V-A05-020缁勪欢鎺ョ嚎鍜屾梺璺簩鏋佺鐘舵€侊紝蹇呰鏃舵洿鎹㈠紓甯哥粍浠躲€?, desc: "鏁翠綋鍙戠數鍋忓樊-2.8%" }
L147: { name: '杩涜涓?, value: 35, color: '#52c41a' },
L148: { name: '寰呭紑濮?, value: 20, color: '#faad14' },
L168: id: '', // 涓婚敭ID锛堟柊澧炰负绌猴級
L169: orderNo: '', // 宸ュ崟缂栧彿锛堝悗绔敓鎴愶級
L170: orderTitle: '鍏変紡缁勪欢娓呮礂宸ュ崟', // 宸ュ崟鏍囬
L171: sourceType: 3, // 鏉ユ簮 3=娓呮礂
L172: orderType: 3, // 绫诲瀷 3=娓呮礂
L173: priorityLevel: 2, // 浼樺厛绾?2=涓? L175: deviceName: currentStation.siteName || '鐢电珯',
L176: deviceType: 1, // 璁惧绫诲瀷锛氱數绔? L189: orderStatus: 1, // 鐘舵€?1=寰呭鐞? L192: taskDescription: '鏍规嵁鐢电珯娓呮磥搴﹀缓璁繘琛岀粍浠舵竻娲楋紝鎻愬崌鍙戠數鏁堢巼',
L193: aiSuggestion: '绯荤粺鑷姩鐢熸垚娓呮礂寤鸿锛岄璁℃彁鍗囧彂鐢甸噺2.6%',
L194: requiredEquipment: '娓呮礂璁惧銆佹按鏋€佹姽甯?,
L195: estimatedImpact: '2.6', // 褰卞搷鍙戠數閲?%) 鏁板瓧
L203: messageApi.success('鉁?娓呮礂宸ュ崟鐢熸垚鎴愬姛');
L205: messageApi.error(res.msg || '鉂?宸ュ崟鐢熸垚澶辫触');
L208: messageApi.error('鉂?宸ュ崟鐢熸垚鎺ュ彛璋冪敤澶辫触');
L225: messageApi.error('鍔犺浇澶辫触');
L238: {/* 馃憞 蹇呴』鍔犺繖涓紝message鎵嶈兘姝e父鏄剧ず */}
L241: {/* 椤堕儴缁熻鍗$墖 */}
L244: { title: t('home.todayGeneration'), value: '4,752', unit: t('home.kWh'), sub: '鏃ョ洰鏍?5,000 kWh', color: '#00B42A', bg: '#E8FFEA', icon: <ThunderboltOutlined /> },
L245: { title: t('home.currentPower'), value: '812.6', unit: 'kW', sub: '瑁呮満瀹归噺 1,000 kWp', color: '#165DFF', bg: '#E8F3FF', icon: <DashboardOutlined /> },
L246: { title: 'Performance Ratio', value: '82.6%', unit: '', sub: '鏄ㄦ棩 81.3% 鈫?.3%', color: '#00B42A', bg: '#E8FFEA', icon: <BarChartOutlined /> },
L247: { title: t('home.systemAvailability'), value: '99.35%', unit: '', sub: '鏄ㄦ棩 99.12% 鈫?.23%', color: '#165DFF', bg: '#E8F3FF', icon: <RiseOutlined /> },
L248: { title: t('home.alertCount'), value: alarmList.length, unit: '', sub: `鏈鐞?${alarmList.filter(item => item.handleStatus == 1).length} / 宸插叧闂?${alarmList.filter(item => item.handleStatus == 2).length}`
L280: {/* 涓讳綋甯冨眬 */}
L282: {/* 宸︿晶鍥捐〃 */}
L286: <div style={{ fontSize: 11, color: '#666', marginBottom: 8 }}>浠婃棩鍙戠數鍔熺巼瓒嬪娍 (kW)</div>
L322: series={[{ key: 'efficiency', name: '鏁堢巼', color: '#165DFF' }]}
L325: <Card title={<span style={{ fontWeight: 800 }}>{t('home.maintenanceProgress')}</span>} extra={<Button type="link" size="small">鏇村 &gt;</Button>} bordered={false} style={cardStyle} bodyStyle={{ padding
L337: <div style={{ fontSize: 12, color: '#999' }}>鎬讳换鍔?/div>
L346: {/* 涓棿 */}
L374: title="澶栭儴绯荤粺"
L384: <Card title={<span style={{ fontWeight: 800 }}>{t('home.recentInspection')}</span>} extra={<Button type="link" size="small">鏇村 &gt;</Button>} bordered={false} style={{ ...cardStyle, height: "100%" }}
L390: { title: '宸℃绫诲瀷', dataIndex: 'name', key: 'name', ellipsis: true },
L391: { title: '宸℃鏃堕棿', dataIndex: 'time', key: 'time' },
L392: { title: '宸℃浜哄憳', dataIndex: 'person', key: 'person', render: (t) => t.substring(0, 10) },
L393: { title: t('roles.status'), dataIndex: 'status', key: 'status', render: () => <span style={{ color: '#52c41a', fontSize: 12 }}>鈼?宸插畬鎴?/span> },
L407: <div style={{ fontSize: 16, fontWeight: 600, color: '#1D2129' }}>鐑偣妫€娴?/div>
L408: <div style={{ fontSize: 14, color: '#4E5969', marginTop: 4 }}>鍙戠幇 <span style={{ color: '#165DFF', fontWeight: 600 }}>2</span> 澶勭粍浠跺瓨鍦ㄥ紓甯哥儹鏂?/div>
L419: <div style={{ fontSize: 16, fontWeight: 600, color: '#1D2129' }}>缁勪覆寮傚父</div>
L420: <div style={{ fontSize: 14, color: '#4E5969', marginTop: 4 }}><span style={{ color: '#165DFF', fontWeight: 600 }}>3</span> 涓粍涓插瓨鍦ㄥ彂鐢靛紓甯?/div>
L431: <div style={{ fontSize: 16, fontWeight: 600, color: '#1D2129' }}>鍙戠數鍋忓樊鍒嗘瀽</div>
L432: <div style={{ fontSize: 14, color: '#4E5969', marginTop: 4 }}>鏁翠綋鍙戠數鍋忓樊 <span style={{ color: '#165DFF', fontWeight: 600 }}>-2.8%</span></div>
L444: {/* 鍙充晶 */}
L447: <Card title={<span style={{ fontWeight: 800 }}>{t('alerts.realtimeAlert')}</span>} extra={<Button type="link" size="small" onClick={() => navigate('/alerts/all')}>鏇村 &gt;</Button>} bordered={false} st
L449: <span style={{ flex: 3 }}>鍛婅鍐呭</span>
L450: <span style={{ flex: 1, textAlign: 'center' }}>绾у埆</span>
L451: <span style={{ flex: 1.5, textAlign: 'right' }}>鍙戠敓鏃堕棿</span>
L471: <Card title={<span style={{ fontWeight: 800 }}>{t('home.deviceOnlineStatus')}</span>} extra={<Button type="link" size="small">鏇村 &gt;</Button>} bordered={false} style={cardStyle} bodyStyle={{ padding:
L474: { name: '缁勪欢闃靛垪', count: '320/320', icon: <AppstoreOutlined /> },
L477: { name: '姘旇薄绔?, count: '1/1', icon: <CloudOutlined /> },
L479: { name: '鐜浼犳劅鍣?, count: '8/8', icon: <ExperimentOutlined /> },
L496: <Card title={<span style={{ fontWeight: 800 }}>{t('home.weatherInfo')}</span>} extra={<Button type="link" size="small">璇︾粏 &gt;</Button>} bordered={false} style={cardStyle} bodyStyle={{ padding: '12px'
L506: <div>婀垮害 {weatherdata.humidity}%</div>
L514: {/* 馃憞 娓呮礂寤鸿 + 鐢熸垚宸ュ崟鎸夐挳锛堝凡瀹屽杽锛?*/}
L516: <Card title={<span style={{ fontWeight: 800 }}>{t('clean.cleaningSuggestion')}</span>} extra={<Button type="link" size="small">鏇村 &gt;</Button>} bordered={false} style={cardStyle} bodyStyle={{ padding
L521: { name: '娓呮磥搴?, value: 85, color: '#00B42A' },
L534: <div style={{ fontSize: 12, color: '#666', marginBottom: 4 }}>寤鸿娓呮礂鏃堕棿: <span style={{ color: '#165DFF' }}>3澶╁唴</span></div>
L535: <div style={{ fontSize: 12, color: '#666', marginBottom: 4 }}>棰勮鎻愬崌鍙戠數閲? <span style={{ color: '#00B42A' }}>2.6 %</span></div>
L536: <div style={{ fontSize: 12, color: '#666' }}>棰勮鎻愬崌鐢甸噺: <span style={{ color: '#00B42A' }}>120 kWh/澶?/span></div>
L545: 鐢熸垚娓呮礂宸ュ崟
 
### src\pages\Login.tsx (3)
L88: {/* 宸︿晶锛氳〃鍗曞尯鍩?*/}
L112: {/* 鐢ㄦ埛鍗忚 */}
L149: {/* 鍙充晶锛氭褰㈡枩鍒?+ 鍥剧墖閾烘弧 */}
 
### src\pages\Profile.tsx (9)
L49: const message = utils.message; // 浣跨敤鍏ㄥ眬 message
L144: {/* 馃敟 鍏抽敭锛氱粰 Row 娣诲姞 align="stretch" 璁╀袱鍒楄嚜鍔ㄧ瓑楂?*/}
L146: {/* 宸︿晶淇℃伅鍗$墖 */}
L155: height: '100%', // 馃敟 楂樺害 100%
L160: <div style={{ padding: '20px 0', flex: 1 }}> {/* 馃敟 鑷姩濉厖楂樺害 */}
L220: {/* 鍙充晶琛ㄥ崟鍗$墖 */}
L228: height: '100%', // 馃敟 楂樺害 100%
L238: {/* 鍩烘湰璧勬枡 */}
L335: {/* 淇敼瀵嗙爜 */}
 
### src\pages\RealTimeMonitor.tsx (10)
L109: {/* 宸︿晶澶ф爮 */}
L112: {/* 鐢电珯鎷撴墤鍥?*/}
L139: title="澶栭儴绯荤粺"
L148: {/* 璁惧瀹炴椂鐩戞帶鍒楄〃 */}
L181: {/* 鍙充晶灏忔爮 */}
L184: {/* 6涓粺璁″崱鐗?*/}
L212: {/* 瀹炴椂鍔熺巼鏇茬嚎 */}
L233: {/* 閫嗗彉鍣ㄥ姛鐜囧姣?*/}
L252: {/* 鐑姏鍥句笌鍦ㄧ嚎鐜?*/}
L333: {/* 绠€鏄撳湴鍥剧偣浣?*/}
 
### src\pages\ReportCenter.tsx (20)
L160: { name: t('report.stationMonthly'), time: '2025-05-31 08:15', operator: '寮犺繍缁?, type: t('report.generationReport'), status: t('report.generated') },
L163: { name: t('report.operationSummary'), time: '2025-05-31 09:00', operator: '鏉庡伐绋嬪笀', type: t('report.operationReport'), status: t('report.generated') },
L164: { name: t('report.cleaningEffectReport'), time: '2025-05-28 10:20', operator: '鐜嬭繍缁?, type: t('report.operationReport'), status: t('report.generated') },
L204: {/* 椤甸潰澶撮儴鏍囩 */}
L230: {/* 宸︿晶鏂囧瓧鍖哄煙 */}
L239: {/* 搴曢儴鐜瘮/澶囨敞 */}
L245: {/* 鍙充晶鍦嗗舰鍥炬爣鍖哄煙 */}
L268: {/* 绛涢€夋爮 */}
L307: {/* 宸︿晶涓诲唴瀹瑰尯 */}
L309: {/* 鏈堝害缁煎悎缁忚惀鍒嗘瀽 */}
L364: {/* 绗簩鎺掞細涓変釜鍥捐〃 */}
L483: {/* 璁㈤槄涓庡垎鍙?*/}
L490: { name: '寮犺繍缁?, role: t('report.roleOmSupervisor'), img: 'https://img.icons8.com/fluency/48/user-male-circle.png' },
L491: { name: '鏉庡伐绋嬪笀', role: t('report.roleStationEngineer'), img: 'https://img.icons8.com/fluency/48/user-male-circle.png' },
L492: { name: '鐜嬭繍缁?, role: t('report.roleDeviceOm'), img: 'https://img.icons8.com/fluency/48/user-male-circle.png' },
L493: { name: '闄堢粡鐞?, role: t('report.roleOmManager'), img: 'https://img.icons8.com/fluency/48/user-male-circle.png' },
L526: {/* 鍙充晶杈规爮 */}
L528: {/* 鎶ヨ〃鐩綍 / 蹇嵎涓嬭浇 */}
L558: {/* 妯℃澘涓績 */}
L577: {/* 鎶ヨ〃鐢熸垚璁板綍 */}
 
### src\pages\Roles.tsx (7)
L170: {/* 缁熶竴鍗$墖瀹瑰櫒锛堝拰鑿滃崟绠$悊涓€鑷达級 */}
L172: {/* 椤堕儴鎿嶄綔鏍忥紙鍜岃彍鍗曠鐞嗙粺涓€锛?*/}
L183: {/* 瑙掕壊鍗$墖鍒楄〃 */}
L204: onClick={() => console.log('绠$悊鎴愬憳', role.roleId)}
L248: {/* 鍒嗛〉缁勪欢锛堟纭Е鍙戯級 */}
L260: {/* 鏂板/缂栬緫寮圭獥 */}
L282: {/* 鐘舵€?Switch */}
 
### src\pages\SystemSetting.tsx (1)
L67: <Text type="secondary" style={{ fontSize: '12px' }}>鍛婅瑙勫垯閰嶇疆銆佺敤鎴疯鑹层€侀€氱煡绠$悊涓庣郴缁熷弬鏁拌缃?/Text>
 
### src\pages\Users.tsx (4)
L87: roleIds: roleIds, // 鍥炲~澶氶€夎鑹? L111: roleIds: values.roleIds || [], // 鐩存帴鎻愪氦鏁扮粍
L208: {/* 鏂板/缂栬緫寮圭獥 */}
L262: {/* 澶氳鑹查€夋嫨 */}
 
### src\pages\Video.tsx (3)
L45: case '瀹夐槻鍨?:
L51: case '杩愯緭鍨?:
L57: case '宸℃鍨?:
 
### src\pages\VideoMonitorPage.tsx (4)
L99: {/* 椤堕儴缁熻鍗$墖 */}
L194: {/* 涓棿瑙嗛鐩戞帶涓績 */}
L297: {/* 搴曢儴涓夋爮 */}
L375: {/* 妯℃嫙妫€娴嬫 */}
 
### src\pages\WorkOrder.tsx (53)
L70: const [selectedRowKeys, setSelectedRowKeys] = useState<string[]>([]); // 鎵归噺閫変腑
L78: todayAdd: 0, // 浠婃棩鏂板宸ュ崟
L79: pending: 0, // 寰呭鐞嗘€绘暟
L80: pendingHigh: 0, // 寰呭鐞嗛珮浼樺厛绾? L81: running: 0, // 鎵ц涓? L82: finishedMonth: 0, // 鏈湀宸插畬鎴? L83: finishRate: '0', // 鎸夋椂瀹屾垚鐜? L84: avgHandleHour: 0, // 骞冲潎澶勭悊鏃堕暱
L85: aiCreate: 0, // AI鑷姩鐢熸垚宸ュ崟
L86: todayAddDiff: '', // 浠婃棩鏂板瀵规瘮鏄ㄦ棩
L87: avgDiff: '' // 骞冲潎鏃堕暱瀵规瘮涓婂懆
L93: const isShowDispatch = userInfo?.roleId !== 26; //鏅€氱敤鎴? L233: assigneeId: values.assignUserId, // 閫変腑浜哄憳ID
L320: todayAddDiff: '+3', // 濡傞渶鐪熷疄鏄ㄦ棩瀵规瘮锛屽崟鐙姹傛槰鏃ョ粺璁℃帴鍙? L369: console.error('鍔犺浇杩?澶╁憡璀﹀け璐?, err);
L408: console.error('鏁版嵁璇锋眰澶辫触', err);
L550: console.log('鏌ヨ琛ㄥ崟鍊?', values);
L590: handleResult: '宸插鐞嗗畬鎴?,
L612: orderStatus: 3, // 宸插畬鎴? L675: const levelText = levelNum2Text[currentDetail?.priorityLevel]; //鏁板瓧杞瓧绗︿覆
L742: setSelectedRowKeys([]); // 娓呯┖閫変腑
L787: setSelectedRowKeys([]); // 娓呯┖閫変腑
L788: getWorkOrderList(); // 鍒锋柊鍒楄〃
L797: fetchWeekAlarmData(); // 鏂板鍔犺浇7澶╁憡璀? L902: {/* 椤堕儴鏍囬鍜岄〉绛?*/}
L910: {/* 缁熻鍗$墖 */}
L938: {/* 绛涢€夋爮 */}
L972: {/* 宸︿晶锛氬垪琛?+ 搴曢儴鍥捐〃 */}
L1074: {/* 鏃ユ湡鍒囨崲鏍?*/}
L1087: {/* 妯悜鏃堕棿琛ㄥご */}
L1097: {/* 鍗曚竴琛屾椂闂寸敾甯冿紝涓嶅啀鍖哄垎浜哄憳 */}
L1155: {/* 鏇村宸ュ崟寮圭獥锛氬脊绐楀唴鍙睍绀哄綋鍓嶉€変腑鏃ユ湡宸ュ崟 */}
L1206: {/* 鍙充晶锛氳鎯?+ AI + 鍛婅 */}
L1261: {/* ============ 鏂板锛氬浘鐗?瑙嗛闄勪欢棰勮鍖哄煙 ============ */}
L1269: {/* 鍥剧墖棰勮缁勶紝鏀寔鐐瑰嚮鏀惧ぇ */}
L1288: {/* 瑙嗛棰勮 */}
L1347: {/* 搴曞眰鐏拌壊杞ㄩ亾 */}
L1357: {/* 杩涘害濉厖 */}
L1590: {/* 淇敼宸ュ崟寮圭獥 */}
L1602: <Option value={1}>ERROR(楂?</Option><Option value={2}>WARNING</Option><Option value={3}>INFO</Option>
L1618: {/* 娲惧崟寮圭獥锛氶€夋嫨浜哄憳 */}
L1627: <FormItem name="id" label="宸ュ崟ID" hidden>
L1669: {/* 鎵ц宸ュ崟寮圭獥 */}
L1672: <FormItem name="orderIds" label="宸ュ崟ID" hidden><Input /></FormItem>
L1700: placeholder="璇烽€夋嫨璁惧"
L1711: { label: <span>devices.robot</span>, options: devices.map(item => ({ value: item.device_sn || item.serialNumber, label: item.deviceAlias || item.deviceName || '鏈煡璁惧' })) },
L1712: { label: <span>constants.uav</span>, options: planedevices.map(item => ({ value: item.device_sn, label: item.drone_callsign || item.callsign || '鏈煡璁惧' })) },
L1726: {/* 鏈哄櫒浜鸿澶囧垎缁?*/}
L1740: {/* 鏃犱汉鏈哄垎缁?*/}
L1763: placeholder="璇烽€夋嫨鎵ц寮€濮嬫椂闂?
L1774: {/* 瀹屾垚宸ュ崟寮圭獥 */}
L1781: <Option value="宸插鐞嗗畬鎴?>{t('workOrder.handledCompleted')}</Option><Option value="宸蹭慨澶?>{t('workOrder.fixed')}</Option><Option value="鏃犻渶澶勭悊">{t('workOrder.noActionNeeded')}</Option><Option value="闂宸查棴鐜?>{t
L1792: {/* 杩?澶╁叏閮ㄥ憡璀﹀脊绐?*/}
 
### src\router\index.tsx (3)
L248: { path: 'notice', element: <Suspense fallback={<PageFallback />}><div style={{ padding: 20 }}><h2>閫氱煡绛栫暐椤甸潰</h2></div></Suspense> },
L250: { path: 'dataSafety', element: <Suspense fallback={<PageFallback />}><div style={{ padding: 20 }}><h2>鏁版嵁涓庡畨鍏ㄩ〉闈?/h2></div></Suspense> },
L327: <p className="text-lg font-medium">妯″潡寮€鍙戜腑</p>
 
### src\store\index.ts (2)
L6: import stationReducer from './stationSlice'; // 馃憟 鍔犺繖涓? L11: station: stationReducer, // 馃憟 鍔犺繖涓?
### src\store\stationSlice.ts (2)
L14: currentStation: loadStationFromStorage(), // 褰撳墠閫変腑鍦虹珯锛堝畬鏁村璞★級
L15: stationId: loadStationFromStorage()?.id || null, // 鏂逛究鐩存帴鐢?id
 
### src\store\userSlice.ts (3)
L18: localStorage.setItem('userInfo', JSON.stringify(res)); // 馃憟 淇濆瓨鐢ㄦ埛淇℃伅
L53: userInfo: loadUserFromStorage(), // 馃憟 鍒锋柊鑷姩鎭㈠
L83: console.error('鐧诲綍澶辫触', action.payload);
 
### src\types\index.ts (5)
L72: tenantCode?: string; // 澶氱鎴风櫥褰曟椂浼犲叆
L79: expiresIn?: number; // token 杩囨湡鏃堕棿锛堢锛? L107: menuType?: 0 | 1 | 2; // 0=鐩綍 1=鑿滃崟 2=鎸夐挳
L108: perms?: string; // 鎸夐挳鏉冮檺鏍囪瘑
L133: /** 涓嶅湪鑿滃崟涓睍绀?*/