Vue3 + ElementPlus动态合并数据相同的单元格(超级详细版)

news2025/1/8 0:16:03

最近的新项目有个需求需要合并单元列表。ElementPlus 的 Table 提供了合并行或列的方法,可以参考一下https://element-plus.org/zh-CN/component/table.html

但项目中,后台数据返回格式和指定合并是动态且没有规律的,Element 的示例过于简单,因此记录下来,大家可以参考一下!

 效果图

 后台返回的数据结构

代码详解

实操中,需要合并的代码通常就是 list_cnt 数据需要进行合并,因为后台返回的格式都是Data 数据中包裹着 list_cnt 数据,这种格式看起来也是比较清晰。由 Element 文档可知:el-table 组件主要靠 :span-method 方法实现合并。

 完整代码

<template>
  <div class="app-container">
    <div class="search-bar">
      <el-form :inline="true" :model="formData" class="common-form-inline">
        <el-form-item label="名称搜索">
          <el-input v-model="formData.name" clearable @clear="queryAndroidList(true)" placeholder="请输入" />
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="queryAndroidList(true)">搜索</el-button>
        </el-form-item>
      </el-form>
    </div>

    <el-table :data="list" :stripe="true" fit highlight-current-row :show-overflow-tooltip="true"
      style="width: 100%; margin-top: 20px" v-loading="loading" @selection-change="handleSelectionChange"
      :span-method="objectSpanMethod" border>
      <el-table-column type="selection" align="center" width="55" />
      <el-table-column align="center" label="实例" prop="idx" width="220px">
        <template #default="scope">
          <el-button size="small" round>实例: {{ scope.row.idx }}</el-button>
          <el-button type="primary" size="small" @click="handleEdit(scope.row)">编辑</el-button>
          <el-button type="primary" size="small" @click="handleCreate(scope.row)">创建</el-button>
          <div class="time-line">
            <span>到期时间: {{ scope.row.update_time || '未授权' }}</span>
          </div>
        </template>
      </el-table-column>
      <el-table-column align="center" label="ip" prop="ip" width="180px">
      </el-table-column>
      <el-table-column align="center" label="ADB/API端口" prop="levelName" width="180px">
        <template #default="scope">
          <span v-if="scope.row.adb_port || scope.row.sdk_port">{{ scope.row.adb_port || '-' }} - {{ scope.row.sdk_port
            || '-' }}</span>
          <span v-else> - </span>
        </template>
      </el-table-column>

      <el-table-column align="center" label="名称" prop="name" width="120px">
        <template #default="scope">
          <span v-if="scope.row.name">{{ scope.row.name }}</span>
          <span v-else>-</span>
        </template>
      </el-table-column>
      <el-table-column align="center" label="状态" prop="status" width="150px">
        <template #default="scope">
          <el-button plain :style="{
            backgroundColor: scope.row.status === 20 ? '#fef0f0' : scope.row.status === 10 ? '#f0f9eb' : '',
            borderColor: scope.row.status === 20 ? '#fde2e2' : scope.row.status === 10 ? '#e1f3d8' : '',
            color: scope.row.status === 20 ? '#f56c6c' : scope.row.status === 10 ? '#67c23a' : ''
          }" v-if="scope.row.status">
            {{ scope.row.status === 10 ? '运行中' : scope.row.status === 20 ? '关机' : '空闲' }}
          </el-button>
        </template>
      </el-table-column>
      <el-table-column align="center" label="系统版本" prop="serial_no" width="150px">
        <template #default="scope">
          <span>版本1.0</span>
        </template>
      </el-table-column>

      <el-table-column :show-overflow-tooltip="false" align="center" label="操作">
        <template #default="scope">
          <div class="cell">
            <el-button :type="scope.row.status === 20 ? 'success' : 'danger'" size="small"
              @click="handlePowerAction(scope.row)">
              {{ scope.row.status === 20 ? '开机' : '关机' }}
            </el-button>
            <div class="el-dropdown flex flex-wrap items-center">
              <el-dropdown>
                <el-button type="info">
                  更多操作<el-icon class="el-icon--right"><arrow-down /></el-icon>
                </el-button>
                <template #dropdown>
                  <el-dropdown-menu>
                    <el-dropdown-item @click="handleoperate('restart', scope.row)">重启云机
                    </el-dropdown-item>
                    <el-dropdown-item @click="handleoperate('edit', scope.row)">修改名称</el-dropdown-item>
                    <el-dropdown-item @click="handleoperate('remark', scope.row)">设置备注</el-dropdown-item>
                    <el-dropdown-item @click="handleoperate('random', scope.row)">随机设备信息</el-dropdown-item>
                    <el-dropdown-item @click="handleoperate('mirror', scope.row)">切换镜像</el-dropdown-item>
                    <el-dropdown-item @click="handleoperate('reset', scope.row)">重置云机</el-dropdown-item>
                    <el-dropdown-item @click="handleoperate('copy', scope.row)">复制云机</el-dropdown-item>
                    <el-dropdown-item @click="handleoperate('delete', scope.row)">删除云机</el-dropdown-item>
                    <el-dropdown-item @click="handleoperate('terminal', scope.row)">终端窗口</el-dropdown-item>
                  </el-dropdown-menu>
                </template>
              </el-dropdown>
            </div>

            <div class="flex flex-wrap items-center">
              <el-dropdown>
                <el-button type="primary">
                  选择网络<el-icon class="el-icon--right"><arrow-down /></el-icon>
                </el-button>
                <template #dropdown>
                  <el-dropdown-menu>
                    <el-dropdown-item @click="handleSelectVPC">(旧)选择VPC网络</el-dropdown-item>
                    <el-dropdown-item>(新)选择VPC网络</el-dropdown-item>
                  </el-dropdown-menu>
                </template>
              </el-dropdown>
            </div>
          </div>
        </template>
      </el-table-column>
    </el-table>

    <!-- 创建 -->
    <el-dialog v-model="createdVisible" title="创建安卓" width="500">
      <el-form :model="formCreate">
        <el-form-item label="云机数量" :label-width="formLabelWidth">
          <el-input-number v-model="formCreate.num" autocomplete="off" :min="1" :max="12" />
        </el-form-item>
        <el-form-item label="镜像类型" :label-width="formLabelWidth">
          <el-radio-group v-model="formCreate.img_type">
            <el-radio label="10">基础镜像</el-radio>
            <el-radio label="20">GMS镜像</el-radio>
          </el-radio-group>
          <el-button type="primary" size="small" style="margin-left: 10px" @click="handleSwitchImage">
            <el-icon>
              <Refresh />
            </el-icon>&nbsp; 切换
          </el-button>
        </el-form-item>

        <el-form-item label="DNS设置" :label-width="formLabelWidth">
          <el-select v-model="formCreate.dns" @change="selectDns" placeholder="请选择DNS" class="w130" filterable>
            <el-option v-for="item in setDns" :key="item.id" :label="item.name" :value="item.id" />
          </el-select>
        </el-form-item>

        <el-form-item label="屏幕刷新率" :label-width="formLabelWidth">
          <el-select v-model="formCreate.fps" placeholder="请选择刷新率">
            <el-option label="60 FPS" value="60" />
            <el-option label="90 FPS" value="90" />
            <el-option label="120 FPS" value="120" />
          </el-select>
        </el-form-item>

        <!-- <el-form-item label="VPC网络" :label-width="formLabelWidth">
          <el-select v-model="formCreate.vpc" placeholder="请选择VPC">
            <el-option label="VPC网络 1" value="vpc1" />
            <el-option label="VPC网络 2" value="vpc2" />
            <el-option label="VPC网络 3" value="vpc3" />
          </el-select>
        </el-form-item> -->
      </el-form>
      <template #footer>
        <div class="dialog-footer">
          <el-button @click="createdVisible = false">取消</el-button>
          <el-button type="primary" @click="createdDialog(row)">
            确定
          </el-button>
        </div>
      </template>
    </el-dialog>

    <!-- 修改 -->
    <el-dialog v-model="dialogFormVisible" title="修改云机名称" width="500">
      <el-form :model="formEdit">
        <el-form-item label="名称" :label-width="formLabelWidth">
          <el-input v-model="formEdit.new_name" autocomplete="off" />
        </el-form-item>
      </el-form>
      <template #footer>
        <div class="dialog-footer">
          <el-button @click="dialogFormVisible = false">取消</el-button>
          <el-button type="primary" @click="editDialog(row)">
            确定
          </el-button>
        </div>
      </template>
    </el-dialog>

    <!-- 设置备注 -->
    <el-dialog v-model="remarkVisible" title="设置云机备注" width="500">
      <el-form :model="formRemark">
        <el-form-item label="云机备注" :label-width="formLabelWidth">
          <el-input v-model="formRemark.name" autocomplete="off" />
        </el-form-item>
      </el-form>
      <template #footer>
        <div class="dialog-footer">
          <el-button @click="remarkVisible = false">取消</el-button>
          <el-button type="primary" @click="remarkVisible = false">
            确定
          </el-button>
        </div>
      </template>
    </el-dialog>

    <!-- 切换云机镜像 -->
    <el-dialog v-model="mirrorVisible" title="切换云机镜像" width="500">
      <el-form :model="formMirror">
        <el-form-item label="云机镜像" :label-width="formLabelWidth">
          <el-select v-model="formMirror.mirror" multiple placeholder="请选择" style="width: 240px">
            <el-option v-for="item in mirrorList" :key="item.value" :label="item.label" :value="item.value" />
          </el-select>
        </el-form-item>
        <p>说明:如何切换的镜像不存在,系统会先拉取镜像,这个过程比较耗时请耐心等待。</p>
      </el-form>
      <template #footer>
        <div class="dialog-footer">
          <el-button @click="mirrorVisible = false">取消</el-button>
          <el-button type="primary" @click="mirrorVisible = false">
            确定
          </el-button>
        </div>
      </template>
    </el-dialog>

    <!-- 随机设备信息 -->
    <el-dialog v-model="randomVisible" title="随机设备信息" width="500"> </el-dialog>

    <!-- 复制云机 -->
    <el-dialog v-model="copyVisible" title="复制云机" width="500">
      <el-form :model="formCopy">
        <span>云机复制数量
        </span><el-input-number v-model="formCopy.num" :min="1" :max="10" />
      </el-form>
      <span>说明:复制请先关闭云机。相同实例号的云机,同时只能有一台为开机状态。复制云机比较耗时请耐心等待</span>
      <template #footer>
        <div class="dialog-footer">
          <el-button @click="copyVisible = false">取消</el-button>
          <el-button type="primary" @click="handleCopy(row)">
            确定
          </el-button>
        </div>
      </template>
    </el-dialog>

    <!-- 重置云机 -->
    <el-dialog v-model="resetVisible" title="提示" width="500">
      <el-icon>
        <WarningFilled />
      </el-icon> <span>确定要重置此云机?</span>
      <template #footer>
        <div class="dialog-footer">
          <el-button @click="resetVisible = false">取消</el-button>
          <el-button type="primary" @click="handleReset(row)">
            确定
          </el-button>
        </div>
      </template>
    </el-dialog>

    <!-- 删除云机 -->
    <el-dialog v-model="deleteVisible" title="提示" width="500">
      <el-icon>
        <WarningFilled />
      </el-icon> <span>确定要删除此云机?</span>
      <template #footer>
        <div class="dialog-footer">
          <el-button @click="deleteVisible = false">取消</el-button>
          <el-button type="primary" @click="handleDele(row)">
            确定
          </el-button>
        </div>
      </template>
    </el-dialog>

    <!-- 终端窗口 -->
    <el-dialog v-model="terminalVisible" title="终端窗口" width="500">
      <iframe src="http://192.168.1.100:8080" frameborder="0" width="100%" height="500px"></iframe>
      <template #footer> </template>
    </el-dialog>

    <!-- 选择网络 -->
    <el-dialog v-model="networkVisible" title="选择网络" width="500">
      <el-form :model="formNetwork">
        <el-form-item label="VPC网络" :label-width="formLabelWidth">
          <el-select v-model="formNetwork.network" placeholder="请选择">
            <el-option label="VPC网络1" value="1" />
            <el-option label="VPC网络2" value="2" />
            <el-option label="VPC网络3" value="3" />
          </el-select>
        </el-form-item>
      </el-form>
    </el-dialog>

  </div>
