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

1830 lines
220 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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: /** 涓嶅湪鑿滃崟涓睍绀?*/