You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
|
|
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Document</title> <style> *, html, body { margin: 0; padding: 0; box-sizing: border-box; } .container { display: flex; width: 100vw; align-items: center; box-sizing: border-box; justify-content: space-between; } .left_chat { border: solid 1px #000; height: 100vh; display: flex; box-sizing: border-box; flex-direction: column; flex: 0.6; padding: 24px; overflow: scroll; } .right_message { height: 100vh; box-sizing: border-box; flex: 1; } .btn { padding: 36px; font-size: 24px; margin-top: 24px; width: 100%; } .right_message { padding: 24px; border: solid 1px #000; display: flex; flex-direction: column; } .message_wrap { flex: 1; border: solid 1px #ddd; overflow: scroll; } .message { padding: 6px 8px; border-bottom: solid 1px #ddd; } .input_wrap { display: flex; align-items: center; /* margin-bottom: 20px; */ } .input_wrap .ws_connnect { flex: 2; padding: 4px 0; margin-right: 20px; } .input_wrap .connect { flex: 1; } .order { display: grid; grid-template-columns: repeat(1, 1fr); column-gap: 20px; row-gap: 10px; margin-bottom: 20px; } .status { padding: 4px 0; } .tabs { margin: 20px 0; }
.tab-bar { display: flex; }
.tab { padding: 10px 20px; border: 1px solid #ccc; border-bottom: none; cursor: pointer; }
.active { border-bottom: 2px solid blue; }
.tab-panel { display: none; padding: 20px; border: 1px solid #ccc; }
.active { display: block; }
.common_order_input { display: flex; align-items: center; justify-content: space-evenly; padding: 0 20px; margin-bottom: 10px; } .common_order_input .single { display: flex; flex-direction: column; align-items: center; } .single .input { width: 100%; text-align: center; padding: 4px; } .common_btns { width: 100%; } .btn_c { width: 100%; padding: 4px 0; margin-bottom: 10px; } .report_c { border: solid 1px #ddd; padding: 10px; } .form_line { display: flex; align-items: center; width: 100%; margin-bottom: 10px; } .form_line .tit { margin-right: 6px; white-space: nowrap; } .form_line .info { width: 100%; text-align: center; padding: 4px 0; } .report_c .title { border-bottom: solid 1px #ddd; margin-bottom: 10px; } </style> </head> <body> <div class="container"> <div class="left_chat"> <div class="input_wrap"> <input type="text" class="ws_connnect" id="ws_connnect_input" /> <button class="connect" onclick="connectWs()">连接</button> </div> <p class="status" id="status">当前状态: 未连接</p> <div class="report_c"> <p class="title">上报解析</p> <div class="form_line"> <p class="tit">ADDRESS:</p> <input type="text" class="info" disabled id="report_address" /> </div> <div class="form_line"> <p class="tit">VALUE:</p> <input type="text" class="info" disabled id="report_val" /> </div> </div> <div class="report_c"> <p class="title">回执解析</p> <div class="form_line"> <p class="tit">ADDRESS:</p> <input type="text" class="info" disabled id="receipt_address" /> </div> <div class="form_line"> <p class="tit">VALUE:</p> <input type="text" class="info" disabled id="receipt_val" /> </div> <div class="form_line"> <p class="tit">结果:</p> <input type="text" class="info" value="无" disabled id="receipt_message" /> </div> </div> <div class="tabs"> <ul class="tab-bar"> <li class="tab active">通用指令</li> <li class="tab">指令列表</li> </ul> <div class="tab-content"> <div class="tab-panel active"> <div class="common_order_input"> <div class="single"> <p>ID</p> <input type="text" class="input" id="common_id" /> </div> <div class="single" style="margin-left: 10px; margin-right: 5px" > <p>BASE</p> <input type="text" class="input" id="common_base" /> </div> <div class="single" style="margin-left: 5px; margin-right: 10px" > <p>OFFSET</p> <input type="text" class="input" id="common_off" /> </div> <div class="single"> <p>VALUE</p> <input type="text" class="input" id="common_value" /> </div> </div> <div class="common_btns"> <button class="btn_c" onclick="writeFun()">写</button> <button class="btn_c" onclick="read()">读</button> <button class="btn_c" onclick="autoReport()"> 使能自动上报 </button> <button class="btn_c" onclick="reportCycle()"> 设置上报周期 </button> </div> </div> <div class="tab-panel"> <div class="order" id="order"></div> </div> </div> </div> </div> <div class="right_message"> <div class="message_wrap" id="message_wrap"></div> <div style="display: flex; align-items: center; margin-top: 10px"> <textarea style="flex: 1" name="bio" rows="15" cols="40"></textarea> <div style="display: flex; flex-direction: column; height: 100%"> <button style="flex: 1" onclick="sendMessage()">发送</button> <button style="flex: 1" onclick="clearTextArea()">清空</button> </div> </div> </div> </div> </body> <script src="./config.js"></script> <script> window.onload = () => { const commonI = document.querySelector("#common_id"); const commonB = document.querySelector("#common_base"); commonI.value = localStorage.getItem("id"); commonB.value = localStorage.getItem("base"); }; var ws = null; const websocketInput = document.querySelector("#ws_connnect_input"); websocketInput.value = websocketAddress; // 先向order下动态添加指令集合 const order = document.querySelector("#order");
for (let key in config) { const button = document.createElement("button"); button.textContent = key; button.className = "order_btn"; button.setAttribute("v", key); order?.appendChild(button); }
order.addEventListener("click", (e) => { const item = e.target; if (item && item.getAttribute("v")) { const key = item.getAttribute("v"); sendOrder(config[key]); } });
const commonI = document.querySelector("#common_id"); const commonB = document.querySelector("#common_base"); commonI.addEventListener("input", (e) => { localStorage.setItem("id", e.target.value); }); commonB.addEventListener("input", (e) => { localStorage.setItem("base", e.target.value); });
const tabs = document.querySelector(".tabs"); const tabBars = document.querySelectorAll(".tab-bar .tab"); const tabPanels = document.querySelectorAll(".tab-content .tab-panel");
for (let i = 0; i < tabBars.length; i++) { tabBars[i].onclick = function () { removeActive(); this.classList.add("active"); tabPanels[i].classList.add("active"); }; }
function removeActive() { for (let i = 0; i < tabBars.length; i++) { tabBars[i].classList.remove("active"); tabPanels[i].classList.remove("active"); } } const clearMessage = () => { const messageWrap = document.querySelector("#message_wrap"); messageWrap.innerHTML = ""; }; const clearTextArea = () => { const textArea = document.querySelector("textarea"); textArea.value = ""; clearMessage(); }; const sendMessage = () => { if (ws) { const textArea = document.querySelector("textarea"); const messageVal = textArea.value; ws.send(messageVal); const messageWrap = document.querySelector("#message_wrap"); const div = document.createElement("div"); div.classList = ["message"]; div.textContent = `Tx: ${messageVal}`; messageWrap.appendChild(div); messageWrap.scrollTop = messageWrap.scrollHeight - messageWrap.clientHeight; } else { } }; const connectWs = () => { const input = document.querySelector("#ws_connnect_input"); const status = document.querySelector("#status"); const address = input.value; try { ws = new WebSocket(address); ws.onopen = function () { console.log("Connected to WebSocket server."); // 改变状态 status.innerHTML = `当前状态: 已连接${address}`; };
ws.onmessage = function (evt) { console.log(evt.data); const messageWrap = document.querySelector("#message_wrap"); const div = document.createElement("div"); div.classList = ["message"]; div.textContent = `Rx: ${evt.data}`; messageWrap.appendChild(div); messageWrap.scrollTop = messageWrap.scrollHeight - messageWrap.clientHeight; // 对消息进行处理 try { const messageBody = JSON.parse(evt.data); const { type, ctrlPointAddr, ctrlPointVal } = messageBody; const receiptMessage = document.querySelector("#receipt_message"); const receiptAddress = document.querySelector("#receipt_address"); const receiptVal = document.querySelector("#receipt_val"); const reportAddress = document.querySelector("#report_address"); const reportVal = document.querySelector("#report_val"); if (type == "receipt") { receiptMessage.value = "正确"; receiptAddress.value = ctrlPointAddr; receiptVal.value = ctrlPointVal; } if (type == "error_receipt") { receiptMessage.value = "错误"; receiptAddress.value = ctrlPointAddr; receiptVal.value = ctrlPointVal; } if (type == "report") { reportAddress.value = ctrlPointAddr; reportVal.value = ctrlPointVal; } } catch (error) {} };
ws.onclose = function () { status.innerHTML = `当前状态: 已关闭`; }; } catch (error) { status.innerHTML = `当前状态: 连接错误`; } }; const sendOrder = (msg) => { if (ws) { ws.send(msg); const messageWrap = document.querySelector("#message_wrap"); const div = document.createElement("div"); div.classList = ["message"]; div.textContent = `Tx: ${msg}`; messageWrap.appendChild(div); messageWrap.scrollTop = messageWrap.scrollHeight - messageWrap.clientHeight; } };
const getCommonOrderInput = (type) => { const id = document.querySelector("#common_id"); const base = document.querySelector("#common_base"); const off = document.querySelector("#common_off"); const value = document.querySelector("#common_value"); const { protocol, message } = commonMessage; return JSON.stringify({ protocol, message: { ...message, targetId: id.value, ctrlPointAddr: base.value + off.value, ctrlPointVal: value.value, type, }, }); };
const writeFun = () => { const msg = getCommonOrderInput("write"); sendOrder(msg); }; const read = () => { const msg = getCommonOrderInput("read"); sendOrder(msg); }; const autoReport = () => { const msg = getCommonOrderInput("set_auto_report_enable_flag"); sendOrder(msg); }; const reportCycle = () => { const msg = getCommonOrderInput("set_auto_report_period"); sendOrder(msg); }; </script> </html>
|