</template>
<script setup>
import { ref, reactive, nextTick } from 'vue'
import andriodList from '@/network/andriodList'
import { ElMessage } from 'element-plus'


// 搜索条件
const formData = reactive({
  name: '',
})
const loading = ref(false); // 列表的加载中
const list = ref([{}]) // 列表的数据

const queryAndroidList = async (flag) => {
  // 根据搜索条件设置查询参数
  if (flag) {
    formData.name = formData.name.trim()
  }
  loading.value = true
  try {
    const res = await andriodList.getAllAndroidList({
      name: formData.name
    })
    if (res.code === 200) {
      let allDataList = [];
      res.data && res.data.length > 0 && res.data.forEach((item, index) => {
        item.list_cnt && item.list_cnt.length > 0 && item.list_cnt.forEach((item2, index2) => {
          allDataList.push({
            ...item,
            // ...item2, 看具体需求  处理列表所需字段, 将list_cnt里的数据平铺开
            idx: item2.idx,
            name: item2.name,
            status: item2.status,
            data_dir: item2.data_dir,
            update_time: item2.update_time,
            sdk_port1: item2.sdk_port,
            adb_port1: item2.adb_port,
            cnt_id1: item2.cnt_id,
          })
        })


      })
      list.value = allDataList;
    } else {
      list.value = []
    }
  } catch (error) {
    list.value = []
  } finally {
    loading.value = false
  }
}
// 初始化获取列表
queryAndroidList()

