vue2使用antv/g6-editor实现可拖拽流程图

news2024/11/16 6:00:12

依赖下载

照着这个引入就好,然后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 = this
      const editor = new G6Editor()
      this.editor = editor
      G6Editor.track(false)
      const Command = G6Editor.Command
      // 注册新命令save
      Command.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 + S
        shortcutCodes: [
          ['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')).width
      minimapWidth = Number(minimapWidth.replace(/px$/, ''))
      const minimap = new G6Editor.Minimap({
        container: 'minimap',
        width: minimapWidth,
        height: 200
      })
      // 右键菜单
      const contextmenu = new G6Editor.Contextmenu({
        container: 'contextmenu'
      })
      // 挂载以上组件到Editor
      editor.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.label
          this.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.label
          this.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 newCanvas
      if (this.saveAsImageFormat === 'jpg') {
        const canvas = this.editor.getCurrentPage().saveImage()
        newCanvas = document.createElement('canvas')
        newCanvas.width = canvas.width
        newCanvas.height = canvas.height
        const 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 = imageDataURL
      document.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 = blobURL
      document.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.edges
      const nodes = source.nodes
      console.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
        });
      });
    }
  }
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1800382.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

移动端 UI 风格,打造极致体验

移动端 UI 风格&#xff0c;打造极致体验

Three.js和Babylon.js,webGL中的对比效果分析!

hello&#xff0c;今天分享一些three.js和babylon.js常识&#xff0c;为大家选择three.js还是babylon.js做个分析&#xff0c;欢迎点赞评论转发。 一、Babylon.js是什么 Babylon.js是一个基于WebGL技术的开源3D游戏引擎和渲染引擎。它提供了一套简单易用的API&#xff0c;使开发…

在Windows上用Llama Factory微调Llama 3的基本操作

这篇博客参考了一些文章&#xff0c;例如&#xff1a;教程&#xff1a;利用LLaMA_Factory微调llama3:8b大模型_llama3模型微调保存-CSDN博客 也可以参考Llama Factory的Readme&#xff1a;GitHub - hiyouga/LLaMA-Factory: Unify Efficient Fine-Tuning of 100 LLMsUnify Effi…

【数据结构】平衡二叉树左旋右旋与红黑树

平衡二叉树左旋右旋与红黑树 平衡二叉树 定义 平衡二叉树是二叉搜索树的一种特殊形式。二叉搜索树&#xff08;Binary Search Tree&#xff0c;BST&#xff09;是一种具有以下性质的二叉树&#xff1a; 对于树中的每个节点&#xff0c;其左子树中的所有节点都小于该节点的值…

创意KMS知识图谱ui设计合集来了

创意KMS知识图谱ui设计合集来了

解决nvidia驱动和CUDA升级问题

解决nvidia驱动和CUDA升级问题 注释&#xff1a;升级高版本的nvidia驱动和cuda是不影响现有的docker镜像和容器的。因为是向下兼容的。仅仅升级后重启服务器即可。 ERROR: An NVIDIA kernel module ‘nvidia-drm’ appears to already be loaded in your kernel. This may be…

微信公众号二维码登录

微信扫码登录&#xff1a; 方式1、微信开放平台&#xff1a;第三方应用接入&#xff0c;依赖公司在【微信开放平台】用【公司营业执照】注册的账号&#xff0c;才能实现扫码登录 微信开放平台 方式2、微信公众平台&#xff1a;扫码通过微信公众号授权登录的&#xff0c;借助个人…

【vscode,gdb】在vscode调试时显示STL容器内容(开启gdb的pretty-printing)

在gdb调试cpp代码时&#xff0c;会发现它无法打印stl库中的容器&#xff0c;所以需要利用pretty-printing来将它打印出来 配置方法 在home下新建文件夹.gdb&#xff0c;然后在.gdb下新建文件printers.py 进入网址https://gcc.gnu.org/git/?pgcc.git;ablob_plain;flibstdc%2…

Mamba v2诞生:2 那些烧脑的矩阵们

大模型技术论文不断&#xff0c;每个月总会新增上千篇。本专栏精选论文重点解读&#xff0c;主题还是围绕着行业实践和工程量产。若在某个环节出现卡点&#xff0c;可以回到大模型必备腔调或者LLM背后的基础模型新阅读。而最新科技&#xff08;Mamba,xLSTM,KAN&#xff09;则提…

用自然语言连接信息孤岛

