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

【GO】k8s 管理系统项目23[前端部分–工作负载-Pod]

k8s 管理系统项目[前端部分–工作负载-Deployment]

1. 代码部分

1.1 准备工作

由于Pod页面和Deployment内容差不多.那么就直接把Deployment的内容复制过来.再做修改.

  1. 替换Deployment为Pod
  2. 替换Deploy为Pod
  3. 替换deployment为pod
  4. 替换deploy为pod
  5. 禁用新增的按钮,删除新增方法,表单
  6. 删除扩容和重启的按钮,方法,抽屉

1.2 Pod前端代码

src/views/workload/Pod.vue

<template><div class="pod"><el-row><!-- 头部1 --><el-col :span="24"><div><el-card class="pod-head-card" shadow="never" :body-style="{padding:'10px'}"><el-row><el-col :span="6"><div><span>命名空间: </span><el-select v-model="namespaceValue" filterable placeholder="请选择"><el-optionv-for="(item, index) in namespaceList":key="index":label="item.metadata.name":value="item.metadata.name"></el-option></el-select></div></el-col><el-col :span="2" :offset="16"><div><el-button style="border-radius:2px;" icon="Refresh" plain @click="getPods()">刷新</el-button></div></el-col></el-row></el-card></div></el-col><!-- 头部2 --><el-col :span="24"><div><el-card class="pod-head-card" shadow="never" :body-style="{padding:'10px'}"><el-row><el-col :span="2"><div><el-button disabled style="border-radius:2px;" icon="Edit" type="primary">创建</el-button></div></el-col><el-col :span="6"><div><el-input class="pod-head-search" clearable placeholder="请输入" v-model="searchInput"></el-input><el-button style="border-radius:2px;" icon="Search" type="primary" plain @click="getPods()">搜索</el-button></div></el-col></el-row></el-card></div></el-col><!-- 数据表格 --><el-col :span="24"><div><el-card class="pod-body-card" shadow="never" :body-style="{padding:'5px'}"><!-- 数据表格 --><!-- row-key 用来定义行数据的key,结合expand-row-keys使用,往expandKeys中增加key来展开行 --><!-- expand-row-keys 展开的行的key数组 --><!-- expand-change 展开触发时,调用这个方法 --><el-tablestyle="width:100%;font-size:12px;margin-bottom:10px;":data="podList"v-loading="appLoading":row-key="getRowKeys":expand-row-keys="expandKeys"@expand-change="expandChange"><el-table-column width="10"></el-table-column><!-- 展开 --><el-table-column type="expand"><!-- 插槽,里面是展开的内容,props标识展开的行的数据 --><template #default="props"><el-tabs v-model="activeName" type="card"><!-- tab容器标签页 --><el-tab-pane label="容器" name="container"><el-card shadow="never" style="border-radius:1px;" :body-style="{padding:'5px'}"><!-- 嵌套数据表格 --><el-tablestyle="width:100%;font-size:12px;":data="props.row.spec.containers"><el-table-column align=left prop="name" label="容器名"></el-table-column><el-table-column align=left prop="image" label="镜像"></el-table-column><el-table-column align=center label="Pod IP"><span>{{ props.row.status.podIP }}</span></el-table-column><el-table-column align=center prop="args" label="启动命令"></el-table-column><el-table-column align=center label="环境变量"><template v-slot="scope"><!-- 气泡弹出框,内容是所有的环境变量 --><el-popover :width="500" placement="left" trigger="hover"><el-table style="width:100%;font-size:12px;" size="mini" :show-header="false" :data="scope.row.env"><el-table-column property="name" label="名称"></el-table-column><el-table-column property="value" label="值"></el-table-column></el-table><template #reference><el-button size="small">此处查看</el-button></template></el-popover></template></el-table-column></el-table></el-card></el-tab-pane><!-- tab日志标签页 --><el-tab-pane label="日志" name="log"><el-card shadow="never" style="border-radius:1px;" :body-style="{padding:'5px'}"><el-row :gutter="10"><el-col :span="3"><!-- 容器选择框 --><el-select size="small" v-model="containerValue" placeholder="请选择"><el-option v-for="item in containerList" :key="item" :value="item"></el-option></el-select></el-col><el-col :span="2"><!-- 查看日志按钮 --><el-button style="border-radius:2px;" size="small" type="primary" @click="getPodLog(props.row.metadata.name)">查看</el-button></el-col><el-col :span="24" style="margin-top: 5px"><!-- 显示日志内容 --><el-card shadow="never" class="pod-body-log-card" :body-style="{padding:'5px'}"><span class="pod-body-log-span">{{ logContent }}</span></el-card></el-col></el-row></el-card></el-tab-pane><!-- tab终端标签页 --><el-tab-pane label="终端" name="shell"><el-card shadow="never" style="border-radius:1px;" :body-style="{padding:'5px'}"><el-row :gutter="10"><el-col :span="3"><!-- 容器选择框 --><el-select size="small" v-model="containerValue" placeholder="请选择"><el-option v-for="item in containerList" :key="item" :value="item"></el-option></el-select></el-col><el-col :span="1"><!-- 连接按钮 --><el-button style="border-radius:2px;" size="small" type="primary" @click="initSocket(props.row)">连接</el-button></el-col><el-col :span="1"><!-- 关闭连接按钮 --><el-button style="border-radius:2px;" size="small" type="danger" @click="closeSocket()">关闭</el-button></el-col><el-col :span="24" style="margin-top: 5px"><el-card shadow="never" class="pod-body-shell-card" :body-style="{padding:'5px'}"><!-- xterm虚拟终端 --><div id="xterm"></div></el-card></el-col></el-row></el-card></el-tab-pane></el-tabs></template></el-table-column><el-table-column align=left label="Pod名"><template v-slot="scope"><!-- 三元运算:expandMap[scope.row.metadata.name]为1则触发关闭(expandedRows为空数组),为0则触发展开expandedRows有值 --><a class="pod-body-podname" @click="expandMap[scope.row.metadata.name] ? expandChange(scope.row, []) : expandChange(scope.row, [scope.row])">{{ scope.row.metadata.name }}</a></template></el-table-column><el-table-column align=center min-width="150" label="节点"><template v-slot="scope"><el-tag v-if="scope.row.spec.nodeName !== undefined" type="warning">{{ scope.row.spec.nodeName }}</el-tag></template></el-table-column><el-table-column align=center label="状态"><template v-slot="scope"><div :class="{'success-dot':scope.row.status.phase == 'Running' || scope.row.status.phase == 'Succeeded', 'warning-dot':scope.row.status.phase == 'Pending', 'error-dot':scope.row.status.phase != 'Running' && scope.row.status.phase != 'Pending' && scope.row.status.phase != 'Succeeded'}"></div><span :class="{'success-status':scope.row.status.phase == 'Running' || scope.row.status.phase == 'Succeeded', 'warning-status':scope.row.status.phase == 'Pending', 'error-status':scope.row.status.phase != 'Running' && scope.row.status.phase != 'Pending' && scope.row.status.phase != 'Succeeded'}">{{ scope.row.status.phase }} </span></template></el-table-column><el-table-column align=center label="重启数"><template v-slot="scope"><span>{{ restartTotal(scope) }} </span></template></el-table-column><el-table-column align=center min-width="100" label="创建时间"><template v-slot="scope"><el-tag type="info">{{ timeTrans(scope.row.metadata.creationTimestamp) }} </el-tag></template></el-table-column><el-table-column align=center label="操作" width="200"><template v-slot="scope"><el-button size="small" style="border-radius:2px;" icon="Edit" type="primary" plain @click="getPodDetail(scope)">YAML</el-button><el-button size="small" style="border-radius:2px;" icon="Delete" type="danger" @click="handleConfirm(scope, '删除', delPod)">删除</el-button></template></el-table-column></el-table><el-paginationclass="pod-body-pagination"background@size-change="handleSizeChange"@current-change="handleCurrentChange":current-page="currentPage":page-sizes="pagesizeList":page-size="pagesize"layout="total, sizes, prev, pager, next, jumper":total="podTotal"></el-pagination></el-card></div></el-col></el-row><!-- 展示YAML信息的弹框 --><el-dialog title="YAML信息" v-model="yamlDialog" width="45%" top="5%"><codemirror:value="contentYaml"border:options="cmOptions"height="500"style="font-size:14px;"@change="onChange"></codemirror><template #footer><span class="dialog-footer"><el-button @click="yamlDialog = false">取 消</el-button><el-button type="primary" @click="updatePod()">更 新</el-button></span></template></el-dialog></div>
</template><script>
import common from "../common/Config";
import httpClient from '../../utils/request';
//引入xterm终端依赖
import { Terminal } from 'xterm';
import { FitAddon } from 'xterm-addon-fit';
import 'xterm/css/xterm.css';
import 'xterm/lib/xterm.js';
import yaml2obj from 'js-yaml';
import json2yaml from 'json2yaml';
export default {data() {return {//编辑器配置cmOptions: common.cmOptions,contentYaml: '',//分页currentPage: 1,pagesize: 10,pagesizeList: [10, 20, 30],//searchInput: '',namespaceValue: 'default',namespaceList: [],namespaceListUrl: common.k8sNamespaceList,appLoading: false,podList: [],podTotal: 0,getPodsData: {url: common.k8sPodList,params: {filter_name: '',namespace: '',page: '',limit: '',}},//详情podDetail: {},getPodDetailData: {url: common.k8sPodDetail,params: {pod_name: '',namespace: ''}},//yaml更新yamlDialog: false,updatePodData: {url: common.k8sPodUpdate,params: {namespace: '',content: ''}},//删除delPodData: {url: common.k8sPodDel,params: {pod_name: '',namespace: ''}},//expand扩展activeName: 'container',expandKeys: [],expandMap: {},//日志containerList: {},containerValue: '',getPodContainerData: {url: common.k8sPodContainer,params: {pod_name: '',namespace: ''}},logContent: '',getPodLogData: {url: common.k8sPodLog,params: {container_name: '',pod_name: '',namespace: ''}},//terminalterm: null,socket: null}},methods: {transYaml(content) {return json2yaml.stringify(content)},transObj(content) {return yaml2obj.load(content)},onChange(val) {this.contentYaml = val},handleSizeChange(size) {this.pagesize = size;this.getPods()},handleCurrentChange(currentPage) {this.currentPage = currentPage;this.getPods()},handleClose(done) {this.$confirm('确认关闭?').then(() => {done();}).catch(() => {});},ellipsis(value) {return value.length>15?value.substring(0,15)+'...':value},timeTrans(timestamp) {let date = new Date(new Date(timestamp).getTime() + 8 * 3600 * 1000)date = date.toJSON();date = date.substring(0, 19).replace('T', ' ')return date},restartTotal(e) {let index, sum = 0let containerStatuses = e.row.status.containerStatusesfor ( index in containerStatuses) {sum = sum + containerStatuses[index].restartCount}return sum},getNamespaces() {httpClient.get(this.namespaceListUrl).then(res => {this.namespaceList = res.data.items}).catch(res => {this.$message.error({message: res.msg})})},getPods() {this.appLoading = truethis.getPodsData.params.filter_name = this.searchInputthis.getPodsData.params.namespace = this.namespaceValuethis.getPodsData.params.page = this.currentPagethis.getPodsData.params.limit = this.pagesizehttpClient.get(this.getPodsData.url, {params: this.getPodsData.params}).then(res => {this.podList = res.data.itemsthis.podTotal = res.data.total}).catch(res => {this.$message.error({message: res.msg})})this.appLoading = false},getPodDetail(e) {this.getPodDetailData.params.pod_name = e.row.metadata.namethis.getPodDetailData.params.namespace = this.namespaceValuehttpClient.get(this.getPodDetailData.url, {params: this.getPodDetailData.params}).then(res => {this.podDetail = res.datathis.contentYaml = this.transYaml(this.podDetail)this.yamlDialog = true}).catch(res => {this.$message.error({message: res.msg})})},updatePod() {let content = JSON.stringify(this.transObj(this.contentYaml))this.updatePodData.params.namespace = this.namespaceValuethis.updatePodData.params.content = contenthttpClient.put(this.updatePodData.url, this.updatePodData.params).then(res => {this.$message.success({message: res.msg})}).catch(res => {this.$message.error({message: res.msg})})this.yamlDialog = false},delPod(e) {this.delPodData.params.pod_name = e.row.metadata.namethis.delPodData.params.namespace = this.namespaceValuehttpClient.delete(this.delPodData.url, {data: this.delPodData.params}).then(res => {this.getPods()this.$message.success({message: res.msg})}).catch(res => {this.$message.error({message: res.msg})})},handleConfirm(obj, operateName, fn) {this.confirmContent = '确认继续 ' + operateName + ' 操作吗?'this.$confirm(this.confirmContent,'提示',{confirmButtonText: '确定',cancelButtonText: '取消',}).then(() => {fn(obj)}).catch(() => {this.$message.info({message: '已取消操作'})})},getRowKeys(row) {return row.metadata.name},//row,展开的当前行的数据//expandedRows,展开的所有行的数据组成的数组,但是这里用法是只会有一行,也就是数组长度永远为1expandChange(row, expandedRows) {//初始化变量//清空expandKeys,代表关闭所有展开的行this.expandKeys = []//清空日志内容this.logContent= ''//清空containervalue,展开时不显示上次的值this.containerValue = ''//将tab标签页顶部页面调成容器this.activeName = 'container'//expandedRows.length == 1表示展开,expandedRows.length == 0 表示关闭if (expandedRows.length > 0) {//expandMap key表示展开过的行的key,值为1表示展开标记,值为0表示关闭标记//expandMap用于数据表格点击name的展开,用于判断这一行是展开还是关闭的行为this.expandMap[row.metadata.name] = 1//将expandMap除了row.metadata.name,其他key的值都置为0this.setExpandMap(row.metadata.name)//这里才是真正的展开,将row.metadata.name添加到expandKeys数组中展开,然后执行方法获取containerthis.expandKeys.push(row.metadata.name)this. getPodContainer(row)} else {//关闭标记this.expandMap[row.metadata.name] = 0}},//匹配expandMap中podName,不相等的全都置为0,意为除了podName这行,其他全都标记关闭setExpandMap(podName) {let keyfor ( key in this.expandMap ) {key !== podName ? this.expandMap[key] = 0 : ''}},getPodContainer(row) {this.getPodContainerData.params.pod_name = row.metadata.namethis.getPodContainerData.params.namespace = this.namespaceValuehttpClient.get(this.getPodContainerData.url, {params: this.getPodContainerData.params}).then(res => {this.containerList = res.datathis.containerValue = this.containerList[0]}).catch(res => {this.$message.error({message: res.msg})})},getPodLog(podName) {this.getPodLogData.params.pod_name = podNamethis.getPodLogData.params.container_name = this.containerValuethis.getPodLogData.params.namespace = this.namespaceValuehttpClient.get(this.getPodLogData.url, {params: this.getPodLogData.params}).then(res => {this.logContent = res.data}).catch(res => {this.$message.error({message: res.msg})})},initTerm() {//初始化xterm实例this.term = new Terminal({rendererType: 'canvas', //渲染类型rows: 30, //行数cols: 110,convertEol: false, //启用时,光标将设置为下一行的开头scrollback: 10, //终端中的回滚量disableStdin: false, //是否应禁用输入cursorStyle: 'underline', //光标样式cursorBlink: true, //光标闪烁theme: {foreground: 'white', //字体background: '#060101', //背景色cursor: 'help' //设置光标}});//绑定domthis.term.open(document.getElementById('xterm'))//终端适应父元素大小const fitAddon = new FitAddon()this.term.loadAddon(fitAddon)fitAddon.fit();//获取终端的焦点this.term.focus();let _this = this; //一定要重新定义一个this,不然this指向会出问题//onData方法用于定义输入的动作this.term.onData(function (key) {// 这里key值是输入的值,数据格式就是后端定义的 {"operation":"stdin","data":"ls"}let msgOrder = {operation: 'stdin',data: key,};//发送数据_this.socket.send(JSON.stringify(msgOrder));});//发送resize请求let msgOrder2 = {operation: 'resize',cols: this.term.cols,rows: this.term.rows,};this.socket.send(JSON.stringify(msgOrder2))},//初始化websocketinitSocket(row) {//定义websocket连接地址let terminalWsUrl = common.k8sTerminalWs + "?pod_name=" + row.metadata.name + "&container_name=" + this.containerValue + "&namespace=" + this.namespaceValue//实例化this.socket = new WebSocket(terminalWsUrl);//关闭连接时的方法this.socketOnClose();//建立连接时的方法this.socketOnOpen();//接收消息的方法this.socketOnMessage();//报错时的方法this.socketOnError();},socketOnOpen() {this.socket.onopen = () => {//简历连接成功后,初始化虚拟终端this.initTerm()}},socketOnMessage() {this.socket.onmessage = (msg) => {//接收到消息后将字符串转为对象,输出data内容let content = JSON.parse(msg.data)this.term.write(content.data)}},socketOnClose() {this.socket.onclose = () => {//关闭连接后打印在终端里this.term.write("链接已关闭")}},socketOnError() {this.socket.onerror = () => {console.log('socket 链接失败')}},//关闭连接closeSocket() {//若没有实例化,则不需要关闭if (this.socket === null) {return}this.term.write("链接关闭中。。。")this.socket.close()}},watch: {namespaceValue: {handler() {localStorage.setItem('namespace', this.namespaceValue)this.currentPage = 1this.getPods()}},//若tab标签页切到日志,则重新加载日志内容activeName: {handler() {if ( this.activeName == 'log' ) {this.expandKeys.length == 1 ? this.getPodLog(this.expandKeys[0]) : ''}}}},beforeMount() {if (localStorage.getItem('namespace') !== undefined && localStorage.getItem('namespace') !== null) {this.namespaceValue = localStorage.getItem('namespace')}this.getNamespaces()this.getPods()},beforeUnmount() {//若websocket连接没有关闭,则在改生命周期关闭if ( this.socket !== null ) {this.socket.close()}},
}
</script><style scoped>
.pod-head-card,.pod-body-card {border-radius: 1px;margin-bottom: 5px;
}
.pod-head-search {width:160px;margin-right:10px;
}
.pod-body-podname {color: #4795EE;
}
.pod-body-podname:hover {color: rgb(84, 138, 238);cursor: pointer;font-weight: bold;
}
/* pod状态栏圆点的css实现 */
.success-dot{display:inline-block;width: 7px;height:7px;background: rgb(27, 202, 21);border-radius:50%;border:1px solid rgb(27, 202, 21);margin-right: 10px;
}
.warning-dot{display:inline-block;width: 7px;height:7px;background: rgb(233, 200, 16);border-radius:50%;border:1px solid rgb(233, 200, 16);margin-right: 10px;
}
.error-dot{display:inline-block;width: 7px;height:7px;background: rgb(226, 23, 23);border-radius:50%;border:1px solid rgb(226, 23, 23);margin-right: 10px;
}
.success-status {color: rgb(27, 202, 21);
}
.warning-status {color: rgb(233, 200, 16);
}
.error-status {color: rgb(226, 23, 23);
}
/deep/ .el-tabs__item {font-size: 12px;
}
/deep/ .el-tabs__header {margin-bottom: 8px;
}
.pod-body-log-card, .pod-body-shell-card {border-radius:1px;height:600px;overflow:auto;background-color: #060101;
}
.pod-body-log-card {color: aliceblue;
}
.pod-body-log-span {white-space:pre;
}
</style>

2. 功能测试

2.1 获取pod清单和分页

请添加图片描述
请添加图片描述

2.2 获取pod详细信息

2.2.1 pod详情

请添加图片描述

2.2.2 Pod环境变量

请添加图片描述

2.2.2 Pod日志

请添加图片描述

2.2.4 控制台

请添加图片描述

2.3 Yaml

请添加图片描述

2.4 删除Pod

请添加图片描述

请添加图片描述

请添加图片描述

3. 两个小bug

3.1 router错误

之前写后端路由时/api/k8s/pod/detail写成了/api/k8s/pods/detail

造成获取yaml时无法获得消息.

尝试用api调用发现问题,修改了router下的路由问题解决

3.2 翻页的问题

之前后端GetPods中取total写成了

	filtered := selectableData.Filter()// 排序和分页data := filtered.Sort().Paginate()total := len(data.GenericDataList)

改了下问题解决

	filtered := selectableData.Filter()total := len(filtered.GenericDataList)// 排序和分页data := filtered.Sort().Paginate()

相关文章:

【GO】k8s 管理系统项目23[前端部分–工作负载-Pod]

k8s 管理系统项目[前端部分–工作负载-Deployment] 1. 代码部分 1.1 准备工作 由于Pod页面和Deployment内容差不多.那么就直接把Deployment的内容复制过来.再做修改. 替换Deployment为Pod替换Deploy为Pod替换deployment为pod替换deploy为pod禁用新增的按钮,删除新增方法,表…...

rabbitmq在linux系统下安装步骤

第一步&#xff1a;登录官网 官网地址&#xff1a;www.rabbitmq.com,点击Get Started 重要信息&#xff1a;RabbitMQ Tutorials手册&#xff0c;描述了工作模式 第二步&#xff1a;点击Download Installation下载 重要信息&#xff1a;rabbitmq是用erlang语言开发的&#xff0…...

阿里测试员晒薪资条,看完真的扎心了...

前几天&#xff0c;有位老粉私信我&#xff0c;说看到某95后学弟晒出阿里的工资单&#xff0c;他是真酸了…想狠补下技术&#xff0c;努力冲一把大厂。 为了帮到他&#xff0c;也为了大家能在最短的时间内做面试复习&#xff0c;我把软件测试面试系列都汇总在这一篇文章了。 …...

内网渗透辅助工具集Yasso

目录 介绍 工具优势 程序功能模块 目前已有用功能模块 使用例子 工具下载</...

Spring笔记(1):概述

1、什么是Spring&#xff1f; Spring是最受欢迎的企业级Java应用程序开发框架&#xff0c;使用它创建性能好、易于测试、可重用的代码。Spring是一种轻量级的框架。Spring框架的核心特性是开发任何Java应用程序&#xff0c;其目标是使得J2EE开发变得更容易&#xff0c;通过启用…...

工程机械焊接件焊接结构件三维扫描检测外观质量控制-CASAIM三维扫描检测仪

焊接已发展为制造业中的一种重要的加工方法&#xff0c;广泛应用于航空、航天、冶金、石油、汽车制造以及国防等领域。工程机械焊接件品种繁多、几何形状复杂&#xff0c;焊接件质量的好坏将直接影响到产品的使用寿命长短。对焊缝表面尺寸测量及评定表面焊缝缺陷时&#xff0c;…...

使用linux部署项目步骤

文章目录前言一、服务器环境配置二、数据库导入三、项目打包1、修改项目中的访问路径2、修改db.properties的数据库访问路径3、打包4、修改配置&#xff0c;启动服务四、测试总结前言 今天学习了在服务器中部署项目&#xff0c;记录一下 一、服务器环境配置 首先要安装VMware&…...

pt02-list-tuple-dir

容器类型 通用操作 数学运算符 (1) 用于拼接两个容器 (2) 用原容器与右侧容器拼接,并重新绑定变量 (3) * 重复生成容器元素 (4) * 用原容器生成重复元素, 并重新绑定变量 (5) !&#xff1a;依次比较两个容器中元素,一但不同则返回比较结果。< < > > 意…...

高端电器新十年,求解「竞速突围」

竞争激烈的高端电器品牌们&#xff0c;平时王不见王&#xff0c;但也有例外。海尔、博西、海信、创维、方太、老板等等近乎中国电器行业所有一线品牌副总裁级别以上高层&#xff0c;2月22日都现身于上海&#xff0c;来参加一场由红星美凯龙攒起来的高端电器局&#xff0c;2023中…...

[Android Studio] Android Studio使用keytool工具读取Debug 调试版数字证书以及release 发布版数字证书

&#x1f7e7;&#x1f7e8;&#x1f7e9;&#x1f7e6;&#x1f7ea; Android Debug&#x1f7e7;&#x1f7e8;&#x1f7e9;&#x1f7e6;&#x1f7ea; Topic 发布安卓学习过程中遇到问题解决过程&#xff0c;希望我的解决方案可以对小伙伴们有帮助。 &#x1f4cb;笔记目…...

2023年金三银四必备软件测试常见面试题1500问!!!【测试思维篇】

五、测试思维5.1 打电话功能怎么去测&#xff1f;我们会从几个方面去测试&#xff1a;界面、功能、兼容性、易用性、安全、性能、异常。1&#xff09;界面我们会测试下是否跟界面原型图一致&#xff0c;考虑浏览器不同显示比例&#xff0c;屏幕分辨率。2&#xff09;功能&#…...

推荐四款自用的电脑神器

作为一个经常鼓捣电脑的小编来说&#xff0c;无论是写文章、截图、办公方面都缺少不了一些好用的软件&#xff0c;今天就给大家盘点一些我推荐用的办公效率工具&#xff0c;让你的效率事半功倍。 写文章神器 以前写文章一直是在公众号编辑上直接写的&#xff0c;缺点就是格式有…...

CSDN 竞赛 32 期

CSDN 竞赛 32 期1、题目名称&#xff1a;传奇霸业2、题目名称&#xff1a;严查枪火3、题目名称&#xff1a;蚂蚁家族4、题目名称&#xff1a;运输石油小结1、题目名称&#xff1a;传奇霸业 传奇霸业&#xff0c;是兄弟就来干。 小春(HP a)遇到了一只黄金哥布林(HP x)。 小春每…...

【路径规划】基于前向动态规划算法在地形上找到最佳路径(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…...

spring boot maven打包jar包太大,怎么办?这个方法解决你的烦恼

在springboot maven项目中&#xff0c;有两种打包方式&#xff0c;一种是war包&#xff0c;一种是jar&#xff0c;今天我们讲一下jar的打包方式。但是在jar包打包只要我们发现&#xff0c;我们的项目jar太大了&#xff0c;每次上传到服务器的时候非常的慢&#xff0c;接下来我们…...

Spring之AOP理解及使用

文章目录AOP是什么AOPSpring的通知类型1.Before通知2. AfterReturning通知3.AfterThrowing通知4. After通知5. Around通知动态代理JDK动态代理CGLib动态代理动态代理的代码展示AOP使用切面类的配置最后大家好&#xff0c;我是Leo&#xff01;今天给大家带来的是关于Spring AOP的…...

微信小程序和webview使用postMessage交互

小程序和webview能交互&#xff0c;但是没有你想的那个完美小程序向webview传递参数只能使用url携带参数webview向小程序传递参数可以使用postMessage, 但是注意了&#xff0c;postMessage只会在特定的时机执行&#xff0c;请看官方文档由此可见&#xff0c;如果你想点击webvie…...

pytorch-自动求导机制,构建计算图进行反向传播,需要注意inplace操作导致的报错,梯度属性变化

PyTorch 作为一个深度学习平台&#xff0c;在深度学习任务中比 NumPy 这个科学计算库强在哪里呢&#xff1f;一是 PyTorch 提供了自动求导机制&#xff0c;二是对 GPU 的支持。由此可见&#xff0c;自动求导 (autograd) 是 PyTorch&#xff0c;乃至其他大部分深度学习框架中的重…...

【Project】项目管理软件学习笔记

一、前言使用Project制定项目计划步骤大致如下&#xff1a;以Project2013为例&#xff0c;按照上图步骤指定项目计划。二、实施2.1 创建空白项目点击文件——新建——空白项目&#xff0c;即完成了空白项目的创建&#xff0c;在此我把该项目保存为60mm项目管理.mpp&#xff0c;…...

【算法设计-分治思想】快速幂与龟速乘

文章目录1. 快速幂2. 龟速乘3. 快速幂取模4. 龟速乘取模5. 快速幂取模优化1. 快速幂 算法原理&#xff1a; 计算 311&#xff1a; 311 (35)2 x 335 (32)2 x 332 3 x 3仅需计算 3 次&#xff0c;而非 11 次 计算 310&#xff1a; 310 (35)235 (32)2 x 332 3 x 3仅需计算…...

IDEA运行Tomcat出现乱码问题解决汇总

最近正值期末周&#xff0c;有很多同学在写期末Java web作业时&#xff0c;运行tomcat出现乱码问题&#xff0c;经过多次解决与研究&#xff0c;我做了如下整理&#xff1a; 原因&#xff1a; IDEA本身编码与tomcat的编码与Windows编码不同导致&#xff0c;Windows 系统控制台…...

【JavaEE】-- HTTP

1. HTTP是什么&#xff1f; HTTP&#xff08;全称为"超文本传输协议"&#xff09;是一种应用非常广泛的应用层协议&#xff0c;HTTP是基于TCP协议的一种应用层协议。 应用层协议&#xff1a;是计算机网络协议栈中最高层的协议&#xff0c;它定义了运行在不同主机上…...

前端倒计时误差!

提示:记录工作中遇到的需求及解决办法 文章目录 前言一、误差从何而来?二、五大解决方案1. 动态校准法(基础版)2. Web Worker 计时3. 服务器时间同步4. Performance API 高精度计时5. 页面可见性API优化三、生产环境最佳实践四、终极解决方案架构前言 前几天听说公司某个项…...

《从零掌握MIPI CSI-2: 协议精解与FPGA摄像头开发实战》-- CSI-2 协议详细解析 (一)

CSI-2 协议详细解析 (一&#xff09; 1. CSI-2层定义&#xff08;CSI-2 Layer Definitions&#xff09; 分层结构 &#xff1a;CSI-2协议分为6层&#xff1a; 物理层&#xff08;PHY Layer&#xff09; &#xff1a; 定义电气特性、时钟机制和传输介质&#xff08;导线&#…...

visual studio 2022更改主题为深色

visual studio 2022更改主题为深色 点击visual studio 上方的 工具-> 选项 在选项窗口中&#xff0c;选择 环境 -> 常规 &#xff0c;将其中的颜色主题改成深色 点击确定&#xff0c;更改完成...

【项目实战】通过多模态+LangGraph实现PPT生成助手

PPT自动生成系统 基于LangGraph的PPT自动生成系统&#xff0c;可以将Markdown文档自动转换为PPT演示文稿。 功能特点 Markdown解析&#xff1a;自动解析Markdown文档结构PPT模板分析&#xff1a;分析PPT模板的布局和风格智能布局决策&#xff1a;匹配内容与合适的PPT布局自动…...

2025 后端自学UNIAPP【项目实战:旅游项目】6、我的收藏页面

代码框架视图 1、先添加一个获取收藏景点的列表请求 【在文件my_api.js文件中添加】 // 引入公共的请求封装 import http from ./my_http.js// 登录接口&#xff08;适配服务端返回 Token&#xff09; export const login async (code, avatar) > {const res await http…...

Spring数据访问模块设计

前面我们已经完成了IoC和web模块的设计&#xff0c;聪明的码友立马就知道了&#xff0c;该到数据访问模块了&#xff0c;要不就这俩玩个6啊&#xff0c;查库势在必行&#xff0c;至此&#xff0c;它来了。 一、核心设计理念 1、痛点在哪 应用离不开数据&#xff08;数据库、No…...

GC1808高性能24位立体声音频ADC芯片解析

1. 芯片概述 GC1808是一款24位立体声音频模数转换器&#xff08;ADC&#xff09;&#xff0c;支持8kHz~96kHz采样率&#xff0c;集成Δ-Σ调制器、数字抗混叠滤波器和高通滤波器&#xff0c;适用于高保真音频采集场景。 2. 核心特性 高精度&#xff1a;24位分辨率&#xff0c…...

Mysql中select查询语句的执行过程

目录 1、介绍 1.1、组件介绍 1.2、Sql执行顺序 2、执行流程 2.1. 连接与认证 2.2. 查询缓存 2.3. 语法解析&#xff08;Parser&#xff09; 2.4、执行sql 1. 预处理&#xff08;Preprocessor&#xff09; 2. 查询优化器&#xff08;Optimizer&#xff09; 3. 执行器…...