const selectIds = ref([]);
// 行复选框选中项变化
function handleSelectVPC(selection) {
  selectIds.value = selection.map(item => item.id);
}

function handleQuery() {
  loading.value = true;
}
// 多选框选中数据
function handleSelectionChange(selection) {
  selectIds.value = selection.map(item => item.id);
}

/**
 * 合并行或列
 * @param row 行号
 * @param col 列号
 * @param rowspan 行合并数
 * @param colspan 列合并数
 *  @param rowIndex 当前行号
 * @param columnIndex 当前列号
 * 
 */
const objectSpanMethod = ({
  row,
  column,
  rowIndex,
  columnIndex,
}) => {
  if (column.property === 'idx') {
    if (rowIndex > 0 && list.value[rowIndex].idx === list.value[rowIndex - 1].idx) {
      return {
        rowspan: 0,
        colspan: 0,
      }
    }
    return {
      rowspan: getRowspan('idx', rowIndex),
      colspan: 1,
    }
  }
}

// 获取行合并数
const getRowspan = (key, rowIndex) => {
  let rowspan = 1; //默认合并1行
  let curVal = list.value[rowIndex][key]; //存储了当前值
  for (let i = rowIndex + 1; i < list.value.length; i++) {
    if (list.value[i][key] === curVal) {
      rowspan++;
    } else {
      break;
    }
  }
  return rowspan;
}

