当前位置: 首页 > news >正文

xterm + vue3 + websocket 终端界面

 xterm.js    下载插件

// xterm
npm install --save xterm// xterm-addon-fit    使终端适应包含元素
npm install --save xterm-addon-fit// xterm-addon-attach   通过websocket附加到运行中的服务器进程
npm install --save xterm-addon-attach
<template><div :class="props.type ? 'height305' : 'height160'"><el-row><el-col :span="20"><div:class="['xterm', props.type ? 'heightA' : 'heightB']"ref="terminal"v-loading="loading"element-loading-text="拼命连接中"><div class="terminal" id="terminal" ref="terminal"></div></div><div class="textarea"><textarea ref="textarea" v-model="quickCmd" /><div class="bottomOperate flexEnd"><el-button type="primary" @click="sendCmd" :disabled="!quickCmd">发送命令</el-button></div></div></el-col><el-col :span="4"><div :class="['xtermR', props.type ? 'heightA' : 'heightBR']"><el-tabsv-model="tabActiveName"class="demo-tabs"@tab-click="handleClick"><el-tab-pane label="常用命令" name="first"><div v-if="filteredGroups?.length > 0"><div class="marginBottom10"><el-buttontype="primary"size="small"@click="addCmdGroup('addGroup')">新增命令组</el-button><el-button type="primary" size="small" @click="addCmd('add')">新增命令</el-button></div><el-collapsev-loading="loadingR":class="props.type ? 'listBoxA' : 'listBoxB'"><el-collapse-itemv-for="group in filteredGroups":name="group.name":key="group.name"class="custom-collapse-item"><template #title><divclass="flexSpaceBetween"style="width: 100%"@mouseenter="showActions(group.id, true)"@mouseleave="showActions(group.id, false)"><span class="collapse-title">{{ group.name }}</span><span v-show="actionStates[group.id]"><el-buttonlinktype="primary"@click="addCmdGroup('editGroup', group, $event)">编辑</el-button><el-buttonlinktype="primary"@click="del(group.id, 'group', $event)">删除</el-button></span></div></template><template #default><divv-for="item in group.device_command":key="item.id"class="item flexSpaceBetween paddingRight20 marginBottom10"@mouseenter="showActions1(item.id, true)"@mouseleave="showActions1(item.id, false)"><spanclass="usualName"@click="getName(item.name)":title="item.name">{{ item.name }}</span><span v-show="actionStates1[item.id]" class="btns"><el-buttonlinktype="primary"@click="addCmd('edit', item, group.id)">编辑</el-button><el-button link type="primary" @click="del(item.id)">删除</el-button></span></div></template></el-collapse-item></el-collapse></div><div class="flexCenter" v-else>暂无常用命令</div></el-tab-pane><el-tab-pane label="命令记录" name="second"><div:class="props.type ? 'listBoxA' : 'listBoxB'"v-if="globalStore.cmdRecordList?.length > 0"><divv-for="item in globalStore.cmdRecordList":key="item"class="item flexSpaceBetween paddingRight20 marginBottom10"><span class="recordName" @click="getName(item)">{{item}}</span></div></div><div class="flexCenter" v-else>暂无命令记录</div></el-tab-pane></el-tabs></div></el-col></el-row></div><!-- 新增命令组 --><AddTerminalGroup ref="addTerminalGroup" /><!-- 新增命令 --><AddTerminal ref="addTerminal" />
</template>
<script setup>
import "xterm/css/xterm.css";
import { Terminal } from "xterm";
import { FitAddon } from "xterm-addon-fit";
import { debounce } from "lodash";
import { ElMessage, ElMessageBox } from "element-plus";
import {ref,reactive,onMounted,onBeforeUnmount,computed,nextTick,getCurrentInstance,
} from "vue";
import { useGlobalStore } from "@/stores/modules/global.js";
import AddTerminalGroup from "./AddTerminalGroup.vue";
import AddTerminal from "./AddTerminal.vue";
import {commandGroupIndex,commandGroupDel,commandDel,
} from "@/api/equipment";
import { WebSocketUrl } from "@/api/request";const props = defineProps({type: {type: String,default: () => {return "";},},currentPathRes: {type: String,default: () => {return "/";},},
});
const globalStore = useGlobalStore();
const { proxy } = getCurrentInstance();
const searchTerm = ref("");
const tabActiveName = ref("first");
const cmdRecordList = ref(globalStore.cmdRecordList); // 命令历史记录
const loadingR = ref(false);
const groups = ref([]);
const quickCmd = ref("");
const actionStates = ref({});
const actionStates1 = ref({});const filteredGroups = computed(() => {if (!searchTerm.value) {return groups.value;}return groups.value.map((group) => {const filteredItems = group.device_command.filter((item) =>item.includes(searchTerm.value));return {...group,device_command: filteredItems,};}).filter((group) => group.device_command.length > 0);
});const showActions = (id, show) => {actionStates.value[id] = show;
};const showActions1 = (id, show) => {actionStates1.value[id] = show;
};const addCmdGroup = (type, row, event) => {if (event) event.stopPropagation();nextTick(() => {proxy.$refs["addTerminalGroup"].showDialog({type,row,});});
};const addCmd = (type, row, group_id) => {nextTick(() => {proxy.$refs["addTerminal"].showDialog({type,groupList: groups.value,row,group_id,});});
};const getName = (val) => {quickCmd.value = val;
};// 发送命令
const sendCmd = () => {if (isWsOpen()) {terminalSocket.value.send(quickCmd.value);// 处理命令历史记录handleCmdRecordList(quickCmd.value);}
};const handleCmdRecordList = (newCmd) => {if (newCmd) {// 对新命令进行trim处理const trimmedCmd = newCmd.trim();// 检查是否有重复值并删除const index = cmdRecordList.value.indexOf(trimmedCmd);if (index !== -1) {cmdRecordList.value.splice(index, 1);}// 将新命令添加到数组最前面cmdRecordList.value.unshift(trimmedCmd);globalStore.setCmdRecordList(cmdRecordList.value);}
};const del = (id, group, event) => {if (event) event.stopPropagation();ElMessageBox.confirm("确认删除吗?", "删除", {confirmButtonText: "确定",cancelButtonText: "取消",type: "warning",}).then(() => {if (group) {commandGroupDel({ id }).then((res) => {if (res.status === 200) {ElMessage.success("删除成功");getTableData();}});} else {commandDel({ id }).then((res) => {if (res.status === 200) {ElMessage.success("删除成功");getTableData();}});}}).catch(() => {});
};//获取表格数据
const getTableData = () => {loadingR.value = true;commandGroupIndex().then((res) => {loadingR.value = false;if (res.status === 200) {groups.value = res.data?.list;}}).catch((error) => {loadingR.value = false;});
};
// 命令列表
getTableData();
//终端信息
const loading = ref(false);
const terminal = ref(null);
const fitAddon = new FitAddon();
let first = ref(true);
let terminalSocket = ref(null);
let term = ref(null);// 初始化WS
const initWS = () => {if (!terminalSocket.value) {createWS();}if (terminalSocket.value && terminalSocket.value.readyState > 1) {terminalSocket.value.close();createWS();}
};// 创建WS
const createWS = () => {loading.value = true;terminalSocket.value = new WebSocket(WebSocketUrl + globalStore.wsUrl);terminalSocket.value.onopen = runRealTerminal; //WebSocket 连接已建立terminalSocket.value.onmessage = onWSReceive; //收到服务器消息terminalSocket.value.onclose = closeRealTerminal; //WebSocket 连接已关闭terminalSocket.value.onerror = errorRealTerminal; //WebSocket 连接出错
};//WebSocket 连接已建立
const runRealTerminal = () => {loading.value = false;let sendData = JSON.stringify({t: "conn",});terminalSocket.value.send(sendData);
};
//WebSocket收到服务器消息
const onWSReceive = (event) => {// 首次接收消息,发送给后端,进行同步适配尺寸if (first.value === true) {first.value = false;resizeRemoteTerminal();if (props.type === "termDia") {autoWriteInfo();}}const blob = new Blob([event.data.toString()], {type: "text/plain",});//将Blob 对象转换成字符串const reader = new FileReader();reader.readAsText(blob, "utf-8");reader.onload = (e) => {// 可以根据返回值判断使用何种颜色或者字体,不过返回值自带了一些字体颜色writeOfColor(reader.result);};
};//WebSocket 连接出错
const errorRealTerminal = (ex) => {let message = ex.message;if (!message) message = "disconnected";term.value.write(`\x1b[31m${message}\x1b[m\r\n`);loading.value = false;
};
//WebSocket 连接已关闭
const closeRealTerminal = () => {loading.value = false;
};// 初始化Terminal
const initTerm = () => {term.value = new Terminal({rendererType: "canvas", //渲染类型// rows: 50, //行数,影响最小高度// cols: 100, // 列数,影响最小宽度convertEol: true, //启用时,光标将设置为下一行的开头// scrollback: 50, //终端中的滚动条回滚量disableStdin: false, //是否应禁用输入。cursorStyle: "underline", //光标样式cursorBlink: true, //光标闪烁theme: {foreground: "#F8F8F8",background: "#2D2E2C",cursor: "help", //设置光标lineHeight: 16,},fontFamily: '"Cascadia Code", Menlo, monospace',});// writeDefaultInfo();// 弹框自动输入term.value.open(terminal.value); //挂载dom窗口term.value.loadAddon(fitAddon); //自适应尺寸term.value.focus();termData(); //Terminal 事件挂载
};const autoWriteInfo = () => {let sendData = "\n" + "cd " + props.currentPathRes + "\n";// term.value.write(`\x1b[37m${sendData}\x1b[m`);// term.value.write("\r\n");if (isWsOpen()) {terminalSocket.value.send(sendData);}
};const writeDefaultInfo = () => {let defaultInfo = ["┌\x1b[1m terminals \x1b[0m─────────────────────────────────────────────────────────────────┐ ","│                                                                            │ ","│  \x1b[1;34m 欢迎使用XS  SSH   \x1b[0m                                                       │ ","│                                                                            │ ","└────────────────────────────────────────────────────────────────────────────┘ ",];term.value.write(defaultInfo.join("\n\r"));term.value.write("\r\n");// writeOfColor('我是加粗斜体红色的字呀', '1;3;', '31m')
};const writeOfColor = (txt, fontCss = "", bgColor = "") => {// 在Linux脚本中以 \x1B[ 开始,中间前部分是样式+内容,以 \x1B[0m 结尾// 示例 \x1B[1;3;31m 内容 \x1B[0m// fontCss// 0;-4;字体样式(0;正常 1;加粗 2;变细 3;斜体 4;下划线)// bgColor// 30m-37m字体颜色(30m:黑色 31m:红色 32m:绿色 33m:棕色字 34m:蓝色 35m:洋红色/紫色 36m:蓝绿色/浅蓝色 37m:白色)// 40m-47m背景颜色(40m:黑色 41m:红色 42m:绿色 43m:棕色字 44m:蓝色 45m:洋红色/紫色 46m:蓝绿色/浅蓝色 47m:白色)// console.log("writeOfColor", term)term.value.write(`\x1b[37m${fontCss}${bgColor}${txt}\x1b[m`);// term.value.write(`\x1B[${fontCss}${bgColor}${txt}\x1B[0m`);
};// 终端输入触发事件
const termData = () => {fitAddon.fit();// 输入与粘贴的情况,onData不能重复绑定,不然会发送多次term.value.onData((data) => {// console.log(data, "传入服务器");if (isWsOpen()) {terminalSocket.value.send(data);}});// 终端尺寸变化触发term.value.onResize(() => {resizeRemoteTerminal();});
};//尺寸同步 发送给后端,调整后端终端大小,和前端保持一致,不然前端只是范围变大了,命令还是会换行
const resizeRemoteTerminal = () => {const { cols, rows } = term.value;if (isWsOpen()) {terminalSocket.value.send(JSON.stringify({t: "resize",width: rows,height: cols,}));}
};// 是否连接中0 1 2 3 状态
const isWsOpen = () => {// console.log(terminalSocket.value, "terminalSocket.value");const readyState = terminalSocket.value && terminalSocket.value.readyState;return readyState === 1;
};// 适应浏览器尺寸变化
const fitTerm = () => {fitAddon.fit();
};
const onResize = debounce(() => fitTerm(), 500);
const onTerminalResize = () => {window.addEventListener("resize", onResize);
};
const removeResizeListener = () => {window.removeEventListener("resize", onResize);
};//*生命周期函数
onMounted(() => {initWS();initTerm();onTerminalResize();
});onBeforeUnmount(() => {removeResizeListener();let sendData = JSON.stringify({t: "close",});if (isWsOpen()) {terminalSocket.value.send(sendData);terminalSocket.value && terminalSocket.value.close();}
});// 暴露方法
defineExpose({ getTableData });
</script>
<style lang="scss" scoped>
.xterm {position: relative;width: 100%;background: rgb(45, 46, 44);
}.xtermR {position: relative;width: 100%;background: #fff;padding: 10px;position: relative;// overflow: hidden;.listBoxA {overflow-y: auto;height: calc(100vh - 450px);}.listBoxB {overflow-y: auto;height: calc(100vh - 300px);}
}.heightA {height: calc(100vh - 400px);
}
.heightB {height: calc(100vh - 235px);
}
.heightBR {height: calc(100vh - 155px);
}.usualName {width: calc(100% - 80px);display: inline-block;cursor: pointer;overflow: hidden;text-overflow: ellipsis;white-space: nowrap;
}.btns {width: 80px;
}.textarea {overflow: hidden;position: relative;height: 80px;background: #ffffff;textarea {width: 100%;height: 90px;border: 0 none;outline: none;resize: none;font-size: 15px;overflow-y: auto;padding: 5px;background: #ffffff;}.bottomOperate {position: absolute;right: 10px;bottom: 10px;}
}
.recordName {font-size: 13px;color: #303133;cursor: pointer;margin-bottom: 10px;width: 100%;
}
.flexCenter {font-size: 14px;padding-top: 150px;
}
</style>

 此页面兼容了弹框和非弹框页面,做了两种样式处理判断

相关文章:

xterm + vue3 + websocket 终端界面

xterm.js 下载插件 // xterm npm install --save xterm// xterm-addon-fit 使终端适应包含元素 npm install --save xterm-addon-fit// xterm-addon-attach 通过websocket附加到运行中的服务器进程 npm install --save xterm-addon-attach <template><div :…...

解锁 CSS:网页美化与布局的艺术

目录 一、CSS 是什么 二、CSS 的作用 三、CSS 的应用方式&#xff08;引用方式&#xff09; 四、选择器&#xff1a;如何挑选要 “打扮” 的元素 五、CSS 属性&#xff1a;丰富多样的 “服装款式” 字体属性&#xff1a; 文本属性&#xff1a;只能控制文字的相关样式。 …...

AWS K8s 部署架构

Amazon Web Services&#xff08;AWS&#xff09;提供了一种简化的Kubernetes&#xff08;K8s&#xff09;部署架构&#xff0c;使得在云环境中管理和扩展容器化应用变得更加容易。这个架构的核心是AWS EKS&#xff08;Elastic Kubernetes Service&#xff09;&#xff0c;它是…...

【鸿蒙NEXT】鸿蒙里面类似iOS的Keychain——关键资产(@ohos.security.asset)实现设备唯一标识

前言 在iOS开发中Keychain 是一个非常安全的存储系统&#xff0c;用于保存敏感信息&#xff0c;如密码、证书、密钥等。与 NSUserDefaults 或文件系统不同&#xff0c;Keychain 提供了更高的安全性&#xff0c;因为它对数据进行了加密&#xff0c;并且只有经过授权的应用程序才…...

电子电器架构 --- HUD的工作原理

我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 所谓鸡汤,要么蛊惑你认命,要么怂恿你拼命,但都是回避问题的根源,以现象替代逻辑,以情绪代替思考,把消极接受现实的懦弱,伪装成乐观面对不幸的…...

C# 窗体应用程序嵌套web网页,基于谷歌浏览器内核(含源码)

有一个winform项目&#xff0c;需要借助一个web项目来显示&#xff0c;并且对web做一些操作,web页目是需要用谷歌内核&#xff0c;基于谷歌 Chromium项目的开源Web Browser控件来开发写了一个demo。 安装步骤 第一步&#xff1a;右键项目&#xff0c;点击 管理NuGet程序包 , 输…...

FFmpeg 中 examples 使用教程

FFmpeg 中 examples FFmpeg 的 examples 目录包含了一系列示例程序,旨在展示如何使用 FFmpeg 的不同库和 API。这些示例涵盖了多种功能,包括音视频编解码、格式转换、过滤、网络传输等。以下是一些常见的示例程序及其功能介绍: 音频和视频解码: 示例程序展示了如何打开音视…...

自动化办公-合并多个excel

在日常的办公自动化工作中&#xff0c;尤其是处理大量数据时&#xff0c;合并多个 Excel 表格是一个常见且繁琐的任务。幸运的是&#xff0c;借助 Python 语言中的强大库&#xff0c;我们可以轻松地自动化这个过程。本文将带你了解如何使用 Python 来合并多个 Excel 表格&#…...

Docker搭建MySQL

Docker搭建MySQL 准备工作 先准备配置目录和持久化目录&#xff0c;举个栗子&#xff1a;mkdir -p /opt/module/mysql/{conf,data,log}准备配置文件*.cnf,放到/opt/module/mysql/conf目录下。当然不准备也没事&#xff0c;容器中有个默认配置&#xff1a;/etc/mysql/conf.d/m…...

亚马逊国际站商品爬虫:Python实战指南

在数字化时代&#xff0c;数据的价值不言而喻。对于电商领域而言&#xff0c;获取竞争对手的商品信息、价格、评价等数据&#xff0c;对于市场分析和策略制定至关重要。本文将带你了解如何使用Python编写爬虫&#xff0c;以亚马逊国际站为例&#xff0c;按照关键字搜索并获取商…...

pwntools用法

pwntools 是一个Python库&#xff0c; 用于编写二进制漏洞利用&#xff08;exploitation&#xff09;脚本 功能&#xff1a; 远程连接和本地连接&#xff1a; 支持通过TCP/UDP连接远程服务或与本地进程进行交互。Shellcode和ROP链构造&#xff1a; 提供了便捷的工具来生成和利…...

企业云盘怎么选?2024年免费版9款整理

文章介绍了以下9大企业云盘&#xff1a;1.亿方云&#xff1b;2.Worktile&#xff1b;3.百度网盘&#xff1b;4.腾讯云盘&#xff1b;5.阿里云盘&#xff1b;6.金山云盘&#xff1b;7.Dropbox&#xff1b;8.Box。 在企业日常管理中&#xff0c;文件存储和共享一直是个不小的难题…...

Linux之ARM(MX6U)裸机篇----5.仿stm32的LED驱动实验

一&#xff0c;启动文件 .global _start .global _bss_start /* 类似宏定义把__bss_start定义为_bss_start */ _bss_start:.word __bss_start.global _bss_end _bss_end:.word __bss_end_start:#设置处理器进入SVC模式mrs r0, cpsr /* 读取cpsr到r0 */bic r0, r0, …...

Qt从入门到入土(七)-实现炫酷的登录注册界面(下)

前言 Qt从入门到入土&#xff08;六&#xff09;-实现炫酷的登录注册界面&#xff08;上&#xff09;主要讲了如何使用QSS样式表进行登录注册的界面设计&#xff0c;本篇文章将介绍如何对登录注册界面进行整体控件的布局&#xff0c;界面的切换以及实现登录、记住密码等功能。…...

如何进行年度工作回顾?

发生了什么事&#xff1f; 什么事情进展顺利 &#xff1f; 什么事情进展不顺利&#xff1f; 如何适应未来&#xff1f; 年度回顾的定义&#xff1a;这是一种战略工具&#xff0c;能帮助人们清晰看到过去一年对业务、职业或个人生活的影响&#xff0c;可用于明确关键事件、找出问…...

spring默认线程池SimpleAsyncTaskExecutor特点为什么要尽量避免使用

在 Spring Boot 中&#xff0c;默认的线程池配置由 TaskExecutionAutoConfiguration 类提供&#xff0c;使用的是 SimpleAsyncTaskExecutor。 SimpleAsyncTaskExecutor特点 每次调用创建新线程&#xff1a; SimpleAsyncTaskExecutor 每次执行任务时都会创建一个新线程&#xf…...

每天40分玩转Django:Django表单集

Django表单集 一、知识要点概览表 类别知识点掌握程度要求基础概念FormSet、ModelFormSet深入理解内联表单集InlineFormSet、BaseInlineFormSet熟练应用表单集验证clean方法、验证规则熟练应用自定义配置extra、max_num、can_delete理解应用动态管理JavaScript动态添加/删除表…...

构建混合技术栈的统一监控与日志平台

文章目录 摘要引言构建统一监控与日志平台的核心思路痛点分析解决方案 平台架构设计架构概览 环境准备Java 服务的 Prometheus 指标导出Prometheus 指标采集模块Node.js 日志收集模块3. Logstash 配置4. Grafana 与 Kibana 配置 QA 环节总结未来展望参考资料 摘要 在多技术栈开…...

KOI技术-事件驱动编程(Sping后端)

1 “你日渐平庸&#xff0c;甘于平庸&#xff0c;将继续平庸。”——《以自己喜欢的方式过一生》 2. “总是有人要赢的&#xff0c;那为什么不能是我呢?”——科比布莱恩特 3. “你那么憎恨那些人&#xff0c;和他们斗了那么久&#xff0c;最终却要变得和他们一样&#xff0c;…...

ubuntu 20.04 国内源安装docker

先更新软件包&#xff0c;安装备要apt软件 # 更新软件包索引 sudo apt-get update# 安装需要的软件包以使apt能够通过HTTPS使用仓库 sudo apt-get install ca-certificates curl gnupg lsb-release使用阿里云源 # 添加阿里云官方GPG密钥 curl -fsSL http://mirrors.aliyun.co…...

微信小程序 app.json 配置文件解析与应用

目录 一、什么是 app.json&#xff1f; 二、app.json 文件的基本结构 三、详细解析 app.json 配置项 1. pages&#xff1a;小程序页面路径配置 2. window&#xff1a;窗口样式配置 3. tabBar&#xff1a;底部标签栏配置 4. networkTimeout&#xff1a;网络请求超时配置 …...

C高级:思维导图Day2

目录 总览1 总览2 总览1 压缩与解压缩 打包与解包 软连接与硬链接 ubuntu下关机与重启指令 总览2 结束...

蓝桥杯(Java)(ing)

Java前置知识 输入流&#xff1a; &#xff08;在Java面向对象编程-CSDN博客里面有提过相关知识------IO流&#xff09; // 快读快写 static BufferedReader in new BufferedReader(new InputStreamReader(System.in)); static BufferedWriter out new BufferedWriter(new…...

[Pro Git#2] 分支管理 | branch fix_bug , feature | 处理合并冲突

目录 一、Issue模板文件 二、Pull Requests模板文件 分支管理 1. 理解分支 2. 创建与管理分支 1. 切换分支与提交历史 2. 合并分支 3. 删除分支 4. 解决合并冲突 6. 查看分支合并情况 快速创建并切换分支 分支管理策略 分支合并模式 分支管理原则 日常开发环境 …...

Java——集合框架

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 1 集合框架概述1.1 内存层面需要针对多个数据进行存储。此时&#xff0c;可以考虑的容器有&#xff1a;1.2 数组存储多个数据方面的特点和弊端1.3 Java集合框架体系…...

Mac 环境 VVenC 编译与编码命令行工具使用教程

VVenC VVenC 是一个开源的高效视频编码器&#xff0c;专门用于支持 H.266/VVC (Versatile Video Coding) 标准的编码。H.266/VVC 是继 HEVC (H.265) 之后的新一代视频编码标准&#xff0c;主要目的是提供比 HEVC 更高的压缩效率&#xff0c;同时保持或提高视频质量。H.266/VVC…...

WebRTC:实现浏览器与移动应用的实时通信

1.技术简介 &#xff08;Web Real-Time&#xff09;是一种开放式实时通信技术&#xff0c;旨在使浏览器和移动应用程序通过简单的API即可实现实时音频、视频和数据传输&#xff0c;而无需安装插件或额外软件。它支持网络应用中的点对点通信&#xff0c;例如视频聊天、语音通话…...

curl+openssl 踩坑笔记

curl编译&#xff1a;点击跳转 踩坑一 * SSL certificate problem: unable to get local issuer certificate * closing connection #0 curl: (60) SSL certificate problem: unable to get local issuer certificate More details here: https://curl.se/docs/sslcerts.html …...

【NebulaGraph】变化的多跳查询

【NebulaGraph】变化的多跳查询 1. 需求2. 解决方案2.1 确定查询结构2.2 构建查询语句 3. 追加需求&#xff1a;如果增加每一跳都要指定查询某SPACE下的Tag&#xff0c;或者不查询某个Tag怎么办 1. 需求 存在多跳请求&#xff0c;其中每一跳是从上一跳查询结果为基础的。但是 …...

【C++】九九乘法表编程题详解与多角度对比分析

博客主页&#xff1a; [小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: C 文章目录 &#x1f4af;前言&#x1f4af;题目概述题目描述 &#x1f4af;老师的实现方法代码解析优点不足 &#x1f4af;我的实现方法代码解析优点不足 &#x1f4af;实现方法对比&#x1f4af;优化与扩展代码优化…...

node.js卸载并重新安装(超详细图文步骤)

卸载node.js 重新安装nodejs 一、卸载 1、首先进入控制面板卸载程序 2、卸载后 到文件夹中进行进一步的删除 删除上述的几个文件夹 每个人可能不一样&#xff0c;总之是找到自己的nodejs安装路径&#xff0c;下面是我的 ①删除C:UsersAdminAppDataRoaming路径下的npm相关文件…...

redis的集群模式与ELK基础

一、redis的集群模式 1.主从复制 &#xff08;1&#xff09;概述 主从模式&#xff1a;这是redis高可用的基础&#xff0c;哨兵和集群都是建立在此基础之上。 主从模式和数据库的主从模式是一样的&#xff0c;主负责写入&#xff0c;然后把写入的数据同步到从服务器&#xff…...

一份关于 Ubuntu 系统下代理配置的故障排查笔记

Ubuntu 网络代理配置与故障排查指南 在使用 Ubuntu 系统时&#xff0c;配置网络代理可以帮助提升网络访问速度或突破网络限制。然而&#xff0c;代理配置过程中可能会遇到各种问题。本文将详细介绍如何在 Ubuntu 下配置网络代理&#xff0c;并提供故障排查的步骤和解决方案。 …...

如何用jmeter工具进行性能测试

前言 今天我们来说说jmeter如何进行性能测试&#xff0c;我们都知道jmeter工具除了可以进行接口功能测试外&#xff0c;还可以进行性能测试。当项目趋于稳定&#xff0c;根据性能需求就可以着手准备性能测试了&#xff0c;今天就说一说jmeter如何进行性能测试&#xff0c;jmet…...

五、Vue 循环语句

文章目录 简介一、基础数组迭代二、对象属性迭代三、整数循环 简介 在 Vue.js 的世界里&#xff0c;当我们需要处理重复性的结构并依据数据动态渲染时&#xff0c;v-for 指令就成了不可或缺的工具&#xff0c;它赋予开发者简洁且强大的能力&#xff0c;轻松应对各种列表渲染场景…...

HMSC联合物种分布模型

联合物种分布模型&#xff08;Joint Species Distribution Modelling&#xff0c;JSDM&#xff09;在生态学领域&#xff0c;特别是群落生态学中发展最为迅速&#xff0c;Hmsc是物种群落分层模型的缩写(Hierarchical Modelling of Species Communities)&#xff0c;它是一种基于…...

【CPU】risc-v指令集和其他指令集的差别(个人草稿)

第三&#xff0c;在 RISC-V 中对于所有指令&#xff0c;要读写的寄存器的标识符总是在同一位置&#xff0c;意味着在解码指令之前&#xff0c;就可以先开始访问寄存器。在许多其他的 ISA 中&#xff0c;某些指令字段在部分指令中被重用作为源目的地&#xff0c;在其他指令中又被…...

处理元素卡在视野边界,滚动到视野内

效果图如下&#xff1a; 本示例处理场景&#xff1a;点击底部的折叠面板&#xff0c;展开后移动端滚动条位置不变&#xff0c;导致展开内容在视图外。造成面板展开无内容的错觉。 处理核心API: IntersectionObserver 此API可绑定元素并监听元素是否在视野内。若在视野外​​​…...

环,域,体,整区,理想,极大理想,

环&#xff1a; 定义&#xff1a; 加法交换群 乘法半群 分配律 域的定义&#xff1a; 加法交换群 乘法群&#xff08;去掉0元是交换群&#xff09; 分配律 Eg:比如整数集合不是域&#xff0c;因为对于乘法来说&#xff0c;去掉0后没有单位元了&#xff0c;但是是环 Eg…...

音视频入门基础:MPEG2-TS专题(22)——FFmpeg源码中,获取TS流的音频信息的实现

音视频入门基础&#xff1a;MPEG2-TS专题系列文章&#xff1a; 音视频入门基础&#xff1a;MPEG2-TS专题&#xff08;1&#xff09;——MPEG2-TS官方文档下载 音视频入门基础&#xff1a;MPEG2-TS专题&#xff08;2&#xff09;——使用FFmpeg命令生成ts文件 音视频入门基础…...

大模型—Ollama 结构化输出

Ollama 结构化输出 Ollama现在支持结构化输出,使得可以按照由JSON模式定义的特定格式来约束模型的输出。Ollama的Python和JavaScript库已经更新,以支持结构化输出。 结构化输出的用例包括: 从文档中解析数据从图像中提取数据结构化所有语言模型响应比JSON模式更可靠和一致开…...

基于Pytorch和yolov8n手搓安全帽目标检测的全过程

一.背景 还是之前的主题&#xff0c;使用开源软件为公司搭建安全管理平台&#xff0c;从视觉模型识别安全帽开始。主要参考学习了开源项目 https://github.com/jomarkow/Safety-Helmet-Detection&#xff0c;我是从运行、训练、标注倒过来学习的。由于工作原因&#xff0c;抽空…...

数据结构与算法基础(C语言版)

参考资料&#xff1a;https://www.bilibili.com/video/BV1GW421A7qY/ 所有代码均已在Ubuntu 20.04.6 LTS中测试通过 逻辑结构与存储结构 逻辑结构 逻辑结构指的是数据对象中数据元素间的相互关系&#xff0c;分为以下四种&#xff1a; 集合结构 集合结构中的数据元素除了同属于…...

Qt监控系统放大招/历经十几年迭代完善/多屏幕辅屏预览/多层级设备树/网络登录和回放

一、前言说明 近期对视频监控系统做了比较大的更新升级&#xff0c;主要就是三点&#xff0c;第一点就是增加了辅屏预览&#xff0c;这个也是好多个客户需要的功能&#xff0c;海康的iVMS-4200客户端就有这个功能&#xff0c;方便在多个屏幕打开不同的视频进行查看&#xff0c…...

使用Locust对MySQL进行负载测试

1.安装环境 pip install locust mysql-connector-python 2.设置测试环境 打开MySQL服务 打开Navicat新建查询&#xff0c;输入SQL语句 3.编写locust脚本 load_mysql.py # codingutf-8 from locust import User, TaskSet, task, between import mysql.connector import ran…...

layui多图上传,tp8后端接收处理

环境&#xff1a;layui2.9.21\thinkphp8.1 前端代码&#xff1a; layui.use([upload, layer], function() {const upload layui.upload;const layer layui.layer;const $ layui.$;// 上传图片const uploadInstImage upload.render({elem: #uploadImage,url: /admin/demo/…...

【Rust自学】8.3. String类型 Pt.1:字符串的创建、更新与拼接

8.3.0. 本章内容 第八章主要讲的是Rust中常见的集合。Rust中提供了很多集合类型的数据结构&#xff0c;这些集合可以包含很多值。但是第八章所讲的集合与数组和元组有所不同。 第八章中的集合是存储在堆内存上而非栈内存上的&#xff0c;这也意味着这些集合的数据大小无需在编…...

Linux(Ubuntu)下ESP-IDF下载与安装完整流程(1)

本文主要看参考官网说明,如下: 快速入门 - ESP32-S3 - — ESP-IDF 编程指南 latest 文档 Linux 和 macOS 平台工具链的标准设置 - ESP32-S3 - — ESP-IDF 编程指南 latest 文档 一、安装准备 为了在ESP32-S3中使用ESP-IDF,需要根据操作系统安装一些软件包。可以参考以下安…...

Android性能优化—— 内存优化

Android 系统中&#xff0c;垃圾回收是自动的&#xff0c;比较隐蔽&#xff0c;这就导致一些内存问题表现的并不明显&#xff0c;出现问题后难以定位。常见的内存问题有内存泄漏、内存溢出&#xff08;Out of Memory&#xff09;、内存抖动等。 我们做内存优化的主要原因有以下…...

【MATLAB第111期】基于MATLAB的sobol全局敏感性分析方法二阶指数计算

【MATLAB第111期】基于MATLAB的sobol全局敏感性分析方法二阶指数计算 一、简介 在MATLAB中计算Sobol二阶效应指数通常涉及到全局敏感性分析&#xff08;Global Sensitivity Analysis, GSA&#xff09;&#xff0c;其中Sobol方法是一种流行的技术&#xff0c;用于评估模型输入…...