feat(fullscreen, UI), reformat code
- add ws binary message communication (not stable) - reformat ws: move ws text/bin packing code to msgRouter - reformat api: centralize module ID
This commit is contained in:
parent
275f3ac859
commit
c2b8f6ba09
|
@ -1,3 +1,3 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
export VITE_APP_GIT_TAG=$(git describe --tags)
|
export VITE_APP_GIT_TAG=$(git describe --tags | cut -d'-' -f1,2)
|
||||||
export VITE_APP_LAST_COMMIT=$(git log -1 --format=%cd)
|
export VITE_APP_LAST_COMMIT=$(git log -1 --format=%cd)
|
|
@ -40,7 +40,7 @@ onMounted(() => {
|
||||||
logHelloMessage();
|
logHelloMessage();
|
||||||
let host = "";
|
let host = "";
|
||||||
if (isDevMode()) {
|
if (isDevMode()) {
|
||||||
host = import.meta.env.VITE_DEVICE_HOST_NAME;
|
host = import.meta.env.VITE_DEVICE_HOST_NAME || "dap.local";
|
||||||
} else {
|
} else {
|
||||||
host = window.location.host
|
host = window.location.host
|
||||||
}
|
}
|
||||||
|
@ -55,8 +55,10 @@ onUnmounted(() => {
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
<div class="flex flex-col h-screen">
|
||||||
<header>
|
<header>
|
||||||
<nav-bar/>
|
<nav-bar/>
|
||||||
</header>
|
</header>
|
||||||
<RouterView/>
|
<RouterView/>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
import {type ApiJsonMsg, sendJsonMsg} from '@/api'
|
import {type ApiJsonMsg, sendJsonMsg, WtModuleID} from '@/api'
|
||||||
|
|
||||||
export const WifiModuleID = 1;
|
|
||||||
export enum WifiCmd {
|
export enum WifiCmd {
|
||||||
UNKNOWN = 0,
|
UNKNOWN = 0,
|
||||||
WIFI_API_JSON_STA_GET_AP_INFO,
|
WIFI_API_JSON_STA_GET_AP_INFO,
|
||||||
|
@ -17,7 +16,7 @@ interface WifiMsgOut extends ApiJsonMsg {
|
||||||
|
|
||||||
export function wifi_get_scan_list() {
|
export function wifi_get_scan_list() {
|
||||||
const msg : WifiMsgOut = {
|
const msg : WifiMsgOut = {
|
||||||
module: WifiModuleID,
|
module: WtModuleID.WIFI,
|
||||||
cmd: WifiCmd.WIFI_API_JSON_GET_SCAN,
|
cmd: WifiCmd.WIFI_API_JSON_GET_SCAN,
|
||||||
}
|
}
|
||||||
sendJsonMsg(msg);
|
sendJsonMsg(msg);
|
||||||
|
@ -25,7 +24,7 @@ export function wifi_get_scan_list() {
|
||||||
|
|
||||||
export function wifi_sta_get_ap_info() {
|
export function wifi_sta_get_ap_info() {
|
||||||
const msg : WifiMsgOut = {
|
const msg : WifiMsgOut = {
|
||||||
module: WifiModuleID,
|
module: WtModuleID.WIFI,
|
||||||
cmd: WifiCmd.WIFI_API_JSON_STA_GET_AP_INFO,
|
cmd: WifiCmd.WIFI_API_JSON_STA_GET_AP_INFO,
|
||||||
}
|
}
|
||||||
sendJsonMsg(msg);
|
sendJsonMsg(msg);
|
||||||
|
@ -33,7 +32,7 @@ export function wifi_sta_get_ap_info() {
|
||||||
|
|
||||||
export function wifi_ap_get_info() {
|
export function wifi_ap_get_info() {
|
||||||
const msg : WifiMsgOut = {
|
const msg : WifiMsgOut = {
|
||||||
module: WifiModuleID,
|
module: WtModuleID.WIFI,
|
||||||
cmd: WifiCmd.WIFI_API_JSON_AP_GET_INFO,
|
cmd: WifiCmd.WIFI_API_JSON_AP_GET_INFO,
|
||||||
}
|
}
|
||||||
sendJsonMsg(msg);
|
sendJsonMsg(msg);
|
||||||
|
@ -41,7 +40,7 @@ export function wifi_ap_get_info() {
|
||||||
|
|
||||||
export function wifi_connect_to(ssid: string, password: string) {
|
export function wifi_connect_to(ssid: string, password: string) {
|
||||||
const msg: WifiMsgOut = {
|
const msg: WifiMsgOut = {
|
||||||
module: WifiModuleID,
|
module: WtModuleID.WIFI,
|
||||||
cmd: WifiCmd.WIFI_API_JSON_CONNECT,
|
cmd: WifiCmd.WIFI_API_JSON_CONNECT,
|
||||||
ssid: ssid,
|
ssid: ssid,
|
||||||
password: password,
|
password: password,
|
||||||
|
@ -59,6 +58,6 @@ export interface WifiInfo extends ApiJsonMsg {
|
||||||
wifiLogo?: string;
|
wifiLogo?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface WifiList {
|
export interface WifiList extends ApiJsonMsg {
|
||||||
scan_list: Array<WifiInfo>;
|
scan_list: Array<WifiInfo>;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,52 @@
|
||||||
|
import type {WtModuleID} from "@/api/index";
|
||||||
|
|
||||||
|
export enum WtDataType {
|
||||||
|
RESERVED = 0x00,
|
||||||
|
/* primitive type */
|
||||||
|
EVENT = 0x02,
|
||||||
|
ROUTE_HDR = 0x03,
|
||||||
|
RAW_BROADCAST = 0x04,
|
||||||
|
|
||||||
|
/* broadcast data */
|
||||||
|
CMD_BROADCAST = 0x11,
|
||||||
|
|
||||||
|
/* targeted data */
|
||||||
|
RAW = 0x20,
|
||||||
|
CMD = 0x21,
|
||||||
|
RESPONSE = 0x22,
|
||||||
|
|
||||||
|
/* standard protocols */
|
||||||
|
PROTOBUF = 0x40,
|
||||||
|
JSON = 0x41,
|
||||||
|
MQTT = 0x42,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export interface ApiBinaryMsg {
|
||||||
|
data_type: WtDataType,
|
||||||
|
module: WtModuleID,
|
||||||
|
sub_mod: number,
|
||||||
|
payload: Uint8Array;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function decodeHeader(arrayBuffer: ArrayBuffer) : ApiBinaryMsg {
|
||||||
|
// Create a DataView to access the data in the ArrayBuffer
|
||||||
|
const dataView = new DataView(arrayBuffer);
|
||||||
|
|
||||||
|
// Extract the data_type from the first byte
|
||||||
|
const data_type = dataView.getUint8(0) as WtDataType;
|
||||||
|
|
||||||
|
// Extract the module_id and sub_id from the next bytes
|
||||||
|
const module = dataView.getUint8(1);
|
||||||
|
const sub_mod = dataView.getUint8(2);
|
||||||
|
|
||||||
|
const payload = new Uint8Array(arrayBuffer.slice(4));
|
||||||
|
|
||||||
|
// Constructing the header object
|
||||||
|
return {
|
||||||
|
data_type,
|
||||||
|
module,
|
||||||
|
sub_mod,
|
||||||
|
payload,
|
||||||
|
};
|
||||||
|
}
|
|
@ -1,4 +1,5 @@
|
||||||
import {getWebsocketService} from "@/composables/websocket/websocketService";
|
import {getWebsocketService} from "@/composables/websocket/websocketService";
|
||||||
|
import type {ApiBinaryMsg} from "@/api/binDataDef";
|
||||||
|
|
||||||
export interface ApiJsonMsg {
|
export interface ApiJsonMsg {
|
||||||
module: number;
|
module: number;
|
||||||
|
@ -26,18 +27,34 @@ export interface ControlMsg {
|
||||||
|
|
||||||
export interface ServerMsg {
|
export interface ServerMsg {
|
||||||
type: "json" | "binary"
|
type: "json" | "binary"
|
||||||
data: ApiJsonMsg | object;
|
data: string | ArrayBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum WtModuleID {
|
||||||
|
WIFI = 1,
|
||||||
|
DATA_FLOW = 2,
|
||||||
|
UART = 4,
|
||||||
}
|
}
|
||||||
|
|
||||||
export function sendJsonMsg(apiJsonMsg: ApiJsonMsg) {
|
export function sendJsonMsg(apiJsonMsg: ApiJsonMsg) {
|
||||||
const msg: ServerMsg = {
|
const msg: ServerMsg = {
|
||||||
type: "json",
|
type: "json",
|
||||||
data: apiJsonMsg,
|
data: JSON.stringify(apiJsonMsg),
|
||||||
};
|
};
|
||||||
getWebsocketService().send(msg);
|
getWebsocketService().send(msg);
|
||||||
// toServer.postMessage(msg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function sendBinMsg(msg: ApiJsonMsg) {
|
export function sendBinMsg(binMsg: ApiBinaryMsg) {
|
||||||
// toServer.postMessage(JSON.stringify(msg));
|
const buffer = new Uint8Array(4 + binMsg.payload.length);
|
||||||
|
buffer[0] = binMsg.data_type;
|
||||||
|
buffer[1] = binMsg.module;
|
||||||
|
buffer[2] = binMsg.sub_mod;
|
||||||
|
buffer[3] = 0; // Reserved byte
|
||||||
|
buffer.set(binMsg.payload, 4); // Append payload after header
|
||||||
|
|
||||||
|
const msg: ServerMsg = {
|
||||||
|
type: "binary",
|
||||||
|
data: buffer,
|
||||||
|
};
|
||||||
|
getWebsocketService().send(msg);
|
||||||
}
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
.text-layout {
|
.text-layout {
|
||||||
@apply m-auto max-w-2xl min-w-min px-2
|
@apply mx-auto max-w-2xl w-full sm:min-w-[640px] px-2
|
||||||
}
|
}
|
||||||
|
|
||||||
.page-title {
|
.page-title {
|
||||||
|
@ -14,3 +14,8 @@
|
||||||
@apply text-blue-600 font-bold;
|
@apply text-blue-600 font-bold;
|
||||||
cursor: default;
|
cursor: default;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.el-checkbox:hover {
|
||||||
|
background-color: var(--el-color-primary-light-9);
|
||||||
|
border-color: var(--el-color-primary-light-8);
|
||||||
|
}
|
||||||
|
|
|
@ -80,26 +80,13 @@ class OneTimeWebsocket implements IWebsocket {
|
||||||
return
|
return
|
||||||
|
|
||||||
const msg: ServerMsg = {
|
const msg: ServerMsg = {
|
||||||
data: {},
|
data: ev.data,
|
||||||
type: "json",
|
type: "json",
|
||||||
}
|
}
|
||||||
if (typeof ev.data === "string") {
|
if (typeof ev.data === "string") {
|
||||||
try {
|
msg.type = "json"
|
||||||
msg.data = JSON.parse(ev.data) as ApiJsonMsg;
|
|
||||||
if ((msg.data as ApiJsonMsg).cmd === undefined ||
|
|
||||||
(msg.data as ApiJsonMsg).module === undefined
|
|
||||||
){
|
|
||||||
console.log("Server msg has no cmd or module");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
console.log(e);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
msg.type = "binary";
|
msg.type = "binary";
|
||||||
msg.data = ev.data;
|
|
||||||
console.log(typeof ev.data);
|
|
||||||
}
|
}
|
||||||
this.msgCallback(msg);
|
this.msgCallback(msg);
|
||||||
}
|
}
|
||||||
|
@ -150,11 +137,8 @@ class OneTimeWebsocket implements IWebsocket {
|
||||||
if (isDevMode()) {
|
if (isDevMode()) {
|
||||||
console.log('WebSocket proxies data ', msg);
|
console.log('WebSocket proxies data ', msg);
|
||||||
}
|
}
|
||||||
if (msg.type === "binary") {
|
|
||||||
// this.socket.send(msg.data);
|
this.socket.send(msg.data);
|
||||||
} else if (msg.type === "json") {
|
|
||||||
this.socket.send(JSON.stringify(msg.data));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
clear() {
|
clear() {
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
import type {ApiJsonMsg, ControlMsg, ServerMsg} from "@/api";
|
import type {ApiJsonMsg, ControlMsg, ServerMsg} from "@/api";
|
||||||
import {isDevMode} from "@/composables/buildMode";
|
import {isDevMode} from "@/composables/buildMode";
|
||||||
|
import {type ApiBinaryMsg, decodeHeader} from "@/api/binDataDef";
|
||||||
|
|
||||||
export interface IModuleCallback {
|
export interface IModuleCallback {
|
||||||
ctrlCallback: (msg: ControlMsg) => void;
|
ctrlCallback: (msg: ControlMsg) => void;
|
||||||
serverMsgCallback: (msg: ServerMsg) => void;
|
serverJsonMsgCallback: (msg: ApiJsonMsg) => void;
|
||||||
|
serverBinMsgCallback: (msg: ApiBinaryMsg) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
const moduleMap = new Map<number, IModuleCallback>();
|
const moduleMap = new Map<number, IModuleCallback>();
|
||||||
|
@ -22,19 +24,47 @@ export function unregisterModule(moduleId: number) {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function routeModuleServerMsg(msg: ServerMsg) {
|
export function routeModuleServerMsg(msg: ServerMsg) {
|
||||||
if (msg.type == "json") {
|
if (msg.type === "json") {
|
||||||
const module = (msg.data as ApiJsonMsg).module;
|
let jsonMsg: ApiJsonMsg;
|
||||||
|
try {
|
||||||
|
jsonMsg = JSON.parse(msg.data as string) as ApiJsonMsg;
|
||||||
|
if (jsonMsg.cmd === undefined ||
|
||||||
|
jsonMsg.module === undefined
|
||||||
|
){
|
||||||
|
console.log("Server msg has no cmd or module", msg.data);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.log(e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const module = jsonMsg.module;
|
||||||
const moduleHandler = moduleMap.get(module);
|
const moduleHandler = moduleMap.get(module);
|
||||||
if (moduleHandler) {
|
if (moduleHandler) {
|
||||||
moduleHandler.serverMsgCallback(msg);
|
moduleHandler.serverJsonMsgCallback(jsonMsg);
|
||||||
} else {
|
} else {
|
||||||
if (isDevMode()) {
|
if (isDevMode()) {
|
||||||
console.log("routeModuleServerMsg module not loaded", module);
|
console.log("routeModuleServerMsg module not loaded", module);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
const arr = msg.data as ArrayBuffer;
|
||||||
|
if (arr.byteLength < 4) {
|
||||||
if (isDevMode()) {
|
if (isDevMode()) {
|
||||||
console.log("routeModuleServerMsg ignored:", msg);
|
console.log("binary message too short");
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const binaryMsg = decodeHeader(msg.data as ArrayBuffer);
|
||||||
|
const moduleHandler = moduleMap.get(binaryMsg.module);
|
||||||
|
if (moduleHandler) {
|
||||||
|
moduleHandler.serverBinMsgCallback(binaryMsg);
|
||||||
|
} else {
|
||||||
|
if (isDevMode()) {
|
||||||
|
console.log("routeModuleServerMsg ignored:", msg, binaryMsg);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
const version = import.meta.env.VITE_APP_GIT_TAG;
|
const version = import.meta.env.VITE_APP_GIT_TAG || "v0.0.0";
|
||||||
const compileTime = import.meta.env.VITE_APP_LAST_COMMIT;
|
const compileTime = import.meta.env.VITE_APP_LAST_COMMIT || "1970-00-00";
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
@ -17,23 +17,23 @@ const compileTime = import.meta.env.VITE_APP_LAST_COMMIT;
|
||||||
</el-descriptions>
|
</el-descriptions>
|
||||||
|
|
||||||
<el-descriptions title="鸣谢" border :column="1" class="mt-5 description-style">
|
<el-descriptions title="鸣谢" border :column="1" class="mt-5 description-style">
|
||||||
<el-descriptions-item label="vuejs"><a href="https://github.com/vuejs/vue/blob/main/LICENSE">MIT</a>
|
<el-descriptions-item label="vuejs"><a target="_blank" href="https://github.com/vuejs/vue/blob/main/LICENSE">MIT</a>
|
||||||
</el-descriptions-item>
|
</el-descriptions-item>
|
||||||
<el-descriptions-item label="typescript"><a
|
<el-descriptions-item label="typescript"><a
|
||||||
href="https://github.com/microsoft/TypeScript/blob/main/LICENSE.txt">Apache 2.0</a></el-descriptions-item>
|
href="https://github.com/microsoft/TypeScript/blob/main/LICENSE.txt">Apache 2.0</a></el-descriptions-item>
|
||||||
<el-descriptions-item label="vite"><a href="https://github.com/vitejs/vite/blob/main/LICENSE">MIT</a>
|
<el-descriptions-item label="vite"><a target="_blank" href="https://github.com/vitejs/vite/blob/main/LICENSE">MIT</a>
|
||||||
</el-descriptions-item>
|
</el-descriptions-item>
|
||||||
<el-descriptions-item label="tailwindcss"><a
|
<el-descriptions-item label="tailwindcss"><a
|
||||||
href="https://github.com/tailwindlabs/tailwindcss/blob/master/LICENSE">MIT</a></el-descriptions-item>
|
href="https://github.com/tailwindlabs/tailwindcss/blob/master/LICENSE">MIT</a></el-descriptions-item>
|
||||||
<el-descriptions-item label="element-plus"><a
|
<el-descriptions-item label="element-plus"><a
|
||||||
href="https://github.com/element-plus/element-plus/blob/dev/LICENSE">MIT</a></el-descriptions-item>
|
href="https://github.com/element-plus/element-plus/blob/dev/LICENSE">MIT</a></el-descriptions-item>
|
||||||
<el-descriptions-item label="pinia"><a href="https://github.com/vuejs/pinia/blob/v2/LICENSE">MIT</a>
|
<el-descriptions-item label="pinia"><a target="_blank" href="https://github.com/vuejs/pinia/blob/v2/LICENSE">MIT</a>
|
||||||
</el-descriptions-item>
|
</el-descriptions-item>
|
||||||
<el-descriptions-item label="mitt"><a href="https://github.com/developit/mitt/blob/main/LICENSE">MIT</a>
|
<el-descriptions-item label="mitt"><a target="_blank" href="https://github.com/developit/mitt/blob/main/LICENSE">MIT</a>
|
||||||
</el-descriptions-item>
|
</el-descriptions-item>
|
||||||
<el-descriptions-item label="vue-router"><a
|
<el-descriptions-item label="vue-router"><a
|
||||||
href="https://github.com/vuejs/vue-router/blob/dev/LICENSE">MIT</a></el-descriptions-item>
|
href="https://github.com/vuejs/vue-router/blob/dev/LICENSE">MIT</a></el-descriptions-item>
|
||||||
<el-descriptions-item label="vue-i18n"><a href="https://github.com/kazupon/vue-i18n?tab=MIT-1-ov-file#readme">MIT</a>
|
<el-descriptions-item label="vue-i18n"><a target="_blank" href="https://github.com/kazupon/vue-i18n?tab=MIT-1-ov-file#readme">MIT</a>
|
||||||
</el-descriptions-item>
|
</el-descriptions-item>
|
||||||
<el-descriptions-item label="lightningcss"><a
|
<el-descriptions-item label="lightningcss"><a
|
||||||
href="https://github.com/parcel-bundler/lightningcss/blob/master/LICENSE">MPL-2.0 license</a>
|
href="https://github.com/parcel-bundler/lightningcss/blob/master/LICENSE">MPL-2.0 license</a>
|
||||||
|
@ -42,12 +42,12 @@ const compileTime = import.meta.env.VITE_APP_LAST_COMMIT;
|
||||||
</el-collapse-item>
|
</el-collapse-item>
|
||||||
<el-collapse-item title="关于下位机">
|
<el-collapse-item title="关于下位机">
|
||||||
<el-descriptions border :column="1" class="mt-5 description-style">
|
<el-descriptions border :column="1" class="mt-5 description-style">
|
||||||
<el-descriptions-item label="官网"><a href="https://yunsi.studio/wireless-proxy">允斯工作室</a></el-descriptions-item>
|
<el-descriptions-item label="官网"><a target="_blank" href="https://yunsi.studio/wireless-proxy">允斯工作室</a></el-descriptions-item>
|
||||||
<el-descriptions-item label="版本">-</el-descriptions-item>
|
<el-descriptions-item label="版本">-</el-descriptions-item>
|
||||||
</el-descriptions>
|
</el-descriptions>
|
||||||
|
|
||||||
<el-descriptions title="鸣谢" border :column="1" class="mt-5 description-style">
|
<el-descriptions title="鸣谢" border :column="1" class="mt-5 description-style">
|
||||||
<el-descriptions-item label="windowsair"><a href="https://github.com/windowsair/wireless-esp8266-dap">wireless-esp8266-dap</a>
|
<el-descriptions-item label="windowsair"><a target="_blank" href="https://github.com/windowsair/wireless-esp8266-dap">wireless-esp8266-dap</a>
|
||||||
</el-descriptions-item>
|
</el-descriptions-item>
|
||||||
</el-descriptions>
|
</el-descriptions>
|
||||||
</el-collapse-item>
|
</el-collapse-item>
|
||||||
|
@ -55,11 +55,11 @@ const compileTime = import.meta.env.VITE_APP_LAST_COMMIT;
|
||||||
|
|
||||||
|
|
||||||
<el-descriptions title="作者:空空(kerms)" border :column="1" class="mt-5 description-style">
|
<el-descriptions title="作者:空空(kerms)" border :column="1" class="mt-5 description-style">
|
||||||
<el-descriptions-item label="官网"><a href="https://yunsi.studio/">允斯工作室(https://yunsi.studio/)</a></el-descriptions-item>
|
<el-descriptions-item label="官网"><a target="_blank" href="https://yunsi.studio/">允斯工作室(https://yunsi.studio/)</a></el-descriptions-item>
|
||||||
<el-descriptions-item label="github"><a href="https://github.com/kerms">https://github.com/kerms</a>
|
<el-descriptions-item label="github"><a target="_blank" href="https://github.com/kerms">https://github.com/kerms</a>
|
||||||
</el-descriptions-item>
|
</el-descriptions-item>
|
||||||
<el-descriptions-item label="邮箱">kerms@niazo.org</el-descriptions-item>
|
<el-descriptions-item label="邮箱">kerms@niazo.org</el-descriptions-item>
|
||||||
<el-descriptions-item label="BiliBili"><a href="https://space.bilibili.com/3461571571353885">3461571571353885</a>
|
<el-descriptions-item label="BiliBili"><a target="_blank" href="https://space.bilibili.com/3461571571353885">3461571571353885</a>
|
||||||
</el-descriptions-item>
|
</el-descriptions-item>
|
||||||
<el-descriptions-item label="QQ群">642246000</el-descriptions-item>
|
<el-descriptions-item label="QQ群">642246000</el-descriptions-item>
|
||||||
<el-descriptions-item label="备注">欢迎大家来打扰啊~</el-descriptions-item>
|
<el-descriptions-item label="备注">欢迎大家来打扰啊~</el-descriptions-item>
|
||||||
|
|
|
@ -198,14 +198,13 @@ import {
|
||||||
WifiCmd,
|
WifiCmd,
|
||||||
type WifiInfo,
|
type WifiInfo,
|
||||||
type WifiList,
|
type WifiList,
|
||||||
WifiModuleID,
|
|
||||||
wifi_ap_get_info, wifi_connect_to
|
wifi_ap_get_info, wifi_connect_to
|
||||||
} from "@/api/apiWifi";
|
} from "@/api/apiWifi";
|
||||||
import type {FormInstance} from "element-plus";
|
import type {FormInstance} from "element-plus";
|
||||||
|
|
||||||
import InlineSvg from "@/components/InlineSvg.vue";
|
import InlineSvg from "@/components/InlineSvg.vue";
|
||||||
import type {ApiJsonMsg, ControlMsg, ServerMsg} from "@/api";
|
import type {ApiJsonMsg, ControlMsg, ServerMsg} from "@/api";
|
||||||
import {ControlEvent, ControlMsgType} from "@/api";
|
import {ControlEvent, ControlMsgType, WtModuleID} from "@/api";
|
||||||
import {registerModule, unregisterModule} from "@/router/msgRouter";
|
import {registerModule, unregisterModule} from "@/router/msgRouter";
|
||||||
import {useWsStore} from "@/stores/websocket";
|
import {useWsStore} from "@/stores/websocket";
|
||||||
import {globalNotify, globalNotifyRightSide} from "@/composables/notification";
|
import {globalNotify, globalNotifyRightSide} from "@/composables/notification";
|
||||||
|
@ -250,18 +249,12 @@ const querySearch = (queryString: string, cb: any) => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const onClientMsg = (msg: ServerMsg) => {
|
const onClientMsg = (msg: ApiJsonMsg) => {
|
||||||
if (msg.type !== "json") {
|
switch (msg.cmd as WifiCmd) {
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let json = msg.data as ApiJsonMsg;
|
|
||||||
|
|
||||||
switch (json.cmd as WifiCmd) {
|
|
||||||
case WifiCmd.UNKNOWN:
|
case WifiCmd.UNKNOWN:
|
||||||
break;
|
break;
|
||||||
case WifiCmd.WIFI_API_JSON_STA_GET_AP_INFO: {
|
case WifiCmd.WIFI_API_JSON_STA_GET_AP_INFO: {
|
||||||
const info = msg.data as WifiInfo;
|
const info = msg as WifiInfo;
|
||||||
if (info.rssi === 0) {
|
if (info.rssi === 0) {
|
||||||
Object.assign(wifiStaApInfo, defWifiInfo);
|
Object.assign(wifiStaApInfo, defWifiInfo);
|
||||||
} else {
|
} else {
|
||||||
|
@ -276,7 +269,7 @@ const onClientMsg = (msg: ServerMsg) => {
|
||||||
case WifiCmd.WIFI_API_JSON_CONNECT:
|
case WifiCmd.WIFI_API_JSON_CONNECT:
|
||||||
break;
|
break;
|
||||||
case WifiCmd.WIFI_API_JSON_GET_SCAN: {
|
case WifiCmd.WIFI_API_JSON_GET_SCAN: {
|
||||||
const list = msg.data as WifiList;
|
const list = msg as WifiList;
|
||||||
scanning.value = false;
|
scanning.value = false;
|
||||||
list.scan_list.forEach(value => {
|
list.scan_list.forEach(value => {
|
||||||
if (value.rssi > -50) {
|
if (value.rssi > -50) {
|
||||||
|
@ -298,7 +291,7 @@ const onClientMsg = (msg: ServerMsg) => {
|
||||||
case WifiCmd.WIFI_API_JSON_DISCONNECT:
|
case WifiCmd.WIFI_API_JSON_DISCONNECT:
|
||||||
break;
|
break;
|
||||||
case WifiCmd.WIFI_API_JSON_AP_GET_INFO: {
|
case WifiCmd.WIFI_API_JSON_AP_GET_INFO: {
|
||||||
const info = msg.data as WifiInfo;
|
const info = msg as WifiInfo;
|
||||||
Object.assign(wifiApInfo, info);
|
Object.assign(wifiApInfo, info);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -342,16 +335,17 @@ function onConnectClick() {
|
||||||
}
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
registerModule(WifiModuleID, {
|
registerModule(WtModuleID.WIFI, {
|
||||||
ctrlCallback: onClientCtrl,
|
ctrlCallback: onClientCtrl,
|
||||||
serverMsgCallback: onClientMsg
|
serverJsonMsgCallback: onClientMsg,
|
||||||
|
serverBinMsgCallback: () => {},
|
||||||
});
|
});
|
||||||
wifi_sta_get_ap_info();
|
wifi_sta_get_ap_info();
|
||||||
wifi_ap_get_info();
|
wifi_ap_get_info();
|
||||||
});
|
});
|
||||||
|
|
||||||
onUnmounted(() => {
|
onUnmounted(() => {
|
||||||
unregisterModule(WifiModuleID);
|
unregisterModule(WtModuleID.WIFI);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,25 +1,31 @@
|
||||||
<template>
|
<template>
|
||||||
<nav class="relative px-2 py-1 flex justify-between items-center border-b">
|
<nav class="relative px-2 py-0.5 sm:py-1 flex justify-between items-center border-b h-full">
|
||||||
<div class="flex">
|
<div class="flex">
|
||||||
<button @click.prevent="sideMenuOpen=true" class="flex items-center hover:text-blue-600 p-3">
|
<button @click.prevent="sideMenuOpen=true" class="flex items-center hover:text-blue-600 pl-1 mx-4">
|
||||||
<svg class="block h-4 w-4 fill-current" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg">
|
<svg class="block h-3 lg:h-4 lg:w-4 fill-current" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg">
|
||||||
<title>导航侧栏</title>
|
<title>导航侧栏</title>
|
||||||
<path d="M0 3h20v2H0V3zm0 6h20v2H0V9zm0 6h20v2H0v-2z"></path>
|
<path d="M0 3h20v2H0V3zm0 6h20v2H0V9zm0 6h20v2H0v-2z"></path>
|
||||||
</svg>
|
</svg>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<router-link to="/" class="text-3xl px-4 font-bold leading-none" title="走,去码头整点薯条">
|
<router-link to="/" class="text-3xl px-4 font-bold leading-none hidden items-center sm:flex" title="走,去码头整点薯条">
|
||||||
<InlineSvg name="favicon" class="h-10"></InlineSvg>
|
<InlineSvg name="favicon" class="h-5 lg:h-8"></InlineSvg>
|
||||||
</router-link>
|
</router-link>
|
||||||
|
|
||||||
|
|
||||||
<!-- <a class="text-3xl px-4 font-bold leading-none" href="/">-->
|
<!-- <a class="text-3xl px-4 font-bold leading-none" href="/">-->
|
||||||
<!-- <InlineSvg name="home" class="h-10"></InlineSvg>-->
|
<!-- <InlineSvg name="home" class="h-10"></InlineSvg>-->
|
||||||
<!-- </a>-->
|
<!-- </a>-->
|
||||||
<!-- <router-link to="/" class="flex items-center text-sm text-blue-600 font-bold">主页</router-link>-->
|
<!-- <router-link to="/" class="flex items-center text-sm text-blue-600 font-bold">主页</router-link>-->
|
||||||
<!-- <a class="flex items-center text-sm text-blue-600 font-bold" href="/">主页6</a>-->
|
<!-- <a class="flex items-center text-sm text-blue-600 font-bold" href="/">主页6</a>-->
|
||||||
|
|
||||||
|
<div class="flex pt-0.5 sm:pt-1 ml-4 text-sm items-center sm:hidden">
|
||||||
|
<router-link :to="route.fullPath">{{ route.meta.title }}</router-link>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex">
|
<div class="flex">
|
||||||
<ul class="hidden absolute top-1/2 left-1/2 transform -translate-y-1/2 -translate-x-1/2 md:flex md:mx-auto md:items-center md:w-auto md:space-x-6">
|
<ul class="hidden absolute top-1/2 left-1/2 transform -translate-y-1/2 -translate-x-1/2 sm:flex sm:mx-auto sm:items-center sm:w-auto sm:space-x-6">
|
||||||
<li v-for="(item, index) in menuItems" :key="index" class="router-link">
|
<li v-for="(item, index) in menuItems" :key="index" class="router-link">
|
||||||
<router-link :to="item.href" :class="item?.class">{{item.name}}</router-link>
|
<router-link :to="item.href" :class="item?.class">{{item.name}}</router-link>
|
||||||
</li>
|
</li>
|
||||||
|
@ -27,13 +33,23 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- <a class="md:ml-auto md:mr-3"></a>-->
|
<!-- <a class="md:ml-auto md:mr-3"></a>-->
|
||||||
<div class="flex">
|
<div class="flex h-full">
|
||||||
<el-button :type="wsColor" size="large" class="transition duration-1000">
|
<div id="page-spec-slot" class="content-center h-full flex flex-row"></div>
|
||||||
|
<div class="lg:hidden">
|
||||||
|
<el-button :type="wsColor" size="small" class="transition duration-1000 min-h-full">
|
||||||
<InlineSvg v-show="wsColor!=='success'" name="link-off" class="mr-2" width="20"></InlineSvg>
|
<InlineSvg v-show="wsColor!=='success'" name="link-off" class="mr-2" width="20"></InlineSvg>
|
||||||
<InlineSvg v-show="wsColor==='success'" name="link" class="mr-2" width="20"></InlineSvg>
|
<InlineSvg v-show="wsColor==='success'" name="link" class="mr-2" width="20"></InlineSvg>
|
||||||
{{ wsState }}
|
<div class="text-xs sm:text-sm lg:text-base">{{ wsState }}</div>
|
||||||
</el-button>
|
</el-button>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="hidden lg:flex">
|
||||||
|
<el-button :type="wsColor" size="large" class="transition duration-1000 min-h-full">
|
||||||
|
<InlineSvg v-show="wsColor!=='success'" name="link-off" class="mr-2" width="20"></InlineSvg>
|
||||||
|
<InlineSvg v-show="wsColor==='success'" name="link" class="mr-2" width="20"></InlineSvg>
|
||||||
|
<div class="text-base">{{ wsState }}</div>
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
<div :class='["custom-drawer", {open: sideMenuOpen}]'>
|
<div :class='["custom-drawer", {open: sideMenuOpen}]'>
|
||||||
<el-drawer
|
<el-drawer
|
||||||
|
@ -42,7 +58,7 @@
|
||||||
size=""
|
size=""
|
||||||
:direction="'ltr'"
|
:direction="'ltr'"
|
||||||
>
|
>
|
||||||
<div id="testborder" :class="[sideMenuItemClass]" class="pr-6 flex text-gray-500" @click="sideMenuOpen=false">
|
<div :class="[sideMenuItemClass]" class="pr-6 flex text-gray-500" @click="sideMenuOpen=false">
|
||||||
<InlineSvg name="cross" class="h-6"></InlineSvg>
|
<InlineSvg name="cross" class="h-6"></InlineSvg>
|
||||||
<div>
|
<div>
|
||||||
<p class="h-6 flex items-center">{{ $t("page.close") }}</p>
|
<p class="h-6 flex items-center">{{ $t("page.close") }}</p>
|
||||||
|
@ -59,9 +75,12 @@
|
||||||
|
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<div>
|
<div>
|
||||||
<p class="text-xs text-center text-gray-400">
|
<el-button @click="toggle">
|
||||||
<span>Copyright <a href="http://github.com/kerms">kerms</a> 2024</span>
|
<InlineSvg v-if="!isFullscreen" name="open-in-full" width="16px" fill="#000000"></InlineSvg>
|
||||||
</p>
|
<p v-if="!isFullscreen">全屏</p>
|
||||||
|
<InlineSvg v-if="isFullscreen" name="close-fullscreen" width="16px" fill="#000000"></InlineSvg>
|
||||||
|
<p v-if="isFullscreen">缩小</p>
|
||||||
|
</el-button>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</el-drawer>
|
</el-drawer>
|
||||||
|
@ -90,8 +109,12 @@ import {computed, ref} from "vue";
|
||||||
import {useWsStore} from "@/stores/websocket";
|
import {useWsStore} from "@/stores/websocket";
|
||||||
import {translate} from "@/locales";
|
import {translate} from "@/locales";
|
||||||
import {ControlEvent} from "@/api";
|
import {ControlEvent} from "@/api";
|
||||||
|
import {useRoute} from "vue-router";
|
||||||
|
import { useFullscreen } from '@vueuse/core'
|
||||||
|
|
||||||
const wsStore = useWsStore();
|
const wsStore = useWsStore();
|
||||||
|
const {isFullscreen, toggle} = useFullscreen();
|
||||||
|
const route = useRoute();
|
||||||
|
|
||||||
const sideMenuItemClass = "block p-4 text-sm font-semibold hover:bg-blue-50 hover:text-blue-600 rounded"
|
const sideMenuItemClass = "block p-4 text-sm font-semibold hover:bg-blue-50 hover:text-blue-600 rounded"
|
||||||
const sideMenuOpen = ref(false);
|
const sideMenuOpen = ref(false);
|
||||||
|
@ -127,7 +150,11 @@ const menuItems: Item[] = ([
|
||||||
/* {
|
/* {
|
||||||
name: translate("page.home"),
|
name: translate("page.home"),
|
||||||
href: "/",
|
href: "/",
|
||||||
}, */{
|
}, */
|
||||||
|
{
|
||||||
|
name: translate("page.uart"),
|
||||||
|
href: "/uart",
|
||||||
|
}, {
|
||||||
name: translate("page.wifi"),
|
name: translate("page.wifi"),
|
||||||
href: "/wifi",
|
href: "/wifi",
|
||||||
}, {
|
}, {
|
||||||
|
@ -136,11 +163,7 @@ const menuItems: Item[] = ([
|
||||||
}, {
|
}, {
|
||||||
name: translate("page.feedback"),
|
name: translate("page.feedback"),
|
||||||
href: "/feedback",
|
href: "/feedback",
|
||||||
},/* {
|
},
|
||||||
name: translate("page.uart"),
|
|
||||||
href: "/uart",
|
|
||||||
class: "todo-menu-item",
|
|
||||||
},*/
|
|
||||||
]);
|
]);
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
Loading…
Reference in New Issue