// 选择DNS
const setDns = ref([{
  id: '1',
  name: 'DNS1'
},
{
  id: '2',
  name: 'DNS2'

}])
const selectDns = async () => { }

//创建弹窗
const formCreate = reactive({
  idx: '',
  num: 1,
  img_type: "10",
  dns: '',
  fps: '',
})

const createdVisible = ref(false)
// 创建实例
function handleCreate(row) {
  createdVisible.value = true;
  formCreate.idx = row.idx; // 保存idx到formCreate中
}

const handleCreateAndroid = async () => {
  try {
    const res = await andriodList.createAPI({
      idx: formCreate.idx, // 使用保存的idx
      num: formCreate.num,
      img_type: formCreate.img_type,
      dns: formCreate.dns,
      fps: formCreate.fps,
    })
    if (res.code === 200) {
      ElMessage.success(res.msg)
      createdVisible.value = false
      // 刷新列表
      queryAndroidList()
    } else {
      ElMessage.error(res.msg)
    }
  } catch (error) {
    ElMessage.error(res.msg)
  }
}

//确定创建弹窗
function createdDialog() {
  handleCreateAndroid()
}

// 编辑实例
function handleEdit(row) {
  console.log('编辑实例:', row);
}

//切换镜像
const handleSwitchImage = () => {
  console.log('切换镜像');
}

//开机--关机 --status 容器状态 10 运行中 20 关机
let runId = null
async function handlePowerAction(row) {
  runId = row.cnt_id1
  const status = row.status
  try {
    let res
    if (status === 10) {
      res = await andriodList.stopAPI({
        cnt_id: runId
      })
    } else {
      res = await andriodList.runAPI({
        cnt_id: runId
      })
    }
    if (res.code === 200) {
      ElMessage.success(res.msg)
      queryAndroidList()
    } else {
      ElMessage.error(res.msg)
    }
  } catch (error) {
    ElMessage.error(res.msg)
  }
}

//重启云机
const restarCnt = async () => {
  try {
    const res = await andriodList.restart({
      cnt_id: publicId
    })
    if (res.code === 200) {
      ElMessage.success(res.msg)
      // 重启成功后重新获取列表
      queryAndroidList()
    } else {
      ElMessage.error(res.msg)
    }
  } catch (error) {
    ElMessage.error(res.msg)
  }
}


