[{"data":1,"prerenderedAt":1560},["ShallowReactive",2],{"insight-4":3},{"id":4,"title":5,"body":6,"category":1550,"cover":64,"date":1551,"description":12,"extension":1552,"meta":1553,"navigation":157,"path":1554,"seo":1555,"slug":1556,"stem":1557,"summary":1558,"__hash__":1559},"insight\u002Finsights\u002F4.md","小程序管理端中，充电桩监控功能的实现",{"type":7,"value":8,"toc":1544},"minimark",[9,13,20,25,30,33,40,46,52,55,58,524,529,551,555,558,561,564,583,586,957,962,986,989,992,1169,1172,1176,1182,1185,1188,1206,1209,1317,1322,1343,1346,1493,1496,1507,1510,1514,1517,1537,1540],[10,11,12],"p",{},"实时监控功能是奥升充电系统中，很受管理者喜欢的一个功能。通过它，管理者可以在小程序端随时查看站点的运营情况，了解充电桩的实时状态。",[10,14,15],{},[16,17],"img",{"alt":18,"src":19},"监控界面","https:\u002F\u002Fucode-orise.oss-cn-beijing.aliyuncs.com\u002Fwebsite\u002Farticle\u002F4\u002F1.png",[21,22,24],"h3",{"id":23},"一轮询更新状态","一、轮询更新状态",[26,27,29],"h4",{"id":28},"为什么不用websocket","为什么不用WebSocket？",[10,31,32],{},"实时监控为什么不使用WebSocket这种\"实时\"技术呢？这里有几个重要考虑：",[10,34,35,39],{},[36,37,38],"strong",{},"第一，够用就好","。实时监控功能，主要是查看充电桩的实时状态，不涉及双向交互通信的情况，只需要单向拉取充电桩的状态。而且，用户对实时性要求不高，5秒频率的更新是可接受的。",[10,41,42,45],{},[36,43,44],{},"第二，资源消耗","。WebSocket需要维持长连接，对小程序的内存和电量消耗较大。而轮询方式只在需要时请求数据，更加节能。",[10,47,48,51],{},[36,49,50],{},"第三，兼容性","。不同小程序平台对WebSocket的支持程度不一，轮询作为最基础的HTTP请求，兼容性最好。",[26,53,54],{"id":54},"轮询的具体实现",[10,56,57],{},"我们来看代码中的轮询实现：",[59,60,65],"pre",{"className":61,"code":62,"language":63,"meta":64,"style":64},"language-ts shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","const loadingCountdown = ref(5000) \u002F\u002F 5秒间隔\nconst refreshGunTimer = ref\u003Cany>(null)\nconst responseTime = ref('')\n\n\u002F\u002F 刷新枪状态\nconst stat = ref({})\nconst refreshConnectorList = async () => {\n  clearTimeout(refreshGunTimer.value)\n  if (!stationId.value) return\n\n  try {\n    const res = await getPileStatus(stationId.value)\n    equipmentList.value = res.data.equipmentList\n    stat.value = res.data\n    responseTime.value = dayjs().format('YYYY-MM-DD HH:mm:ss')\n\n    refreshGunTimer.value = setTimeout(() => {\n      refreshConnectorList()\n    }, loadingCountdown.value)\n  } catch (e) {\n    console.error(e)\n  }\n}\n\n\u002F\u002F ... 其他代码 ...\n\nonUnmounted(() => {\n  clearTimeout(refreshGunTimer.value)\n})\n\n","ts","",[66,67,68,103,133,152,159,165,184,206,226,251,256,264,292,316,335,371,376,399,408,423,442,459,465,471,476,482,487,501,516],"code",{"__ignoreMap":64},[69,70,73,77,81,85,89,92,96,99],"span",{"class":71,"line":72},"line",1,[69,74,76],{"class":75},"spNyl","const",[69,78,80],{"class":79},"sTEyZ"," loadingCountdown ",[69,82,84],{"class":83},"sMK4o","=",[69,86,88],{"class":87},"s2Zo4"," ref",[69,90,91],{"class":79},"(",[69,93,95],{"class":94},"sbssI","5000",[69,97,98],{"class":79},") ",[69,100,102],{"class":101},"sHwdD","\u002F\u002F 5秒间隔\n",[69,104,106,108,111,113,115,118,122,125,127,130],{"class":71,"line":105},2,[69,107,76],{"class":75},[69,109,110],{"class":79}," refreshGunTimer ",[69,112,84],{"class":83},[69,114,88],{"class":87},[69,116,117],{"class":83},"\u003C",[69,119,121],{"class":120},"sBMFI","any",[69,123,124],{"class":83},">",[69,126,91],{"class":79},[69,128,129],{"class":83},"null",[69,131,132],{"class":79},")\n",[69,134,136,138,141,143,145,147,150],{"class":71,"line":135},3,[69,137,76],{"class":75},[69,139,140],{"class":79}," responseTime ",[69,142,84],{"class":83},[69,144,88],{"class":87},[69,146,91],{"class":79},[69,148,149],{"class":83},"''",[69,151,132],{"class":79},[69,153,155],{"class":71,"line":154},4,[69,156,158],{"emptyLinePlaceholder":157},true,"\n",[69,160,162],{"class":71,"line":161},5,[69,163,164],{"class":101},"\u002F\u002F 刷新枪状态\n",[69,166,168,170,173,175,177,179,182],{"class":71,"line":167},6,[69,169,76],{"class":75},[69,171,172],{"class":79}," stat ",[69,174,84],{"class":83},[69,176,88],{"class":87},[69,178,91],{"class":79},[69,180,181],{"class":83},"{}",[69,183,132],{"class":79},[69,185,187,189,192,194,197,200,203],{"class":71,"line":186},7,[69,188,76],{"class":75},[69,190,191],{"class":79}," refreshConnectorList ",[69,193,84],{"class":83},[69,195,196],{"class":75}," async",[69,198,199],{"class":83}," ()",[69,201,202],{"class":75}," =>",[69,204,205],{"class":83}," {\n",[69,207,209,212,215,218,221,224],{"class":71,"line":208},8,[69,210,211],{"class":87},"  clearTimeout",[69,213,91],{"class":214},"swJcz",[69,216,217],{"class":79},"refreshGunTimer",[69,219,220],{"class":83},".",[69,222,223],{"class":79},"value",[69,225,132],{"class":214},[69,227,229,233,236,239,242,244,246,248],{"class":71,"line":228},9,[69,230,232],{"class":231},"s7zQu","  if",[69,234,235],{"class":214}," (",[69,237,238],{"class":83},"!",[69,240,241],{"class":79},"stationId",[69,243,220],{"class":83},[69,245,223],{"class":79},[69,247,98],{"class":214},[69,249,250],{"class":231},"return\n",[69,252,254],{"class":71,"line":253},10,[69,255,158],{"emptyLinePlaceholder":157},[69,257,259,262],{"class":71,"line":258},11,[69,260,261],{"class":231},"  try",[69,263,205],{"class":83},[69,265,267,270,273,276,279,282,284,286,288,290],{"class":71,"line":266},12,[69,268,269],{"class":75},"    const",[69,271,272],{"class":79}," res",[69,274,275],{"class":83}," =",[69,277,278],{"class":231}," await",[69,280,281],{"class":87}," getPileStatus",[69,283,91],{"class":214},[69,285,241],{"class":79},[69,287,220],{"class":83},[69,289,223],{"class":79},[69,291,132],{"class":214},[69,293,295,298,300,302,304,306,308,311,313],{"class":71,"line":294},13,[69,296,297],{"class":79},"    equipmentList",[69,299,220],{"class":83},[69,301,223],{"class":79},[69,303,275],{"class":83},[69,305,272],{"class":79},[69,307,220],{"class":83},[69,309,310],{"class":79},"data",[69,312,220],{"class":83},[69,314,315],{"class":79},"equipmentList\n",[69,317,319,322,324,326,328,330,332],{"class":71,"line":318},14,[69,320,321],{"class":79},"    stat",[69,323,220],{"class":83},[69,325,223],{"class":79},[69,327,275],{"class":83},[69,329,272],{"class":79},[69,331,220],{"class":83},[69,333,334],{"class":79},"data\n",[69,336,338,341,343,345,347,350,353,355,358,360,363,367,369],{"class":71,"line":337},15,[69,339,340],{"class":79},"    responseTime",[69,342,220],{"class":83},[69,344,223],{"class":79},[69,346,275],{"class":83},[69,348,349],{"class":87}," dayjs",[69,351,352],{"class":214},"()",[69,354,220],{"class":83},[69,356,357],{"class":87},"format",[69,359,91],{"class":214},[69,361,362],{"class":83},"'",[69,364,366],{"class":365},"sfazB","YYYY-MM-DD HH:mm:ss",[69,368,362],{"class":83},[69,370,132],{"class":214},[69,372,374],{"class":71,"line":373},16,[69,375,158],{"emptyLinePlaceholder":157},[69,377,379,382,384,386,388,391,393,395,397],{"class":71,"line":378},17,[69,380,381],{"class":79},"    refreshGunTimer",[69,383,220],{"class":83},[69,385,223],{"class":79},[69,387,275],{"class":83},[69,389,390],{"class":87}," setTimeout",[69,392,91],{"class":214},[69,394,352],{"class":83},[69,396,202],{"class":75},[69,398,205],{"class":83},[69,400,402,405],{"class":71,"line":401},18,[69,403,404],{"class":87},"      refreshConnectorList",[69,406,407],{"class":214},"()\n",[69,409,411,414,417,419,421],{"class":71,"line":410},19,[69,412,413],{"class":83},"    },",[69,415,416],{"class":79}," loadingCountdown",[69,418,220],{"class":83},[69,420,223],{"class":79},[69,422,132],{"class":214},[69,424,426,429,432,434,437,439],{"class":71,"line":425},20,[69,427,428],{"class":83},"  }",[69,430,431],{"class":231}," catch",[69,433,235],{"class":214},[69,435,436],{"class":79},"e",[69,438,98],{"class":214},[69,440,441],{"class":83},"{\n",[69,443,445,448,450,453,455,457],{"class":71,"line":444},21,[69,446,447],{"class":79},"    console",[69,449,220],{"class":83},[69,451,452],{"class":87},"error",[69,454,91],{"class":214},[69,456,436],{"class":79},[69,458,132],{"class":214},[69,460,462],{"class":71,"line":461},22,[69,463,464],{"class":83},"  }\n",[69,466,468],{"class":71,"line":467},23,[69,469,470],{"class":83},"}\n",[69,472,474],{"class":71,"line":473},24,[69,475,158],{"emptyLinePlaceholder":157},[69,477,479],{"class":71,"line":478},25,[69,480,481],{"class":101},"\u002F\u002F ... 其他代码 ...\n",[69,483,485],{"class":71,"line":484},26,[69,486,158],{"emptyLinePlaceholder":157},[69,488,490,493,495,497,499],{"class":71,"line":489},27,[69,491,492],{"class":87},"onUnmounted",[69,494,91],{"class":79},[69,496,352],{"class":83},[69,498,202],{"class":75},[69,500,205],{"class":83},[69,502,504,506,508,510,512,514],{"class":71,"line":503},28,[69,505,211],{"class":87},[69,507,91],{"class":214},[69,509,217],{"class":79},[69,511,220],{"class":83},[69,513,223],{"class":79},[69,515,132],{"class":214},[69,517,519,522],{"class":71,"line":518},29,[69,520,521],{"class":83},"}",[69,523,132],{"class":79},[10,525,526],{},[36,527,528],{},"关键设计点：",[530,531,532,539,545],"ol",{},[533,534,535,538],"li",{},[36,536,537],{},"5秒间隔","：这个时间间隔是经过实践验证的。太短会增加服务器压力，太长会影响用户体验。",[533,540,541,544],{},[36,542,543],{},"错误处理","：即使某次请求失败，也不会影响后续的轮询，系统会继续尝试。",[533,546,547,550],{},[36,548,549],{},"内存管理","：在组件卸载时会清理定时器，避免内存泄漏。",[21,552,554],{"id":553},"二卡片式布局设备状态的合理展示","二、卡片式布局：设备状态的合理展示",[26,556,557],{"id":557},"设计理念",[10,559,560],{},"监控界面最重要的就是信息清晰易读：关键信息明确，详细数据可查。我们采用卡片式设计，每个充电桩一张卡片，每个充电枪一个状态点。",[10,562,563],{},"这种设计有几个好处：",[10,565,566,569,570,573,576,577,579,582],{},[36,567,568],{},"信息层次清晰","：充电桩→枪，层级分明",[571,572],"br",{},[36,574,575],{},"状态一目了然","：通过颜色，快速识别充电状态",[571,578],{},[36,580,581],{},"操作便捷","：点击枪即可查看详情",[26,584,585],{"id":585},"实现代码解析",[59,587,591],{"className":588,"code":589,"language":590,"meta":64,"style":64},"language-html shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","\u003Cview v-if=\"stationId\" class=\"p-2 flex flex-wrap gap-2\">\n  \u003Cview v-for=\"e in equipmentList\" :key=\"e.equipmentId\" class=\"pile-card\">\n    \u003Cview class=\"pile-title\">{{ e.equipmentName || e.equipmentId }}\u003C\u002Fview>\n    \u003Cview class=\"gun-grid\">\n      \u003Cview\n        v-for=\"(connector, index) in e.connectorList\"\n        :key=\"index\"\n        class=\"gun-item\"\n        @click=\"gunCard(connector, e)\"\n      >\n        \u003Cview class=\"status-indicator\">\n          \u003Cview class=\"status-dot\" :class=\"['status-' + connector.connectorStatus]\">\n            \u003Ctext v-if=\"connector.connectorStatus == 3\">{{ connector.soc * 100 }}\u003C\u002Ftext>\n          \u003C\u002Fview>\n        \u003C\u002Fview>\n        \u003Cview class=\"gun-name\">\n          {{ connector.connectorName || connector.connectorId.slice(-2) }}\n        \u003C\u002Fview>\n      \u003C\u002Fview>\n    \u003C\u002Fview>\n  \u003C\u002Fview>\n\u003C\u002Fview>\n\n","html",[66,592,593,627,671,701,720,728,743,757,771,785,790,810,842,872,881,890,909,914,922,931,940,949],{"__ignoreMap":64},[69,594,595,597,600,603,605,608,610,612,615,617,619,622,624],{"class":71,"line":72},[69,596,117],{"class":83},[69,598,599],{"class":214},"view",[69,601,602],{"class":75}," v-if",[69,604,84],{"class":83},[69,606,607],{"class":83},"\"",[69,609,241],{"class":365},[69,611,607],{"class":83},[69,613,614],{"class":75}," class",[69,616,84],{"class":83},[69,618,607],{"class":83},[69,620,621],{"class":365},"p-2 flex flex-wrap gap-2",[69,623,607],{"class":83},[69,625,626],{"class":83},">\n",[69,628,629,632,634,637,639,641,644,646,649,651,653,656,658,660,662,664,667,669],{"class":71,"line":105},[69,630,631],{"class":83},"  \u003C",[69,633,599],{"class":214},[69,635,636],{"class":75}," v-for",[69,638,84],{"class":83},[69,640,607],{"class":83},[69,642,643],{"class":365},"e in equipmentList",[69,645,607],{"class":83},[69,647,648],{"class":75}," :key",[69,650,84],{"class":83},[69,652,607],{"class":83},[69,654,655],{"class":365},"e.equipmentId",[69,657,607],{"class":83},[69,659,614],{"class":75},[69,661,84],{"class":83},[69,663,607],{"class":83},[69,665,666],{"class":365},"pile-card",[69,668,607],{"class":83},[69,670,626],{"class":83},[69,672,673,676,678,680,682,684,687,689,691,694,697,699],{"class":71,"line":135},[69,674,675],{"class":83},"    \u003C",[69,677,599],{"class":214},[69,679,614],{"class":75},[69,681,84],{"class":83},[69,683,607],{"class":83},[69,685,686],{"class":365},"pile-title",[69,688,607],{"class":83},[69,690,124],{"class":83},[69,692,693],{"class":79},"{{ e.equipmentName || e.equipmentId }}",[69,695,696],{"class":83},"\u003C\u002F",[69,698,599],{"class":214},[69,700,626],{"class":83},[69,702,703,705,707,709,711,713,716,718],{"class":71,"line":154},[69,704,675],{"class":83},[69,706,599],{"class":214},[69,708,614],{"class":75},[69,710,84],{"class":83},[69,712,607],{"class":83},[69,714,715],{"class":365},"gun-grid",[69,717,607],{"class":83},[69,719,626],{"class":83},[69,721,722,725],{"class":71,"line":161},[69,723,724],{"class":83},"      \u003C",[69,726,727],{"class":214},"view\n",[69,729,730,733,735,737,740],{"class":71,"line":167},[69,731,732],{"class":75},"        v-for",[69,734,84],{"class":83},[69,736,607],{"class":83},[69,738,739],{"class":365},"(connector, index) in e.connectorList",[69,741,742],{"class":83},"\"\n",[69,744,745,748,750,752,755],{"class":71,"line":186},[69,746,747],{"class":75},"        :key",[69,749,84],{"class":83},[69,751,607],{"class":83},[69,753,754],{"class":365},"index",[69,756,742],{"class":83},[69,758,759,762,764,766,769],{"class":71,"line":208},[69,760,761],{"class":75},"        class",[69,763,84],{"class":83},[69,765,607],{"class":83},[69,767,768],{"class":365},"gun-item",[69,770,742],{"class":83},[69,772,773,776,778,780,783],{"class":71,"line":228},[69,774,775],{"class":75},"        @click",[69,777,84],{"class":83},[69,779,607],{"class":83},[69,781,782],{"class":365},"gunCard(connector, e)",[69,784,742],{"class":83},[69,786,787],{"class":71,"line":253},[69,788,789],{"class":83},"      >\n",[69,791,792,795,797,799,801,803,806,808],{"class":71,"line":258},[69,793,794],{"class":83},"        \u003C",[69,796,599],{"class":214},[69,798,614],{"class":75},[69,800,84],{"class":83},[69,802,607],{"class":83},[69,804,805],{"class":365},"status-indicator",[69,807,607],{"class":83},[69,809,626],{"class":83},[69,811,812,815,817,819,821,823,826,828,831,833,835,838,840],{"class":71,"line":266},[69,813,814],{"class":83},"          \u003C",[69,816,599],{"class":214},[69,818,614],{"class":75},[69,820,84],{"class":83},[69,822,607],{"class":83},[69,824,825],{"class":365},"status-dot",[69,827,607],{"class":83},[69,829,830],{"class":75}," :class",[69,832,84],{"class":83},[69,834,607],{"class":83},[69,836,837],{"class":365},"['status-' + connector.connectorStatus]",[69,839,607],{"class":83},[69,841,626],{"class":83},[69,843,844,847,850,852,854,856,859,861,863,866,868,870],{"class":71,"line":294},[69,845,846],{"class":83},"            \u003C",[69,848,849],{"class":214},"text",[69,851,602],{"class":75},[69,853,84],{"class":83},[69,855,607],{"class":83},[69,857,858],{"class":365},"connector.connectorStatus == 3",[69,860,607],{"class":83},[69,862,124],{"class":83},[69,864,865],{"class":79},"{{ connector.soc * 100 }}",[69,867,696],{"class":83},[69,869,849],{"class":214},[69,871,626],{"class":83},[69,873,874,877,879],{"class":71,"line":318},[69,875,876],{"class":83},"          \u003C\u002F",[69,878,599],{"class":214},[69,880,626],{"class":83},[69,882,883,886,888],{"class":71,"line":337},[69,884,885],{"class":83},"        \u003C\u002F",[69,887,599],{"class":214},[69,889,626],{"class":83},[69,891,892,894,896,898,900,902,905,907],{"class":71,"line":373},[69,893,794],{"class":83},[69,895,599],{"class":214},[69,897,614],{"class":75},[69,899,84],{"class":83},[69,901,607],{"class":83},[69,903,904],{"class":365},"gun-name",[69,906,607],{"class":83},[69,908,626],{"class":83},[69,910,911],{"class":71,"line":378},[69,912,913],{"class":79},"          {{ connector.connectorName || connector.connectorId.slice(-2) }}\n",[69,915,916,918,920],{"class":71,"line":401},[69,917,885],{"class":83},[69,919,599],{"class":214},[69,921,626],{"class":83},[69,923,924,927,929],{"class":71,"line":410},[69,925,926],{"class":83},"      \u003C\u002F",[69,928,599],{"class":214},[69,930,626],{"class":83},[69,932,933,936,938],{"class":71,"line":425},[69,934,935],{"class":83},"    \u003C\u002F",[69,937,599],{"class":214},[69,939,626],{"class":83},[69,941,942,945,947],{"class":71,"line":444},[69,943,944],{"class":83},"  \u003C\u002F",[69,946,599],{"class":214},[69,948,626],{"class":83},[69,950,951,953,955],{"class":71,"line":461},[69,952,696],{"class":83},[69,954,599],{"class":214},[69,956,626],{"class":83},[10,958,959],{},[36,960,961],{},"技术要点：",[530,963,964,970,980],{},[533,965,966,969],{},[36,967,968],{},"条件渲染","：只有选择了站点才显示设备列表，避免不必要的渲染。",[533,971,972,975,976,979],{},[36,973,974],{},"动态样式","：通过",[66,977,978],{},":class","绑定状态类，实现颜色动态变化。",[533,981,982,985],{},[36,983,984],{},"事件处理","：点击枪位触发详情展示，交互自然。",[26,987,988],{"id":988},"状态颜色系统",[10,990,991],{},"状态颜色采用类似信号灯的颜色，减少认知成本：",[59,993,997],{"className":994,"code":995,"language":996,"meta":64,"style":64},"language-css shiki shiki-themes material-theme-lighter material-theme material-theme-palenight",".status-0 { background-color: #999 !important; }     \u002F\u002F 离线\n.status-1 { background-color: #07c160 !important; }  \u002F\u002F 空闲\n.status-2 { background-color: #239ad8 !important; }  \u002F\u002F 插枪\n.status-3 { background-color: #0066ff !important; }  \u002F\u002F 充电中\n.status-4 { background-color: #ff9900 !important; }  \u002F\u002F 已锁定\n.status-255 { background-color: #ff0000 !important; } \u002F\u002F 故障\n\n","css",[66,998,999,1034,1061,1088,1115,1142],{"__ignoreMap":64},[69,1000,1001,1003,1006,1009,1013,1016,1019,1022,1025,1028,1031],{"class":71,"line":72},[69,1002,220],{"class":83},[69,1004,1005],{"class":120},"status-0",[69,1007,1008],{"class":83}," {",[69,1010,1012],{"class":1011},"sqsOY"," background-color",[69,1014,1015],{"class":83},":",[69,1017,1018],{"class":83}," #",[69,1020,1021],{"class":79},"999 ",[69,1023,1024],{"class":94},"!important",[69,1026,1027],{"class":83},";",[69,1029,1030],{"class":83}," }",[69,1032,1033],{"class":79},"     \u002F\u002F 离线\n",[69,1035,1036,1038,1041,1043,1045,1047,1049,1052,1054,1056,1058],{"class":71,"line":105},[69,1037,220],{"class":83},[69,1039,1040],{"class":120},"status-1",[69,1042,1008],{"class":83},[69,1044,1012],{"class":1011},[69,1046,1015],{"class":83},[69,1048,1018],{"class":83},[69,1050,1051],{"class":79},"07c160 ",[69,1053,1024],{"class":94},[69,1055,1027],{"class":83},[69,1057,1030],{"class":83},[69,1059,1060],{"class":79},"  \u002F\u002F 空闲\n",[69,1062,1063,1065,1068,1070,1072,1074,1076,1079,1081,1083,1085],{"class":71,"line":135},[69,1064,220],{"class":83},[69,1066,1067],{"class":120},"status-2",[69,1069,1008],{"class":83},[69,1071,1012],{"class":1011},[69,1073,1015],{"class":83},[69,1075,1018],{"class":83},[69,1077,1078],{"class":79},"239ad8 ",[69,1080,1024],{"class":94},[69,1082,1027],{"class":83},[69,1084,1030],{"class":83},[69,1086,1087],{"class":79},"  \u002F\u002F 插枪\n",[69,1089,1090,1092,1095,1097,1099,1101,1103,1106,1108,1110,1112],{"class":71,"line":154},[69,1091,220],{"class":83},[69,1093,1094],{"class":120},"status-3",[69,1096,1008],{"class":83},[69,1098,1012],{"class":1011},[69,1100,1015],{"class":83},[69,1102,1018],{"class":83},[69,1104,1105],{"class":79},"0066ff ",[69,1107,1024],{"class":94},[69,1109,1027],{"class":83},[69,1111,1030],{"class":83},[69,1113,1114],{"class":79},"  \u002F\u002F 充电中\n",[69,1116,1117,1119,1122,1124,1126,1128,1130,1133,1135,1137,1139],{"class":71,"line":161},[69,1118,220],{"class":83},[69,1120,1121],{"class":120},"status-4",[69,1123,1008],{"class":83},[69,1125,1012],{"class":1011},[69,1127,1015],{"class":83},[69,1129,1018],{"class":83},[69,1131,1132],{"class":79},"ff9900 ",[69,1134,1024],{"class":94},[69,1136,1027],{"class":83},[69,1138,1030],{"class":83},[69,1140,1141],{"class":79},"  \u002F\u002F 已锁定\n",[69,1143,1144,1146,1149,1151,1153,1155,1157,1160,1162,1164,1166],{"class":71,"line":167},[69,1145,220],{"class":83},[69,1147,1148],{"class":120},"status-255",[69,1150,1008],{"class":83},[69,1152,1012],{"class":1011},[69,1154,1015],{"class":83},[69,1156,1018],{"class":83},[69,1158,1159],{"class":79},"ff0000 ",[69,1161,1024],{"class":94},[69,1163,1027],{"class":83},[69,1165,1030],{"class":83},[69,1167,1168],{"class":79}," \u002F\u002F 故障\n",[10,1170,1171],{},"这种颜色编码让运维人员能够快速识别问题设备，提高工作效率。",[21,1173,1175],{"id":1174},"三浮动面板优雅的交互设计","三、浮动面板：优雅的交互设计",[10,1177,1178],{},[16,1179],{"alt":1180,"src":1181},"界面","https:\u002F\u002Fucode-orise.oss-cn-beijing.aliyuncs.com\u002Fwebsite\u002Farticle\u002F4\u002F2.png",[26,1183,1184],{"id":1184},"设计思考",[10,1186,1187],{},"浮动面板是移动端一种典型的交互模式。它的优势在于：",[10,1189,1190,1193,1194,1196,1199,1200,1202,1205],{},[36,1191,1192],{},"不需要跳转","：查看详情时，不需要跳转页面，可以快速切换节点；",[571,1195],{},[36,1197,1198],{},"操作自然","：从底部滑出符合用户手势习惯；",[571,1201],{},[36,1203,1204],{},"信息分层","：概览和详情分离，界面清爽。",[26,1207,1208],{"id":1208},"技术实现",[59,1210,1212],{"className":588,"code":1211,"language":590,"meta":64,"style":64},"\u003Cwd-floating-panel\n  v-if=\"selectedConnector.connectorId\"\n  v-model:height=\"height\"\n  :anchors=\"anchors\"\n  safeAreaInsetBottom\n  custom-class=\"bg-page\"\n>\n  \u003CConnectorDetail :connector=\"selectedConnector\" \u002F>\n\u003C\u002Fwd-floating-panel>\n\n",[66,1213,1214,1221,1235,1249,1263,1268,1282,1286,1308],{"__ignoreMap":64},[69,1215,1216,1218],{"class":71,"line":72},[69,1217,117],{"class":83},[69,1219,1220],{"class":214},"wd-floating-panel\n",[69,1222,1223,1226,1228,1230,1233],{"class":71,"line":105},[69,1224,1225],{"class":75},"  v-if",[69,1227,84],{"class":83},[69,1229,607],{"class":83},[69,1231,1232],{"class":365},"selectedConnector.connectorId",[69,1234,742],{"class":83},[69,1236,1237,1240,1242,1244,1247],{"class":71,"line":135},[69,1238,1239],{"class":75},"  v-model:height",[69,1241,84],{"class":83},[69,1243,607],{"class":83},[69,1245,1246],{"class":365},"height",[69,1248,742],{"class":83},[69,1250,1251,1254,1256,1258,1261],{"class":71,"line":154},[69,1252,1253],{"class":75},"  :anchors",[69,1255,84],{"class":83},[69,1257,607],{"class":83},[69,1259,1260],{"class":365},"anchors",[69,1262,742],{"class":83},[69,1264,1265],{"class":71,"line":161},[69,1266,1267],{"class":75},"  safeAreaInsetBottom\n",[69,1269,1270,1273,1275,1277,1280],{"class":71,"line":167},[69,1271,1272],{"class":75},"  custom-class",[69,1274,84],{"class":83},[69,1276,607],{"class":83},[69,1278,1279],{"class":365},"bg-page",[69,1281,742],{"class":83},[69,1283,1284],{"class":71,"line":186},[69,1285,626],{"class":83},[69,1287,1288,1290,1293,1296,1298,1300,1303,1305],{"class":71,"line":208},[69,1289,631],{"class":83},[69,1291,1292],{"class":214},"ConnectorDetail",[69,1294,1295],{"class":75}," :connector",[69,1297,84],{"class":83},[69,1299,607],{"class":83},[69,1301,1302],{"class":365},"selectedConnector",[69,1304,607],{"class":83},[69,1306,1307],{"class":83}," \u002F>\n",[69,1309,1310,1312,1315],{"class":71,"line":228},[69,1311,696],{"class":83},[69,1313,1314],{"class":214},"wd-floating-panel",[69,1316,626],{"class":83},[10,1318,1319],{},[36,1320,1321],{},"关键参数说明：",[1323,1324,1325,1331,1337],"ul",{},[533,1326,1327,1330],{},[66,1328,1329],{},"v-model:height","：双向绑定面板高度，实现拖动调节",[533,1332,1333,1336],{},[66,1334,1335],{},":anchors","：预设停靠点，提供标准的交互体验",[533,1338,1339,1342],{},[66,1340,1341],{},"safeAreaInsetBottom","：适配全面屏设备的安全区域",[26,1344,1345],{"id":1345},"停靠点设置",[59,1347,1349],{"className":61,"code":1348,"language":63,"meta":64,"style":64},"onMounted(() => {\n  windowHeight.value = uni.getSystemInfoSync().windowHeight\n  anchors.value = [150, Math.round(0.4 * windowHeight.value), Math.round(1 * windowHeight.value)]\n  height.value = anchors.value[0]\n})\n\n",[66,1350,1351,1364,1390,1460,1487],{"__ignoreMap":64},[69,1352,1353,1356,1358,1360,1362],{"class":71,"line":72},[69,1354,1355],{"class":87},"onMounted",[69,1357,91],{"class":79},[69,1359,352],{"class":83},[69,1361,202],{"class":75},[69,1363,205],{"class":83},[69,1365,1366,1369,1371,1373,1375,1378,1380,1383,1385,1387],{"class":71,"line":105},[69,1367,1368],{"class":79},"  windowHeight",[69,1370,220],{"class":83},[69,1372,223],{"class":79},[69,1374,275],{"class":83},[69,1376,1377],{"class":79}," uni",[69,1379,220],{"class":83},[69,1381,1382],{"class":87},"getSystemInfoSync",[69,1384,352],{"class":214},[69,1386,220],{"class":83},[69,1388,1389],{"class":79},"windowHeight\n",[69,1391,1392,1395,1397,1399,1401,1404,1407,1410,1413,1415,1418,1420,1423,1426,1429,1431,1433,1436,1438,1440,1442,1444,1446,1449,1451,1453,1455,1457],{"class":71,"line":135},[69,1393,1394],{"class":79},"  anchors",[69,1396,220],{"class":83},[69,1398,223],{"class":79},[69,1400,275],{"class":83},[69,1402,1403],{"class":214}," [",[69,1405,1406],{"class":94},"150",[69,1408,1409],{"class":83},",",[69,1411,1412],{"class":79}," Math",[69,1414,220],{"class":83},[69,1416,1417],{"class":87},"round",[69,1419,91],{"class":214},[69,1421,1422],{"class":94},"0.4",[69,1424,1425],{"class":83}," *",[69,1427,1428],{"class":79}," windowHeight",[69,1430,220],{"class":83},[69,1432,223],{"class":79},[69,1434,1435],{"class":214},")",[69,1437,1409],{"class":83},[69,1439,1412],{"class":79},[69,1441,220],{"class":83},[69,1443,1417],{"class":87},[69,1445,91],{"class":214},[69,1447,1448],{"class":94},"1",[69,1450,1425],{"class":83},[69,1452,1428],{"class":79},[69,1454,220],{"class":83},[69,1456,223],{"class":79},[69,1458,1459],{"class":214},")]\n",[69,1461,1462,1465,1467,1469,1471,1474,1476,1478,1481,1484],{"class":71,"line":154},[69,1463,1464],{"class":79},"  height",[69,1466,220],{"class":83},[69,1468,223],{"class":79},[69,1470,275],{"class":83},[69,1472,1473],{"class":79}," anchors",[69,1475,220],{"class":83},[69,1477,223],{"class":79},[69,1479,1480],{"class":214},"[",[69,1482,1483],{"class":94},"0",[69,1485,1486],{"class":214},"]\n",[69,1488,1489,1491],{"class":71,"line":161},[69,1490,521],{"class":83},[69,1492,132],{"class":79},[10,1494,1495],{},"这里设置了三个停靠位置：",[530,1497,1498,1501,1504],{},[533,1499,1500],{},"最小高度，可看到枪的当前信息；",[533,1502,1503],{},"40%高度，可显示出统计信息与最近的几条日志；",[533,1505,1506],{},"全屏显示完整信息，底部可再点击“更多日志”，查看完整设备日志进行问题排查。",[10,1508,1509],{},"这种设计可以让用户根据需要自由调节。",[21,1511,1513],{"id":1512},"四总结","四、总结",[10,1515,1516],{},"这个实时监控系统的设计体现了几个重要的工程原则：",[530,1518,1519,1525,1531],{},[533,1520,1521,1524],{},[36,1522,1523],{},"适用性","：根据功能需要来选择技术实现方式，够用就好。",[533,1526,1527,1530],{},[36,1528,1529],{},"简化信息","：通过信息灯颜色、浮动面板等设计，让复杂的信息变得直观易懂。",[533,1532,1533,1536],{},[36,1534,1535],{},"性能考虑","：请求频率以及定时器清理，做好性能与内存的管理优化。",[10,1538,1539],{},"这种设计思路不仅适用于充电桩监控，对于任何需要实时状态监控的系统都有很好的参考价值。",[1541,1542,1543],"style",{},"html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sqsOY, html code.shiki .sqsOY{--shiki-light:#8796B0;--shiki-default:#B2CCD6;--shiki-dark:#B2CCD6}",{"title":64,"searchDepth":105,"depth":105,"links":1545},[1546,1547,1548,1549],{"id":23,"depth":135,"text":24},{"id":553,"depth":135,"text":554},{"id":1174,"depth":135,"text":1175},{"id":1512,"depth":135,"text":1513},"技术解析","2026-01-09","md",{},"\u002Finsights\u002F4",{"title":5,"description":12},"4","insights\u002F4","适用性：根据功能需要来选择技术实现方式，够用就好。简化信息：通过信息灯颜色、浮动面板等设计，让复杂的信息变得直观易懂。性能考虑：请求频率以及定时器清理，做好性能与内存的管理优化。这种设计思路不仅适用于充电桩监控，对于任何需要实时状态监控的系统都有很好的参考价值，希望本次分享能够启用到你。","01SVjDEwbfTXdUfmpCU9dQEOaWPbEbYPBB7j9VXSdc4",1789965847348]