vue2使用antv/g6-editor实现可拖拽流程图
依赖下载
照着这个引入就好,然后npm install
源码
<template><div id="vue-g6-editor"><el-row><el-col :span="24"></el-col></el-row><!-- 工具栏 --><el-row><el-col :span="24"><div id="toolbar"><i data-command="save" class="command fa fa-floppy-o" title="保存"></i><i class="fa fa-history" title="历史数据" @click="readHistoryData"></i><i class="fa fa-hdd-o" title="上传数据" @click="readUploadData"></i><i class="fa fa-download" title="另存为文件" @click="saveAsFile"></i><i class="fa fa-picture-o" title="另存为图片" @click="openSaveAsImageDialog"></i><i data-command="undo" class="command fa fa-undo" title="撤销"></i><i data-command="redo" class="command fa fa-repeat" title="重做"></i><i data-command="delete" class="command fa fa-trash-o" title="删除"></i><i data-command="zoomOut" class="command fa fa-search-minus" title="缩小"></i><i data-command="zoomIn" class="command fa fa-search-plus" title="放大"></i><i data-command="clear" class="command fa fa-eraser" title="清除画布"></i><i data-command="toFront" class="command fa fa-arrow-up" title="提升层级"></i><i data-command="toBack" class="command fa fa-arrow-down" title="下降层级"></i><i data-command="selectAll" class="command fa fa-check-square-o" title="全选"></i><i data-command="copy" class="command fa fa-files-o" title="复制"></i><i data-command="paste" class="command fa fa-clipboard" title="粘贴"></i><i data-command="autoZoom" class="command fa fa-expand" title="实际大小"></i><i data-command="resetZoom" class="command fa fa-compress" title="适应页面"></i><i data-command="addGroup" class="command fa fa-object-group" title="组合"></i><i data-command="unGroup" class="command fa fa-object-ungroup" title="取消组合"></i><i data-command="multiSelect" class="command fa fa fa-crop" title="多选"></i></div></el-col></el-row><!-- 元素面板 + 画布 + 属性栏 --><el-row><!-- 元素面板 --><el-col :span="2"><div id="itempannel"><!-- 开始节点 --><div id="startNode" class="getItem" data-type="node" data-shape="flow-circle" data-size="72*72"data-label="开始节点" data-color="#FA8C16" data-nodeType="startNode"><img draggable="false" :src="startNodeSVGUrl" alt srcset /></div><!-- 常规节点 --><div id="regularNode" class="getItem" data-type="node" data-size="100*50" data-label="常规节点"data-color="#1890ff"><img draggable="false" :src="regularNodeSVGUrl" alt srcset /></div><!-- 条件节点 --><div id="judgeNode" class="getItem" data-type="node" data-shape="flow-rhombus" data-size="80*80"data-label="条件节点" data-color="#13C2C2"><img draggable="false" :src="conditionNodeSVGUrl" /></div><!-- 结束节点 --><div id="endNode" class="getItem" data-type="node" data-shape="flow-circle" data-size="80*80"data-label="结束节点" data-color="#FA8C16" data-nodeType="endNode"><img draggable="false" :src="endNodeSVGUrl" /></div></div></el-col><!-- 画布 --><el-col :span="18"><el-col :span="24"><div id="page"><div class="controltab">ab</div></div></el-col></el-col><!-- 属性栏 --><el-col :span="4"><section class="right-part"><div id="detailpannel"><!-- 节点属性栏 --><div id="nodeAttributeBar" class="pannel" data-status="node-selected"><div class="title">节点属性</div><div class="main"><el-form :model="nodeAttributeForm" label-position="top" label-width="80px"><el-form-item label="节点文本"><el-input v-model="nodeAttributeForm.label" @change="saveNodeAttribute"></el-input></el-form-item><el-form-item label="宽度"><el-input v-model="nodeAttributeForm.width" @change="saveNodeAttribute"></el-input></el-form-item><el-form-item label="高度"><el-input v-model="nodeAttributeForm.height" @change="saveNodeAttribute"></el-input></el-form-item><el-form-item label="颜色"><el-color-picker v-model="nodeAttributeForm.color" @change="saveNodeAttribute"></el-color-picker></el-form-item></el-form></div></div><!-- 边属性栏 --><div id="edgeAttributeBar" class="pannel" data-status="edge-selected"><div class="title">边属性</div><div class="main"><el-form :model="edgeAttributeForm" label-position="top" label-width="80px"><el-form-item label="边文本"><el-input v-model="edgeAttributeForm.label" @change="saveEdgeAttribute"></el-input></el-form-item><el-form-item label="边文本"><el-select v-model="edgeAttributeForm.shape" @change="saveEdgeAttribute"><el-option label="流程图折线" value="flow-polyline"></el-option><el-option label="流程图圆⻆折线" value="flow-polyline-round"></el-option><el-option label="流程图曲线" value="flow-smooth"></el-option></el-select></el-form-item></el-form></div></div><div id="groupAttributeBar" class="pannel" data-status="group-selected"><div class="title">群组属性栏</div></div><div id="canvasAttributeBar" class="pannel" data-status="canvas-selected"><div class="title">画布属性栏</div><div class="main"><el-form label-width="80px" label-position="right"><el-form-item label="网格对齐"><el-checkbox v-model="canvasAttributeForm.grid" @change="toggleGridShowStatus"></el-checkbox></el-form-item></el-form></div></div><div id="multiAttributeBar" class="pannel" data-status="multi-selected"><div class="title">多选时属性栏</div></div></div><!-- 缩略图 --><div id="minimap"><div class="title">缩略图</div></div></section></el-col></el-row><!-- 弹窗 --><article><!-- 下载图片 --><section class="save-as-image-dialog"><el-dialog title="下载图片" :visible.sync="saveAsImageDialogVisible" width="360px"><el-form label-width="100px" label-position="top"><el-form-item label="选择图片格式"><el-select v-model="saveAsImageFormat"><el-option label="jpg" value="jpg"><span style="float: left;">jpg</span><span style="float: right; color: #8492a6; font-size: 13px;">白色背景</span></el-option><el-option label="png" value="png"><span style="float: left;">png</span><span style="float: right; color: #8492a6; font-size: 13px;">透明背景</span></el-option></el-select></el-form-item></el-form><span slot="footer"><el-button @click="saveAsImageDialogVisible = false">取 消</el-button><el-button type="primary" @click="saveAsImage">确 定</el-button></span></el-dialog></section></article><!-- 右键菜单 --><section><div id="contextmenu"><div data-status="node-selected" class="menu"><el-button data-command="copy" class="command">复制</el-button><el-button data-command="paste" class="command">粘贴</el-button><el-button data-command="delete" class="command">删除</el-button></div><div data-status="edge-selected" class="menu"><el-button data-command="delete" class="command">删除</el-button></div><div data-status="group-selected" class="menu"><el-button data-command="copy" class="command">复制</el-button><el-button data-command="paste" class="command">粘贴</el-button><el-button data-command="unGroup" class="command">取消组合</el-button><el-button data-command="delete" class="command">删除</el-button></div><div data-status="canvas-selected" class="menu"><el-button data-command="undo" class="command">撤销</el-button><el-button data-command="redo" class="command disable">重做</el-button></div><div data-status="multi-selected" class="menu"><el-button data-command="copy" class="command">复制</el-button><el-button data-command="paste" class="command">粘贴</el-button><el-button data-command="addGroup" class="command">组合</el-button></div></div></section></div></template>
<script>
import G6Editor from '@antv/g6-editor'
import mixin from '../mixin'
import { construct } from 'netflix-conductor-json-tree/dist/index'
export default {name: 'VueG6Editor',mixins: [mixin],data() {return {// 节点属性表单nodeAttributeForm: {label: '',width: '',height: ''},// 节点属性表单edgeAttributeForm: {label: ''},// 画布属性栏表单canvasAttributeForm: {grid: true,cell: 20},// SVG节点图片URL地址startNodeSVGUrl: require('../../../assets/start-node.svg'),endNodeSVGUrl: require('../../../assets/end-node.svg'),regularNodeSVGUrl: require('../../../assets/regular-node.svg'),conditionNodeSVGUrl: require('../../../assets/condition-node.svg'),modelNodeSVGUrl: 'https://gw.alipayobjects.com/zos/rmsportal/rQMUhHHSqwYsPwjXxcfP.svg',// 编辑器editor: null,saveAsImageDialogVisible: false,saveAsImageFormat: 'jpg'}},mounted() {this.initG6Editor()},methods: {// 初始化initG6Editor() {const _this = thisconst editor = new G6Editor()this.editor = editorG6Editor.track(false)const Command = G6Editor.Command// 注册新命令saveCommand.registerCommand('save', {// 禁止保存命令进入队列queue: false,// 命令是否可用enable: (editor) => {return true},// 正向命令execute(editor) {const needSaveData = editor.getCurrentPage().save()console.log(needSaveData)localStorage.setItem('flowData', JSON.stringify(needSaveData))_this.save(needSaveData)_this.$message.success('数据已保存')},// 反向命令back(editor) {console.log('反向命令')console.log(editor)},// 快捷键:Ctrl + SshortcutCodes: [['metaKey', 's'],['ctrlKey', 's']]})// 画布const flow = new G6Editor.Flow({graph: {container: 'page'},align: {line: {// 对齐线颜色stroke: '#FA8C16',// 对齐线粗细lineWidth: 1},// 开启全方位对齐item: true,// 网格对齐grid: true},grid: {// 网孔尺寸cell: 18},shortcut: {// 开启自定义命令保存的快捷键save: true}})window.flow = flow// 设置边flow.getGraph().edge({shape: 'flow-polyline'})// 元素面板栏const itempannel = new G6Editor.Itempannel({container: 'itempannel'})// 工具栏const toolbar = new G6Editor.Toolbar({container: 'toolbar'})// 属性栏const detailpannel = new G6Editor.Detailpannel({container: 'detailpannel'})// 缩略图let minimapWidth = getComputedStyle(document.querySelector('.right-part')).widthminimapWidth = Number(minimapWidth.replace(/px$/, ''))const minimap = new G6Editor.Minimap({container: 'minimap',width: minimapWidth,height: 200})// 右键菜单const contextmenu = new G6Editor.Contextmenu({container: 'contextmenu'})// 挂载以上组件到Editoreditor.add(flow)editor.add(itempannel)editor.add(toolbar)editor.add(detailpannel)editor.add(minimap)editor.add(contextmenu)// 挂载到window,方便调试window.editor = editor// 获取当前画布const currentPage = editor.getCurrentPage()currentPage.on('afterchange', (e) => {if (e.action === 'add') {if (e.model.nodetype === 'startNode' || e.model.nodetype === 'endNode') {const nodes = this.editor.getCurrentPage().getNodes()for (const item of nodes) {if (item.model.nodetype === e.model.nodetype && item.model.id !== e.model.id) {this.editor.getCurrentPage().remove(e.item)this.$message.warning('只能有一个开始节点或结束节点')}}}}})// 监听(选择对象后)事件currentPage.on('afteritemselected', (ev) => {console.log('打印所选对象属性', ev.item)console.log('打印所选对象数据模型', ev.item.model)const selectedItemDataModel = ev.item.model// 如果选择的对象是节点if (ev.item.isNode) {this.nodeAttributeForm.label = selectedItemDataModel.labelthis.nodeAttributeForm.width = selectedItemDataModel.size.split('*')[0]this.nodeAttributeForm.height = selectedItemDataModel.size.split('*')[1]this.nodeAttributeForm.color = selectedItemDataModel.color}// 如果选择的对象是边if (ev.item.isEdge) {ev.item.graph.edge({shape: 'flow-polyline-round'})this.edgeAttributeForm.label = selectedItemDataModel.labelthis.edgeAttributeForm.shape = selectedItemDataModel.shape}})// 监听(删除后)事件currentPage.on('afterdelete', (ev) => { })},// 打开保存为图片弹窗openSaveAsImageDialog() {this.saveAsImageDialogVisible = true},// 开启/关闭网格对齐toggleGridShowStatus(value) {if (value) {this.editor.getCurrentPage().showGrid()} else {this.editor.getCurrentPage().hideGrid()}},// 保存为图片saveAsImage() {let newCanvasif (this.saveAsImageFormat === 'jpg') {const canvas = this.editor.getCurrentPage().saveImage()newCanvas = document.createElement('canvas')newCanvas.width = canvas.widthnewCanvas.height = canvas.heightconst newContext = newCanvas.getContext('2d')newContext.fillStyle = '#fff'newContext.fillRect(0, 0, newCanvas.width, newCanvas.height)newContext.drawImage(canvas, 0, 0)}if (this.saveAsImageFormat === 'png') {newCanvas = this.editor.getCurrentPage().saveImage()}const imageDataURL = newCanvas.toDataURL()const downloadLink = document.createElement('a')downloadLink.download = '图片.jpg'downloadLink.href = imageDataURLdocument.body.appendChild(downloadLink)downloadLink.click()document.body.removeChild(downloadLink)this.saveAsImageDialogVisible = false},// 保存为文件saveAsFile() {const jsonString = JSON.stringify(this.editor.getCurrentPage().save())const blob = new Blob([jsonString])const blobURL = URL.createObjectURL(blob)const downloadLink = document.createElement('a')downloadLink.download = '数据.json'downloadLink.href = blobURLdocument.body.appendChild(downloadLink)downloadLink.click()URL.revokeObjectURL(blobURL)document.body.removeChild(downloadLink)},// 读取历史数据readHistoryData() {const stringData = localStorage.getItem('flowData')if (stringData === '' || stringData === '{}' || stringData === null) {this.$message.warning('无历史数据')return}const jsonData = JSON.parse(stringData)this.editor.getCurrentPage().read(jsonData)},// 读取上传数据readUploadData() {const uploadButton = document.createElement('input')uploadButton.setAttribute('type', 'file')uploadButton.setAttribute('accept', '.json')uploadButton.addEventListener('change', (e) => {console.dir(uploadButton)const file = uploadButton.files[0]const fileReader = new FileReader()fileReader.onload = (event) => {console.log(event)const text = JSON.parse(event.target.result)console.log(text)this.editor.getCurrentPage().read(text)}fileReader.readAsText(file)})uploadButton.click()},//save(source) {const edges = source.edgesconst nodes = source.nodesconsole.log(construct)const res = construct(source)console.log(JSON.stringify(res, null, 2))}}
}
</script><style lang="less">
@import url("./index.less");
</style>
index.less
@backgroundColor: #fbfbfb;
@borderColor: #dadce0;@itempannelAndPageBorder: 1px solid #ccc;
@pageHeight: calc(100vh - 41px - 37px);body {margin: 0;}.all {width: 100%;height: 100%;.main {overflow-y: auto;#vue-g6-editor {width: 100%;height: 100%;overflow-x: hidden;background-color: white;// transform: scale(0.5);.showcontent {height: 700px;.showface {height: 700px;}.showcanvas {height: 700px;}.shownode {height: 700px;}}.showtab {width: 100%;height: 700px;}// 主画布#page {height: 700px;position: relative;display: flex;.graph-container {height: 700px;}.controltab {width: 100%;height: 200px;background-color: white;position: absolute;bottom: 0;z-index: 999;/* 子盒子底部与父盒子底部对齐 */display: flex;flex-direction: column;/* 垂直方向排列子元素 */opacity: 0.5;background-color: white;/* 设置盒子的透明度为 0.5,即 50% 不透明 */.controlbt {opacity: 1;width: 100%;height: 50px;display: flex;font-size: 50px;justify-content: center;align-items: center;}}.activeshow {width: 90%;opacity: 1;flex-grow: 1;/* 第二个子盒子沾满剩余空间 */.header {width: 100%;color: black;font-weight: 550;font-size: 20px;padding-left: 10px;padding-top: 10px;}.showmain {display: flex;.objectshow {flex: 1;color: black;font-weight: 550;}}.staticshow {width: 60%;height: 110px;display: flex;flex-direction: column;justify-content: center;align-items: center;.admi {color: black;font-weight: 550;margin-bottom: 15px;}.setps {color: black;font-weight: 550;margin-bottom: 15px;}.atomname {color: black;font-weight: 550;}}}}header:nth-of-type(1) {background: @backgroundColor;line-height: 40px;padding-left: 20px;border-bottom: 1px solid @borderColor;box-sizing: border-box;}}}// 工具栏#toolbar {display: flex;justify-content: center;background: @backgroundColor;border-bottom: 1px solid @borderColor;padding: 4px 14px;i {font-size: 18px;padding: 4px;margin-right: 8px;color: #999999;&:hover {cursor: pointer;background-color: #eeeeee;color: #5cb6ff;}}}// 元素面板#itempannel {box-sizing: border-box;background-color: @backgroundColor;border-right: 1px solid @borderColor;height: @pageHeight;padding-top: 10px;overflow: hidden;display: flex;flex-direction: row;flex-wrap: wrap;justify-content: space-around;align-content: flex-start;.getItem {cursor: move;width: 80px;height: 80px;margin-bottom: 20px;display: flex;justify-content: center;align-items: center;img {width: 100%;}}}// 右侧部分(属性栏 + 缩略图).right-part {height: @pageHeight;display: flex;flex-direction: column;justify-content: flex-start;}// 属性栏#detailpannel {flex-grow: 1;background-color: @backgroundColor;border-left: 1px solid @borderColor;overflow-y: scroll;#nodeAttributeBar,#edgeAttributeBar,#groupAttributeBar,#canvasAttributeBar,#multiAttributeBar {.title {height: 34px;line-height: 34px;text-align: center;box-sizing: border-box;font-weight: bold;font-size: 13px;border-width: 0 0 1px 0;border-style: solid;border-color: @borderColor;}.main {padding: 10px;}}}// 缩略图#minimap {background-color: @backgroundColor;border-top: 1px solid #ccc;border-left: 1px solid #ccc;.title {height: 34px;line-height: 34px;text-align: center;box-sizing: border-box;font-weight: bold;font-size: 13px;border-width: 0 0 1px 0;border-style: solid;border-color: @borderColor;}}// 右键菜单#contextmenu {display: none;.menu {/deep/ .el-button {width: 100%;display: block;margin-left: 0;border-radius: 0 !important;border-bottom: none;&:nth-last-of-type(1) {border-bottom: 1px solid #dcdfe6;}}}}// 下载图片弹窗.save-as-image-dialog {/deep/ .el-select {display: block;}}
}
mixin.js
export default {methods: {// 保存节点属性saveNodeAttribute() {this.editor.executeCommand(() => {// 获取画布const page = this.editor.getCurrentPage();// 获取所选对象const selectedItem = page.getSelected()[0];page.update(selectedItem.id, {label: this.nodeAttributeForm.label,size: this.nodeAttributeForm.width + "*" + this.nodeAttributeForm.height,color: this.nodeAttributeForm.color});});},// 保存边属性saveEdgeAttribute() {this.editor.executeCommand(() => {// 获取画布const page = this.editor.getCurrentPage();// 获取所选对象const selectedItem = page.getSelected()[0];console.log(this.edgeAttributeForm);page.update(selectedItem.id, {label: this.edgeAttributeForm.label,shape: this.edgeAttributeForm.shape});});}}
};
相关文章:

vue2使用antv/g6-editor实现可拖拽流程图
依赖下载 照着这个引入就好,然后npm install 源码 <template><div id"vue-g6-editor"><el-row><el-col :span"24"></el-col></el-row><!-- 工具栏 --><el-row><el-col :span"24&qu…...
springboot学习小结
背景 业务上需要开发,组里一位前辈给我指路 spring基础 什么是spring spring提供一个容器称为spring应用上下文,容器里可以创建和管理组件,组件会在容器里装配好,组件也可以叫bean。 装配不由组件创建他依赖的组件࿰…...

vue聊天发送Emoji表情
在用web端写聊天发送表情的功能中,使用web端有系统自带的unicode表情会出现每端不统一的情况,不好用不能统一,在这里我想到了一个非常好的思路,可以解决这个问题! 那就是发送表情用图片的形式呈现,然后发给…...

360数字安全:2024年4月勒索软件流行态势分析报告
勒索软件传播至今,360 反勒索服务已累计接收到数万勒索软件感染求助。随着新型勒索软件的快速蔓延,企业数据泄露风险不断上升,勒索金额在数百万到近亿美元的勒索案件不断出现。勒索软件给企业和个人带来的影响范围越来越广,危害性…...

【MySQL】日志详解
本文使用的MySQL版本是8 日志概览 它们记录了数据库系统中的不同操作和事件,以便于故障排除、性能优化和数据恢复。本文将介绍MySQL中常见的几种日志,同时也会介绍一点常用的选项。 官方文档:MySQL :: MySQL 8.0 Reference Manual :: 7.4 M…...
MyBatis 延迟加载,一级缓存,二级缓存设置
MyBatis不仅提供了一级缓存和二级缓存机制,还支持延迟加载(Lazy Loading),以进一步优化性能。 1. 延迟加载(Lazy Loading) 延迟加载是在需要时才加载数据,而不是在查询时立即加载所有相关数据。…...

Linux 基本指令2
cp 指令 cp[选项]源文件 目标文件 将源文件的内容复制到目标文件中,源文件可以有多个,最后一个文件为目标文件,目标文件也可以是一段路径,若目的地不是一个目录的话会拷贝失败。若没有路径上的目录则会新建一个,若源是…...
联邦学习的基本流程,联邦学习权重聚合,联邦学习权重更新
目录 联邦学习的基本流程是 S_t = np.random.choice(range(K), m, replace=False) 联邦学习权重聚合 model.state_dict() 联邦学习权重更新 下载数据集 https://ossci-datasets.s3.amazonaws.com/mnist/train-images-idx3-ubyte.gz 联邦学习的基本流程是 **1. server初始…...

React保姆级教学
React保姆级教学 一、创建第一个react项目二、JSX基本语法与react基础知识1、 插值语法:2、 循环一个简单列表3、 实现简单条件渲染4、 实现复杂的条件渲染5、 事件绑定6、 基础组件(函数组件)7、 使用useState8、 基础样式控制9、 动态类名1…...

数据结构和矩阵细节用法:double、cell和complex #matlab
矩阵建立 建立矩阵用[]; 矩阵的同一行内的元素用逗号或者空格隔开; 矩阵的不同行的元素用分号隔开 eg. 矩阵 A 1 2 3 4 5 6 7 8 9 在matlab中矩阵A表示为: clc;clear; A[1,2,3;4,5,6;7,8,9]; %或者A[1 2 3;4 5 …...

12. Django 第三方功能应用
12. 第三方功能应用 因为Django具有很强的可扩展性, 所以延伸了第三方功能应用. 通过本章的学习, 读者能够在网站开发过程中快速实现API接口开发, 验证码生成与使用, 站内搜索引擎, 第三方网站实现用户注册, 异步任务和定时任务, 即时通信等功能.12.1 Django Rest Framework框…...
UnityWebRequest获取本地txt文件,其中中文乱码问题(踩坑记录)
Unity获取本地streamingassert下txt文件,遇到点问题,就是用UnityWebRequest下载一个txt文件的时候,原txt在资源管理器用notepad打开显示正常,但是Unity里调试,打印内容却是乱码, 在notepad 转存为utf-8&…...

轮到国产游戏统治Steam榜单
6月10日晚8点,《黑神话:悟空》实体版正式开启全款预售,预售开启不到5分钟,所有产品即宣告售罄。 Steam上,《黑神话:悟空》持续占据着热销榜榜首的位置。 但在《黑神话:悟空》傲人的光环下,还有一款国产游戏取得出色的成绩。 6月10日&#…...

不想搭集群,直接用spark
为了完成布置的作业,需要用到spark的本地模式,根本用不到集群,就不想搭建虚拟机,hadoop集群啥的,很繁琐,最后写作业还用不到集群(感觉搭建集群对于我完成作业来说没有什么意义)&…...

【MATLAB源码-第225期】基于matlab的计算器GUI设计仿真,能够实现基础运算,三角函数以及幂运算。
操作环境: MATLAB 2022a 1、算法描述 界面布局 计算器界面的主要元素分为几大部分:显示屏、功能按钮、数字按钮和操作符按钮。 显示屏 显示屏(Edit Text):位于界面顶部中央,用于显示用户输入的表达式和…...
Scikit-learn 基础教程:机器学习的初步指南
Scikit-learn 是一个用于数据挖掘和数据分析的机器学习库,建立在 NumPy、SciPy 和 matplotlib 之上。它提供了简单而高效的工具来进行数据分析和建模。本文将为您介绍 Scikit-learn 的安装方法、核心组件,以及如何应用这些组件进行一个简单的机器学习项目…...

开源WebGIS全流程常用技术栈
1 数据生产 1.1 uDig uDig(http://udig.refractions.net/)是一个基于Java开源的桌面应用框架,它构建在Eclipse RCP和GeoTools(一个开源的Java GIS包)上。可以进行shp格式地图文件的编辑和查看;是一个开源空间数据查看…...
前端开发之HTTP协议认识
上一篇👉: 前端开发之WebSocket通信 文章目录 1. HTTP 1.0 和 HTTP 1.1 之间有哪些区别1.连接方面:2.资源传输优化:3.缓存机制增强:4.主机头识别5.请求方法扩展 2.HTTP 1.1 和 HTTP 2.0 的区别1. 二进制分帧层:2.多路…...
力扣刷题总结 -- 数组26
76. 所有奇数长度子数组的和(简单) 题目要求: 给定一个正整数数组 arr ,计算所有奇数长度子数组的和。 子数组定义为原数组中的一个连续子序列。 返回 arr 中 所有奇数长度子数组的和 。 题目分析: 先得到所有子…...

无线MODBUS通讯模块在供水系统中的应用
一、项目背景 我国是人口大国、农业大国,同时也是贫水大国。由于大量工业废水污染了部分河流、地表的浅层水资源,并且有逐年加重的趋势,再加上农业、绿化等灌溉对水资源的大量消耗,这些因素综合作用进一步加剧了我国水资源紧缺的…...

【OSG学习笔记】Day 18: 碰撞检测与物理交互
物理引擎(Physics Engine) 物理引擎 是一种通过计算机模拟物理规律(如力学、碰撞、重力、流体动力学等)的软件工具或库。 它的核心目标是在虚拟环境中逼真地模拟物体的运动和交互,广泛应用于 游戏开发、动画制作、虚…...

智慧工地云平台源码,基于微服务架构+Java+Spring Cloud +UniApp +MySql
智慧工地管理云平台系统,智慧工地全套源码,java版智慧工地源码,支持PC端、大屏端、移动端。 智慧工地聚焦建筑行业的市场需求,提供“平台网络终端”的整体解决方案,提供劳务管理、视频管理、智能监测、绿色施工、安全管…...
【SpringBoot】100、SpringBoot中使用自定义注解+AOP实现参数自动解密
在实际项目中,用户注册、登录、修改密码等操作,都涉及到参数传输安全问题。所以我们需要在前端对账户、密码等敏感信息加密传输,在后端接收到数据后能自动解密。 1、引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId...

iPhone密码忘记了办?iPhoneUnlocker,iPhone解锁工具Aiseesoft iPhone Unlocker 高级注册版分享
平时用 iPhone 的时候,难免会碰到解锁的麻烦事。比如密码忘了、人脸识别 / 指纹识别突然不灵,或者买了二手 iPhone 却被原来的 iCloud 账号锁住,这时候就需要靠谱的解锁工具来帮忙了。Aiseesoft iPhone Unlocker 就是专门解决这些问题的软件&…...

微服务商城-商品微服务
数据表 CREATE TABLE product (id bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 商品id,cateid smallint(6) UNSIGNED NOT NULL DEFAULT 0 COMMENT 类别Id,name varchar(100) NOT NULL DEFAULT COMMENT 商品名称,subtitle varchar(200) NOT NULL DEFAULT COMMENT 商…...

前端开发面试题总结-JavaScript篇(一)
文章目录 JavaScript高频问答一、作用域与闭包1.什么是闭包(Closure)?闭包有什么应用场景和潜在问题?2.解释 JavaScript 的作用域链(Scope Chain) 二、原型与继承3.原型链是什么?如何实现继承&a…...
AI编程--插件对比分析:CodeRider、GitHub Copilot及其他
AI编程插件对比分析:CodeRider、GitHub Copilot及其他 随着人工智能技术的快速发展,AI编程插件已成为提升开发者生产力的重要工具。CodeRider和GitHub Copilot作为市场上的领先者,分别以其独特的特性和生态系统吸引了大量开发者。本文将从功…...

SpringTask-03.入门案例
一.入门案例 启动类: package com.sky;import lombok.extern.slf4j.Slf4j; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cache.annotation.EnableCach…...

力扣热题100 k个一组反转链表题解
题目: 代码: func reverseKGroup(head *ListNode, k int) *ListNode {cur : headfor i : 0; i < k; i {if cur nil {return head}cur cur.Next}newHead : reverse(head, cur)head.Next reverseKGroup(cur, k)return newHead }func reverse(start, end *ListNode) *ListN…...
多模态图像修复系统:基于深度学习的图片修复实现
多模态图像修复系统:基于深度学习的图片修复实现 1. 系统概述 本系统使用多模态大模型(Stable Diffusion Inpainting)实现图像修复功能,结合文本描述和图片输入,对指定区域进行内容修复。系统包含完整的数据处理、模型训练、推理部署流程。 import torch import numpy …...