const formEdit = reactive({
  cnt_id: '',
  new_name: '',
})
const dialogFormVisible = ref(false)
const formLabelWidth = '140px'

const handleEditName = async () => {
  try {
    const res = await andriodList.renameAPI({
      cnt_id: formEdit.cnt_id,
      new_name: formEdit.new_name
    })

    if (res.code === 200) {
      ElMessage.success(res.msg)
      dialogFormVisible.value = false
      queryAndroidList()
    } else {
      ElMessage.error(res.msg)
    }
  } catch (error) {
    ElMessage.error(res.msg)
  }
}
//修改弹窗
function editDialog() {
  handleEditName()
}

//设置备注
const formRemark = reactive({
  name: '',
})
const remarkVisible = ref(false)

//切换
const formMirror = reactive({
  mirror: '',
})
const mirrorList = [{
  value: '1',
  label: '镜像1'
}]
const mirrorVisible = ref(false)

//随机
const randomVisible = ref(false)

//复制
const formCopy = reactive({
  num: 1,
  src_cnt_id: "",
  target_cnt_idx: "",
  target_cnt_name: "",
})
const copyVisible = ref(false)
//复制弹窗
function handleCopy() {
  handleCopyAPI()
}

const handleCopyAPI = async () => {
  try {
    const res = await andriodList.copyAPI({
      num: formCopy.num,
      src_cnt_id: formCopy.src_cnt_id,
      target_cnt_idx: formCopy.target_cnt_idx,
      target_cnt_name: formCopy.target_cnt_name,
    })
    if (res.code === 200) {
      ElMessage.success(res.msg)
      copyVisible.value = false
      queryAndroidList()
    } else {
      ElMessage.error(res.msg)
    }
  } catch (error) {
    ElMessage.error(res.msg)
  }
}

//重置  
const resetVisible = ref(false)
const handleResetId = async () => {
  try {
    const res = await andriodList.resetAPI({
      cnt_id: publicId
    })
    if (res.code === 200) {
      ElMessage.success(res.msg)
      deleteVisible.value = false
      queryAndroidList()
    } else {
      ElMessage.error(res.msg)
    }
  } catch (error) {
    ElMessage.error(res.msg)
  }
}

//重置弹窗
function handleReset() {
  handleResetId()
}


//删除
const deleteVisible = ref(false)
const handleDeleId = async () => {
  try {
    const res = await andriodList.deleteCntAPI({
      cnt_id: publicId
    })
    if (res.code === 200) {
      ElMessage.success(res.msg)
      deleteVisible.value = false
      queryAndroidList()
    } else {
      ElMessage.error(res.msg)
    }
  } catch (error) {
    ElMessage.error(res.msg)
  }
}

//删除
function handleDele() {
  handleDeleId()
}

//终端
const terminalVisible = ref(false)


//选择网络
const formNetwork = reactive({
  network: '',
})
const networkVisible = ref(false) //选择网络弹窗  

//操作
let publicId = null // 公共id
function handleoperate(type, row) {
  publicId = row.cnt_id1 // 获取第一个云机的cnt_id
  switch (type) {
    case 'restart':
      restarCnt(row)
      break;
    case 'edit':
      dialogFormVisible.value = true;
      formEdit.cnt_id = publicId;
      formEdit.new_name = row.name;
      break;
    case 'remark':
      remarkVisible.value = true;
      break;
    case 'random':
      randomVisible.value = true;
      break;
    case 'mirror':
      mirrorVisible.value = true;
      break;
    case 'copy':
      copyVisible.value = true;
      formCopy.src_cnt_id = publicId;
      formCopy.target_cnt_name = row.name;
      formCopy.target_cnt_idx = row.idx;
      break;
    case 'terminal':
      terminalVisible.value = true;
      break;
    case 'reset':
      // 处理重置操作
      resetVisible.value = true;
      break;
    case 'delete':
      // 处理删除操作
      deleteVisible.value = true;
      break;
    default:
      break;
  }
}

</script>

<style lang="scss" scoped>
.app-container {
  .search-bar {
    .el-icon {
      color: #fff;
    }
  }
  .cell {
    display: flex;
    justify-content: center;
    align-items: center;
  }
  .el-dropdown {
    margin-left: 10px;
  }
  .examples {
    display: flex;
    justify-content: center;
  }
  .time-line {
    margin-top: 10px;
    color: rgb(235, 0, 0);
    font-size: 14px;
  }
}
</style>