信息孤岛互联互通的困难 尽管已经进入了互联网时代&#xff0c;信息系统中的信息孤岛现象仍然十分地严重&#xff0c;不同部门&#xff0c;不同机器之间难以实现信息的互联互通。存在大量的信息孤岛。 不同信息系统的相互通信依赖通信协议和数据模型的定义&#xff0c;前者决定…

南卡、漫步者和Cleer该怎么选?高性价比耳机推荐!

身为一位拥有五年资历的数码产品评测专家&#xff0c;我亲身体验了各类蓝牙耳机&#xff0c;足迹遍及小众新秀至国际知名品牌。频繁受邀于不同厂商&#xff0c;为他们的新品提供专业见解&#xff0c;同时&#xff0c;我的社交平台私信中也满载着粉丝关于开放式耳机选择的热切询…

乡村振兴的乡村旅游品质提升:提升乡村旅游服务质量,打造乡村旅游品牌,增强乡村旅游吸引力,打造具有旅游特色的美丽乡村

目录 一、引言 二、提升乡村旅游服务质量 1、完善基础设施建设 2、提升服务人员素质 3、规范服务流程 三、打造乡村旅游品牌 1、挖掘乡村文化特色 2、打造特色旅游产品 3、加强品牌宣传和推广 四、增强乡村旅游吸引力 1、创新旅游体验方式 2、打造旅游精品线路 3、…

【力扣】矩阵中的最长递增路径

一、题目描述 二、解题思路 1、先求出以矩阵中的每个单元格为起点的最长递增路径 题目中说&#xff0c;对于每个单元格&#xff0c;你可以往上&#xff0c;下&#xff0c;左&#xff0c;右四个方向移动。那么以一个单元格为起点的最长递增路径就是&#xff1a;从该单元格往上…

2021年vue面试题整理(万字解析)

一、对MVVM的理解 MVVM分为Model、View、ViewModel。 Model 代表数据模型&#xff0c;数据和业务逻辑都在Model层中定义&#xff1b;泛指后端进行的各种业务逻辑处理和数据操控&#xff0c;对于前端来说就是后端提供的 api 接口。 View 代表UI视图&#xff0c;负责数据的展示…

Redis-重定向

实验环境&#xff08;3主3从的Redis-Cluster&#xff09; 一、Redis重定向基础篇 1、MOVED重定向 Redis Custer 中&#xff0c;客户端可以向集群中任意节点发送请求。此时当前节点先对 Key 进行 CRC 16 计算&#xff0c;然后按 16384 取模确定 Slot 槽。确定该 Slot 槽所对应的…

postgresql之翻页优化

列表和翻页是所有应用系统里面必不可少的需求&#xff0c;但是当深度翻页的时候&#xff0c;越深越慢。下面是几种常用方式 准备工作 CREATE UNLOGGED TABLE data (id bigint GENERATED ALWAYS AS IDENTITY,value double precision NOT NULL,created timestamp with time zon…

AI大模型日报#0607:10家国产大模型、GPT-4o挑战高考作文 | OpenAI公开破解GPT-4新方法

导读&#xff1a;AI大模型日报&#xff0c;爬虫LLM自动生成&#xff0c;一文览尽每日AI大模型要点资讯&#xff01;目前采用“文心一言”&#xff08;ERNIE 4.0&#xff09;、“零一万物”&#xff08;Yi-Large&#xff09;生成了今日要点以及每条资讯的摘要。欢迎阅读&#xf…

新媒体暴力起号必备因素!沈阳新媒体运营培训学校

1周涨粉10w&#xff1f;这对普通人来说可以说是天文数字&#xff0c;但只要掌握方式方法&#xff0c;普通人也能做到&#xff01; 面试经验丰富的人都深知&#xff0c;给面试官留下的第一印象相当重要&#xff0c;几乎决定了80%的面试机会。标题也是如此&#xff0c;在完成一篇…

【c语言】指针就该这么学(3)

&#x1f31f;&#x1f31f;作者主页&#xff1a;ephemerals__ &#x1f31f;&#x1f31f;所属专栏&#xff1a;C语言 目录 一、函数指针 1.函数指针变量的创建 2.函数指针变量的使用 二、typedef关键字 三、函数指针数组 1.函数指针数组的概念 2.函数指针数…

SD卡格式化怎么恢复?一键扫描,轻松找回丢失的数据

SD卡格式化怎么恢复数据&#xff1f;在日常生活中&#xff0c;我们常常会使用SD卡来存储各种数据&#xff0c;如照片、视频、文档等。然而&#xff0c;当SD卡意外格式化或者出现其他问题时&#xff0c;里面的数据就会面临丢失的风险。 此时&#xff0c;如何恢复格式化的SD卡就…