代码中会有一些注释,根据个人需求可以进行参考,此需求也涉及到按钮操作的,如果没有次需求可以忽略不看。

以上就是列表的合并单元格,如果对你有帮助,麻烦点个赞呗~ 

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

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

相关文章

Uniapp Android 本地离线打包(详细流程)

一、简介 App 离线 SDK 暂时不支持 Kotlin&#xff0c;未来不清楚。 uniapp 提供了 云打包 与 本地打包 两种方案&#xff0c;云打包 需要排队且还有次数限制&#xff0c;本地打包 则就没有这些限制&#xff0c;而且会 本地打包 对开发 原生插件 有很大的帮助。 细节&#x…

党员学习交流平台

本文结尾处获取源码。 本文结尾处获取源码。 本文结尾处获取源码。 一、相关技术 后端&#xff1a;Java、JavaWeb / Springboot。前端&#xff1a;Vue、HTML / CSS / Javascript 等。数据库&#xff1a;MySQL 二、相关软件&#xff08;列出的软件其一均可运行&#xff09; I…

Gitee图形界面上传(详细步骤)

目录 1.软件安装 2.安装顺序 3.创建仓库 4.克隆远程仓库到本地电脑 提交代码的三板斧 1.软件安装 Git - Downloads (git-scm.com) Download – TortoiseGit – Windows Shell Interface to Git 2.安装顺序 1. 首先安装git-2.33.1-64-bit.exe&#xff0c;顺序不能搞错2. …

WPF区域导航+导航参数使用+路由守卫+导航日志

背景&#xff1a;使用ContentControl控件实现区域导航是有Mvvm框架的WPF都能使用的&#xff0c;不限于Prism 主要是将ContenControl控件的Content内容在ViewModel中切换成不同的用户控件 下面是MainViewModel&#xff1a; private object body;public object Body {get { retu…

DeepSeek v3为何爆火?如何用其集成Milvus搭建RAG?

最近&#xff0c;DeepSeek v3&#xff08;一个MoE模型&#xff0c;拥有671B参数&#xff0c;其中37B参数被激活&#xff09;模型全球爆火。 作为一款能与Claude 3.5 Sonnet&#xff0c;GPT-4o等模型匹敌的开源模型DeepSeek v3不仅将其算法开源&#xff0c;还放出一份扎实的技术…

得物基于AIGC生成测试用例的探索与实践

一、背景 随着人工智能技术的快速发展&#xff0c;尤其是在自然语言处理&#xff08;NLP&#xff09;、计算机视觉和生成对抗网络&#xff08;GANs&#xff09;等领域&#xff0c;AIGC&#xff08;AI Generated Content&#xff09;得到了广泛应用&#xff0c;这一技术的进步使…

HTML5实现好看的二十四节气网页源码

HTML5实现好看的新年春节元旦网站源码 前言一、设计来源1.1 主界面1.2 关于我们界面1.3 春季节气界面1.4 夏季节气界面1.5 秋季节气界面1.6 冬季节气界面 二、效果和源码2.1 动态效果2.2 源代码 源码下载结束语 HTML5实现好看的二十四节气网页源码&#xff0c;春季节气&#xf…

Hadoop集群之间实现免密登录

实现虚拟机之间能够互相登录&#xff0c;比如可以在hadoop1上面登录hadoop2。 第一步&#xff1a;执行”ssh-keygen -t rsa”命令&#xff0c;生成该虚拟机的密钥 第二步&#xff1a;密钥文件存储在/root/.ssh目录&#xff0c;执行cd /root/.ssh命令进入存储密钥文件的目录&am…

国产编辑器EverEdit - 常用资源汇总

1 国产编辑器EverEdit-常用资源汇总 EverEdit是一款国产文本编辑器&#xff0c;历经超过15年的更新和维护&#xff0c;拥有不输业界顶级商业文本编辑器(EmEditor、UltraEdit)的实力&#xff0c;甚至在某些方面的功能更强(当然&#xff0c;各有千秋)&#xff0c;开发者对文本编辑…

C# 枚举格式字符串

总目录 前言 当前文章为 C# 中的格式设置(格式化字符串) 大全 中的一个小章节。 一、概述 1. 基本信息 可以使用 Enum.ToString 方法&#xff0c;新建表示枚举成员的数字值、十六进制值或字符串值的字符串对象。枚举格式说明符不区分大小写。 二、自定义数字格式说明符详解…

SQL-Server链接服务器访问Oracle数据

SQL Server 链接服务器访问 Oracle 离线安装 .NET Framework 3.5 方法一&#xff1a;使用 NetFx3.cab 文件 下载 NetFx3.cab 文件&#xff0c;并将其放置在 Windows 10 系统盘的 C:Windows 文件夹中。 以管理员身份运行命令提示符&#xff0c;输入以下命令并回车&#xff1a; …

Microi吾码|开源低代码.NET、VUE低代码项目,表单引擎介绍

Microi吾码&#xff5c;开源低代码.NET、VUE低代码项目&#xff0c;表单引擎介绍 一、摘要二、Microi吾码介绍2.1 功能介绍2.2 团队介绍2.3 上线项目案例 三、Microi吾码表单引擎是什么&#xff1f;四、Microi吾码表单引擎功能4.1 模块引擎 - 由表单引擎驱动4.2 流程引擎 - 由表…

自动化立体库安全使用管理制度完整版

导语 大家好&#xff0c;我是社长&#xff0c;老K。专注分享智能制造和智能仓储物流等内容。欢迎大家到本文底部评论区留言。 新书《智能物流系统构成与技术实践》人俱乐部 完整版文件和更多学习资料&#xff0c;请球友到知识星球【智能仓储物流技术研习社】自行下载。 以下是《…

ArcGIS中怎么把数据提取到指定范围(裁剪、掩膜提取)

最近&#xff0c;经常能收到怎么把数据提取到指定范围、栅格数据怎么裁剪、矢量数据怎么裁剪、栅格数据怎么掩膜提取的咨询。 下面是我对这个问题的解决思路&#xff1a; 对于矢量数据&#xff1a; ①首先把数据加载进来 ②软件界面上面的工具栏找到→地理处理→裁剪&#x…

stm32的掉电检测机制——PVD

有时在一些应用中&#xff0c;我们需要检测系统是否掉电了&#xff0c;或者要在掉电的瞬间需要做一些处理。 STM32内部自带PVD功能&#xff0c;用于对MCU供电电压VDD进行监控。 STM32就有这样的掉电检测机制——PVD(Programmable Voltage Detecter)&#xff0c;即可编程电压检…

QT:控件属性及常用控件(2)-----按钮类控件及显示类控件

文章目录 QT关于qrc一个蛋疼的问题一、按钮类控件1.PushButton1.1 给按钮加图标1.2 给按钮加快捷键 2.RadioButtion2.1 单选题2.2 关于状态2.3 多组单选 3.Check Box4.Tool Button 二、显示类控件1.Lable1.1 文本、图片显示1.2 Label格式1.3 设置伙伴(绑定伙伴关系) 2.LCDNumbe…

逆向入门(2)C篇-基础知识

C基础 1、在C中&#xff0c;函数的变量是从右往左传递的&#xff0c;也就是test(x,y)&#xff0c;先传入y&#xff0c;再传x。 2、变量的分类&#xff1a; &#xff08;1&#xff09;全局变量。在编译的时候就已经确定了内存地址和宽度&#xff0c;变量名就是内存地址的别名…

【C语言】_assert断言

目录 1. assert功能 2. 使用assert判指针有效性 3. assert的参数 4. NDEBUG宏与assert机制的关闭 5. Debug版本与Release版本 1. assert功能 assert ( ) 是assert.h头文件定义的宏&#xff0c;用于在运行时确保程序符合指定条件&#xff1a; 如果不符合&#xff08;条件…

在Unity中用Ab包加载资源(简单好抄)

第一步创建一个Editor文件夹 第二步编写BuildAb&#xff08;这个脚本一点要放在Editor中因为这是一个编辑器脚本&#xff0c;放在其他地方可能会报错&#xff09; using System.IO; using UnityEditor; using UnityEngine;public class BuildAb : MonoBehaviour {// 在Unity编…

【可实战】Bug的判定标准、分类、优先级、定位方法、提交Bug(包含常见面试题)

一、Bug相关概念 &#xff08;一&#xff09;bug判定标准 &#xff08;二&#xff09;常见 Bug 分类 &#xff08;三&#xff09;bug优先级 1.bug严重程度与优先级的关系 有些很严重的Bug&#xff0c;只在极端的条件下才出现&#xff0c;用户碰到的概率很低&#xff0c;这种情…