el-table 组件实现 “合并单元格 + N行数据小计” 功能

news2024/7/4 5:49:00

目录

  • 需求 - 要实现的效果
  • 初始代码
  • 代码升级(可供多个表格使用)
    • `CommonTable.vue 子组件 `
    • 使用子组件1 - `父组件 - 图1~图3使用`
      • 效果展示
    • 使用子组件2 - `父组件 - 图4使用`
      • 效果展示
  • 注意
  • 【代码优化 - 解决bug】

需求 - 要实现的效果

在这里插入图片描述

父组件中 info 数据示例

const info = {
  itemMap: {
    警告: [
      {
        total: 28,
        cfzl: '1',
        cfzlView: '警告',
        wfxl: '12',
        wfxlView: '超速行驶',
        jtfs: 'B11',
        jtfsView: '重型栏板半挂车'
      },
      {
        total: 3,
        cfzl: '1',
        cfzlView: '警告',
        wfxl: '17',
        wfxlView: '未低速通过',
        jtfs: 'B11',
        jtfsView: '重型栏板半挂车'
      },
      {
        total: 6,
        cfzl: '1',
        cfzlView: '警告',
        wfxl: '26',
        wfxlView: '违法停车',
        jtfs: 'B11',
        jtfsView: '重型栏板半挂车'
      },
      {
        total: 21,
        cfzl: '1',
        cfzlView: '警告',
        wfxl: '28',
        wfxlView: '违法装载',
        jtfs: 'B11',
        jtfsView: '重型栏板半挂车'
      },
      {
        total: 3,
        cfzl: '1',
        cfzlView: '警告',
        wfxl: '49',
        wfxlView: '其他影响安全行为',
        jtfs: 'B11',
        jtfsView: '重型栏板半挂车'
      },
      {
        total: 1,
        cfzl: '1',
        cfzlView: '警告',
        wfxl: '28',
        wfxlView: '违法装载',
        jtfs: 'B21',
        jtfsView: '中型栏板半挂车'
      }
    ],
    罚款: [
      {
        total: 56,
        cfzl: '2',
        cfzlView: '罚款',
        wfxl: '12',
        wfxlView: '超速行驶',
        jtfs: 'B11',
        jtfsView: '重型栏板半挂车'
      },
      {
        total: 6,
        cfzl: '2',
        cfzlView: '罚款',
        wfxl: '17',
        wfxlView: '未低速通过',
        jtfs: 'B11',
        jtfsView: '重型栏板半挂车'
      },
      {
        total: 12,
        cfzl: '2',
        cfzlView: '罚款',
        wfxl: '26',
        wfxlView: '违法停车',
        jtfs: 'B11',
        jtfsView: '重型栏板半挂车'
      },
      {
        total: 42,
        cfzl: '2',
        cfzlView: '罚款',
        wfxl: '28',
        wfxlView: '违法装载',
        jtfs: 'B11',
        jtfsView: '重型栏板半挂车'
      },
      {
        total: 6,
        cfzl: '2',
        cfzlView: '罚款',
        wfxl: '49',
        wfxlView: '其他影响安全行为',
        jtfs: 'B11',
        jtfsView: '重型栏板半挂车'
      },
      {
        total: 2,
        cfzl: '2',
        cfzlView: '罚款',
        wfxl: '28',
        wfxlView: '违法装载',
        jtfs: 'B21',
        jtfsView: '中型栏板半挂车'
      }
    ]
  },
  columns: [
    {
      // total: 28,
      // cfzl: '1',
      // cfzlView: '警告',
      // wfxl: '12',
      // wfxlView: '超速行驶',
      jtfs: 'B11',
      jtfsView: '重型栏板半挂车'
    },
    {
      // total: 1,
      // cfzl: '1',
      // cfzlView: '警告',
      // wfxl: '28',
      // wfxlView: '违法装载',
      jtfs: 'B21',
      jtfsView: '中型栏板半挂车'
    }
  ]
}

初始代码

父组件

<!-- info 数据来源 → info 数据示例 -->
<CommonTable :info="info"/>

CommonTable.vue 子组件

<template>
  <el-table
    :data="tableData"
    border
    stripe
    max-height="400"
    size="mini"
    :span-method="firstColMergeSpan"
  >
    <el-table-column align="center" prop="cfzl" label="处罚种类" />
    <el-table-column align="center" prop="wfxwfl" label="违法行为分类" />

    <el-table-column
      v-for="(item, index) in columns"
      :key="index"
      align="center"
      :prop="item.jtfs"
      :label="item.jtfsView || '-'"
    >
      <template slot-scope="{ row, $index }">
        <span>{{ row[item.jtfs] | noDataFilter }}</span>
      </template>
    </el-table-column>

    <el-table-column align="center" prop="xj" label="小计" />
  </el-table>
</template>

<script>
export default {
  name: 'CommonTable',
  components: {},

  props: {
    info: {
      type: Object,
      required: true
    }
  },

  data() {
    return {
      spanArr: []
    }
  },

  computed: {
    tableData() {
      const list = []
      Object.entries(this.info?.itemMap || {}).forEach((i) => {
        i[1]?.forEach((ii) => {
          list.push({
            // cfzl: ii.cfzlView,
            cfzl: i[0],
            wfxwfl: ii.wfxlView,
            [ii.jtfs]: ii.total,
            jtfs: ii.jtfs
          })
        })
      })
      return list.map((item) => {
        return {
          ...item,
          xj: this.columnKeyList.reduce((a, b) => {
            return a + (item[b] || 0)
          }, 0)
        }
      })
    },
    columns() {
      return this.info.columns || []
    },
    columnKeyList() {
      return this.columns.map((item) => item.jtfs)
    }
  },

  watch: {
    info() {
      this.xjPosition()
      this.firstColMergeCount()
    }
  },

  created() {},

  methods: {
    // 计算小计行插入位置
    xjPosition(Human = this.tableData) {
      const doctorMap = {}
      for (let i = 0; i < Human.length; i++) {
        // 找出相同名称的行数
        const doctorName = Human[i].cfzl
        if (doctorMap[doctorName] !== undefined) {
          doctorMap[doctorName].push(i)
        } else {
          doctorMap[doctorName] = [i]
        }
      }
      const keyArr = []
      for (const k in doctorMap) {
        // 取出key并倒序,防止正序插入会影响行下标
        keyArr.unshift(k)
      }
      keyArr.forEach((ele, index) => {
        const lastIndex = doctorMap[ele][doctorMap[ele].length - 1] // 找出相同名称最后一行插入合计数据
        const obj = this.xjRowDataCalc(Human, ele) // 计算出小计行数据
        Human.splice(lastIndex + 1, 0, obj) // 插入
      })
    },
    // 小计行计算
    xjRowDataCalc(data, name) {
      const obj = {
        cfzl: name, // 第一列用于合并单元格
        wfxwfl: '小计'
      }
      this.columnKeyList.forEach((key) => {
        obj[key] = 0
      })
      data.forEach((item) => {
        // “处罚种类” 相同的加起来
        if (item.cfzl === name) {
          this.columnKeyList.forEach((key) => {
            obj[key] += Number(item[key] || 0)
          })
        }
      })
      obj.xj = this.columnKeyList.reduce((a, b) => {
        return a + (obj[b] || 0)
      }, 0)
      return obj
    },
    // 合并单元格
    firstColMergeSpan({ row, column, rowIndex, columnIndex }) {
      if (columnIndex === 0) {
        const _row = this.spanArr[rowIndex]
        const _col = _row > 0 ? 1 : 0
        return {
          rowspan: _row,
          colspan: _col
        }
      }
    },
    // 计算要合并的单元格
    firstColMergeCount() {
      let contactDot = 0
      this.spanArr = []
      this.tableData.forEach((item, index) => {
        item.index = index
        if (index === 0) {
          this.spanArr.push(1)
        } else {
          // 根据相同 “处罚种类” 来合并
          if (item.cfzl === this.tableData[index - 1].cfzl) {
            this.spanArr[contactDot] += 1
            this.spanArr.push(0)
          } else {
            contactDot = index
            this.spanArr.push(1)
          }
        }
      })
    }
  }
}
</script>

<style lang='scss' scoped>
</style>

代码升级(可供多个表格使用)

图1
在这里插入图片描述
图2
在这里插入图片描述
图3
在这里插入图片描述
图4
在这里插入图片描述

根据接口返回数据不同(数据格式一致,只是部分字段名不一致),向子组件传入不同的字段名。

CommonTable.vue 子组件

<template>
  <el-table
    :data="tableData"
    border
    stripe
    max-height="400"
    size="mini"
    :span-method="firstColMergeSpan"
  >
    <!-- 第一列 -->
    <el-table-column align="center" :prop="oneColPropField" :label="oneColLabelField" />
    <!-- 第二列 -->
    <el-table-column align="center" :prop="twoColPropField" :label="twoColLabelField" />

    <!-- 其他数量列 -->
    <el-table-column
      v-for="(item, index) in columns"
      :key="index"
      align="center"
      :prop="item[countColPropsField]"
      :label="item[countColLabelField] || '-'"
    >
      <template slot-scope="{ row, $index }">
        <span>{{ row[item[countColPropsField]] | noDataFilter }}</span>
      </template>
    </el-table-column>

    <!-- “小计”列 -->
    <el-table-column align="center" prop="xj" label="小计" />
  </el-table>
</template>

<script>
export default {
  name: 'CommonTable',
  components: {},

  props: {
    info: {
      type: Object,
      required: true
    },
    // 自定义表格列
    selfColumns: {
      type: Array,
      default: () => []
    },
    // 表格列非自定义时(接口获取)列字段名
    columnKeyField: {
      type: String,
      default: 'jtfs'
    },
    // 第一列字段名
    oneColPropField: {
      type: String,
      required: true
    },
    // 第一列展示header文本
    oneColLabelField: {
      type: String,
      required: true
    },
    // 第一列数据来源字段名
    oneColDataField: {
      type: String,
      required: true
    },
    // 第二列字段名
    twoColPropField: {
      type: String,
      required: true
    },
    // 第二列展示header文本
    twoColLabelField: {
      type: String,
      required: true
    },
    // 第二列数据来源字段名
    twoColDataField: {
      type: String,
      required: true
    },
    // 其他数量 列 字段名
    countColPropsField: {
      type: String,
      default: 'jtfs'
    },
    // 其他数量 列 展示header文本字段名
    countColLabelField: {
      type: String,
      default: 'jtfsView'
    },
    // 其他数量 列 数据来源字段名
    countColDataField: {
      type: String,
      default: 'total'
    }
  },

  data() {
    return {
      spanArr: []
    }
  },

  computed: {
    // 表格数据处理
    tableData() {
      const list = []
      Object.entries(this.info?.itemMap || {}).forEach((i) => {
        i[1]?.forEach((ii) => {
          list.push({
            // [this.oneColPropField]: ii[this.oneColDataField] // 第一列数据(第一列数据部分表格 ii 中无第一列数据,所以使用↓↓↓下一行代码 i[0] 取第一列数据)
            [this.oneColPropField]: i[0], // 第一列数据
            [this.twoColPropField]: ii[this.twoColDataField], // 第二列数据
            [ii[this.countColPropsField]]: ii[this.countColDataField] // 其他数量列数据
            // jtfs: ii.jtfs
          })
        })
      })
      return list.map((item) => {
        return {
          ...item,
          // 计算小计数量
          xj: this.columnKeyList.reduce((a, b) => {
            return a + (item[b] || 0)
          }, 0)
        }
      })
    },
    columns() {
      /**
       * 表格列获取
       *    父组件有传表格列 selfColumns 就用 selfColumns
       *    否则用接口获的表格列
       */
      return (this.selfColumns.length && this.selfColumns) || this.info.columns || []
    },
    columnKeyList() {
      // 获取表格每列字段名组成数组
      return this.columns.map((item) => item[this.columnKeyField])
    }
  },

  watch: {
    info() {
      this.xjPosition()
      this.oneColMergeCount()
    }
  },

  created() {},

  methods: {
    // 计算小计行插入位置
    xjPosition(Human = this.tableData) {
      const doctorMap = {}
      for (let i = 0; i < Human.length; i++) {
        // 找出相同名称的行数
        const doctorName = Human[i][this.oneColPropField]
        if (doctorMap[doctorName] !== undefined) {
          doctorMap[doctorName].push(i)
        } else {
          doctorMap[doctorName] = [i]
        }
      }
      const keyArr = []
      for (const k in doctorMap) {
        // 取出key并倒序,防止正序插入会影响行下标
        keyArr.unshift(k)
      }
      keyArr.forEach((ele, index) => {
        const lastIndex = doctorMap[ele][doctorMap[ele].length - 1] // 找出相同名称最后一行插入合计数据
        const obj = this.xjRowDataCalc(Human, ele) // 计算出小计行数据
        Human.splice(lastIndex + 1, 0, obj) // 插入
      })
    },
    // 小计行数据计算
    xjRowDataCalc(data, name) {
      const obj = {
        [this.oneColPropField]: name, // 第一列用于合并单元格
        [this.twoColPropField]: '小计' // 第二列数据
      }
      this.columnKeyList.forEach((key) => {
        obj[key] = 0 // 其他书两列数据
      })
      data.forEach((item) => {
        // 第一列 oneColPropField 数据相同的加起来
        if (item[this.oneColPropField] === name) {
          this.columnKeyList.forEach((key) => {
            obj[key] += Number(item[key] || 0)
          })
        }
      })
      // 小计列数据总和(小计行和小计列交汇处数据)
      obj.xj = this.columnKeyList.reduce((a, b) => {
        return a + (obj[b] || 0)
      }, 0)
      return obj
    },
    // 合并单元格
    firstColMergeSpan({ row, column, rowIndex, columnIndex }) {
      if (columnIndex === 0) {
        const _row = this.spanArr[rowIndex]
        const _col = _row > 0 ? 1 : 0
        return {
          rowspan: _row,
          colspan: _col
        }
      }
    },
    // 计算要合并的单元格
    oneColMergeCount() {
      let contactDot = 0
      this.spanArr = []
      this.tableData.forEach((item, index) => {
        item.index = index
        if (index === 0) {
          this.spanArr.push(1)
        } else {
          // 第一列相同的合并
          if (item[this.oneColPropField] === this.tableData[index - 1][this.oneColPropField]) {
            this.spanArr[contactDot] += 1
            this.spanArr.push(0)
          } else {
            contactDot = index
            this.spanArr.push(1)
          }
        }
      })
    }
  }
}
</script>

<style lang='scss' scoped>
</style>

使用子组件1 - 父组件 - 图1~图3使用

<!-- info 数据来源 → info 数据示例 -->
<CommonTable
  :info="info"
  one-col-prop-field="cfzl"
  one-col-label-field="处罚种类"
  one-col-data-field="cfzlView"
  two-col-prop-field="wfxwfl"
  two-col-label-field="违法行为分类"
  two-col-data-field="wfxlView"
/>

效果展示

在这里插入图片描述

使用子组件2 - 父组件 - 图4使用

<CommonTable
  :info="info"
  one-col-prop-field="cfzl"
  one-col-label-field="处罚种类"
  one-col-data-field="cfzlView"
  two-col-prop-field="wfxwfl"
  two-col-label-field="违法行为分类"
  two-col-data-field="wfxlView"
  column-key-field="timenum"
  count-col-props-field="timenum"
  count-col-label-field="label"
  :self-columns="columns"
/>

<script>
	export default {
	  data() {
	    return {
	      columns: [...Array(24).keys()].map((item) => {
			return {
			  timenum: `${item}`,
			  label: `${item}-${item + 1}`
			}
	      }),
	      info: {
	        itemMap: {
	          警告: [
	            {
	              timenum: 17,
	              total: 9,
	              cfzl: '1',
	              cfzlView: '警告',
	              wfxl: '69',
	              wfxlView: '其他影响安全行为',
	              jtfs: null,
	              jtfsView: null
	            },
	            {
	              timenum: 17,
	              total: 3,
	              cfzl: '1',
	              cfzlView: '警告',
	              wfxl: '58',
	              wfxlView: '违法上道路行驶',
	              jtfs: null,
	              jtfsView: null
	            }
	          ]
	        },
	        columns: []
	      }
	    }
	  }
	}
</script>

效果展示

在这里插入图片描述

注意

  • 使用子组件1 和 使用子组件2 中 info 数据不同

【代码优化 - 解决bug】

解决数据重复问题
在这里插入图片描述

在这里插入图片描述

<template>
  <el-table
    :data="tableData"
    border
    stripe
    max-height="400"
    size="mini"
    :span-method="firstColMergeSpan"
  >
    <!-- 第一列 -->
    <el-table-column align="center" :prop="oneColPropField" :label="oneColLabelField" />
    <!-- 第二列 -->
    <el-table-column align="center" :prop="twoColPropField" :label="twoColLabelField" />

    <!-- 其他数量列 -->
    <el-table-column
      v-for="(item, index) in columns"
      :key="index"
      align="center"
      :prop="item[countColPropsField]"
      :label="item[countColLabelField] || '-'"
    >
      <template slot-scope="{ row, $index }">
        <span>{{ row[item[countColPropsField]] | noDataFilter }}</span>
      </template>
    </el-table-column>

    <!-- “小计”列 -->
    <el-table-column align="center" prop="xj" label="小计" />
  </el-table>
</template>

<script>
export default {
  name: 'CommonTable',
  components: {},

  props: {
    info: {
      type: Object,
      required: true
    },
    // 自定义表格列
    selfColumns: {
      type: Array,
      default: () => []
    },
    // 表格列非自定义时(接口获取)列字段名
    columnKeyField: {
      type: String,
      default: 'jtfs'
    },
    // 第一列字段名
    oneColPropField: {
      type: String,
      required: true
    },
    // 第一列展示header文本
    oneColLabelField: {
      type: String,
      required: true
    },
    // 第一列数据来源字段名
    oneColDataField: {
      type: String,
      required: true
    },
    // 第二列字段名
    twoColPropField: {
      type: String,
      required: true
    },
    // 第二列展示header文本
    twoColLabelField: {
      type: String,
      required: true
    },
    // 第二列数据来源字段名
    twoColDataField: {
      type: String,
      required: true
    },
    // 其他数量 列 字段名
    countColPropsField: {
      type: String,
      default: 'jtfs'
    },
    // 其他数量 列 展示header文本字段名
    countColLabelField: {
      type: String,
      default: 'jtfsView'
    },
    // 其他数量 列 数据来源字段名
    countColDataField: {
      type: String,
      default: 'total'
    }
  },

  data() {
    return {
      spanArr: []
    }
  },

  computed: {
    // 表格数据处理
    tableData() {
      const list = []
      Object.entries(this.info?.itemMap || {}).forEach((i) => {
        i[1]?.forEach((ii) => {
          /** ** 解决数据重复问题 start ****/
          const listDataIndex = list.findIndex(
            (listItem) => listItem[this.twoColPropField] === ii[this.twoColDataField] 
          )
          // 判断即将要 push 进 list 的数据 是否与 list 中已有数据的第二列数据有重复,有重复的话,就在 list 中重复的第二列数据的行数据中只添加当前数据为“其他数量列数据”
          if (listDataIndex !== -1) {
            list[listDataIndex][ii[this.countColPropsField]] = ii[this.countColDataField]
            return
          }
          /** ** 解决数据重复问题 end ****/
          list.push({
            // [this.oneColPropField]: ii[this.oneColDataField] // 第一列数据(第一列数据部分表格 ii 中无第一列数据,所以使用↓↓↓下一行代码 i[0] 取第一列数据)
            [this.oneColPropField]: i[0], // 第一列数据
            [this.twoColPropField]: ii[this.twoColDataField], // 第二列数据
            [ii[this.countColPropsField]]: ii[this.countColDataField] // 其他数量列数据
            // jtfs: ii.jtfs
          })
        })
      })
      return list.map((item) => {
        return {
          ...item,
          // 计算小计数量
          xj: this.columnKeyList.reduce((a, b) => {
            return a + (item[b] || 0)
          }, 0)
        }
      })
    },
    columns() {
      /**
       * 表格列获取
       *    父组件有传表格列 selfColumns 就用 selfColumns
       *    否则用接口获的表格列
       */
      return (this.selfColumns.length && this.selfColumns) || this.info.columns || []
    },
    columnKeyList() {
      // 获取表格每列字段名组成数组
      return this.columns.map((item) => item[this.columnKeyField])
    }
  },

  watch: {
    info() {
      this.xjPosition()
      this.oneColMergeCount()
    }
  },

  created() {},

  methods: {
    // 计算小计行插入位置
    xjPosition(Human = this.tableData) {
      const doctorMap = {}
      for (let i = 0; i < Human.length; i++) {
        // 找出相同名称的行数
        const doctorName = Human[i][this.oneColPropField]
        if (doctorMap[doctorName] !== undefined) {
          doctorMap[doctorName].push(i)
        } else {
          doctorMap[doctorName] = [i]
        }
      }
      const keyArr = []
      for (const k in doctorMap) {
        // 取出key并倒序,防止正序插入会影响行下标
        keyArr.unshift(k)
      }
      keyArr.forEach((ele, index) => {
        const lastIndex = doctorMap[ele][doctorMap[ele].length - 1] // 找出相同名称最后一行插入合计数据
        const obj = this.xjRowDataCalc(Human, ele) // 计算出小计行数据
        Human.splice(lastIndex + 1, 0, obj) // 插入
      })
    },
    // 小计行数据计算
    xjRowDataCalc(data, name) {
      const obj = {
        [this.oneColPropField]: name, // 第一列用于合并单元格
        [this.twoColPropField]: '小计' // 第二列数据
      }
      this.columnKeyList.forEach((key) => {
        obj[key] = 0 // 其他书两列数据
      })
      data.forEach((item) => {
        // 第一列 oneColPropField 数据相同的加起来
        if (item[this.oneColPropField] === name) {
          this.columnKeyList.forEach((key) => {
            obj[key] += Number(item[key] || 0)
          })
        }
      })
      // 小计列数据总和(小计行和小计列交汇处数据)
      obj.xj = this.columnKeyList.reduce((a, b) => {
        return a + (obj[b] || 0)
      }, 0)
      return obj
    },
    // 合并单元格
    firstColMergeSpan({ row, column, rowIndex, columnIndex }) {
      if (columnIndex === 0) {
        const _row = this.spanArr[rowIndex]
        const _col = _row > 0 ? 1 : 0
        return {
          rowspan: _row,
          colspan: _col
        }
      }
    },
    // 计算要合并的单元格
    oneColMergeCount() {
      let contactDot = 0
      this.spanArr = []
      this.tableData.forEach((item, index) => {
        item.index = index
        if (index === 0) {
          this.spanArr.push(1)
        } else {
          // 第一列相同的合并
          if (item[this.oneColPropField] === this.tableData[index - 1][this.oneColPropField]) {
            this.spanArr[contactDot] += 1
            this.spanArr.push(0)
          } else {
            contactDot = index
            this.spanArr.push(1)
          }
        }
      })
    }
  }
}
</script>

<style lang='scss' scoped>
</style>

【注】计算小计插入位置等部分方法参考文章 https://blog.csdn.net/seeeeeeeeeee/article/details/133122424

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

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

相关文章

【vue部署】Apache部署vue项目

Apache部署vue项目 Apache 下载安装(windows)1. 下载2. 安装3. 启动服务 vue 部署配置1. 基础配置2. 解决页面刷新问题 Apache 下载安装(windows) 1. 下载 Apache 2.4.59 下载地址&#xff1a;httpd-2.4.59-240404-win64-VS17.zip Visual C Redistributable for Visual Studi…

海山数据库(He3DB)从方法到实践,构建以场景为中心的体验管理体系

编者按&#xff1a;体验优化的过程中设计师经常会遇到几个阶段&#xff0c;发现问题、定义问题、优化问题、查看反馈&#xff0c;但在产品快速迭代的过程中&#xff0c;体验的问题经常被归类到“不紧急”需求中&#xff0c;并逐步转为长尾问题&#xff0c;这些不被重视的问题聚…

AI在线免费音乐生成工具:suno、udio、stableaudio

文生音乐 1、suno https://app.suno.ai/ 2、udio https://www.udio.com/ 3、stableaudio https://stableaudio.com/live https://www.stableaudio.com/?utm_campaignstableaudio_promo&utm_mediumcta_button&utm_sourcestability_ai 4、其他MusicGen https://…

2024 年 电工杯(A题)大学生数学建模挑战赛 | 园区微电网风光储协调| 数学建模完整代码+建模过程全解全析

当大家面临着复杂的数学建模问题时&#xff0c;你是否曾经感到茫然无措&#xff1f;作为2022年美国大学生数学建模比赛的O奖得主&#xff0c;我为大家提供了一套优秀的解题思路&#xff0c;让你轻松应对各种难题。 CS团队倾注了大量时间和心血&#xff0c;深入挖掘解决方案。通…

智慧校园的运作加速学校现代化

智慧校园的建造使师生的学校日子愈加便利&#xff0c;学校办公现代化&#xff0c;整个学校充满了生机与活力。其间智慧校园带来的不只是大环境的改变&#xff0c;也为教育教育带来了一种新的形式。我们知道智慧校园是依据信息化的互联网技能&#xff0c;这些技能运用于学校后让…

linux系统CPU持续飙高的排查方法

目录 前言&#xff1a; 1、查看系统cpu使用情况 2、找出占用cpu高的进程 3、进一步分析进程占用的原因&#xff01;&#xff01;&#xff01; 4、解决办法 前言&#xff1a; 如果一台服务器&#xff0c;它的cpu使用率一直处于一个高峰值&#xff0c;此时服务器可能导致无…

vue3中在elementplus多行表格中渲染多图数组中首图的显示问题,无法正常显示图片,作用域插槽写法问题

背景 在vue3中使用elementplus的el-table组件的时候&#xff0c;此时我在vue生命周期中挂载时获取了到服务器了数据&#xff0c;这个数据是一个多个对象的数组&#xff0c;各个对象又包括了图片数组&#xff0c;此时我想在表格上的每一行渲染图片的首图&#xff0c;也就是下标为…

设计系统采购与安装:乙级资质申请的技术准备

在设计系统采购与安装方面&#xff0c;为乙级资质申请所做的技术准备涉及多个方面。以下是一些关键的技术准备事项&#xff1a; 明确技术需求&#xff1a;首先&#xff0c;需要明确乙级资质申请所需的技术系统类型和规格。这可能包括但不限于设计软件、工程管理系统、项目管理系…

【webrtc】m98:Call的创建及Call对音频接收处理

call中多個流共享相同的辅助组件 这几个是与外部共用的 线程传输send控制module 线程任务队列工厂call的辅助组件中各种统计以及接收测的cc是自己创建的 call自己的多个辅助组件是外部传递来的 call 创建多个接收流 这里用一个set 来保存所有指针,并没有要map的意思:

手艺人百度百科怎么创建

创建手艺人百度百科的过程与创建其他类型人物百度百科类似&#xff0c;都需要遵循一定的步骤和注意事项。以下是伯乐网络传媒pouquan整理的手艺人百度百科创建指南&#xff1a; 创建前的准备工作 确定词条名称&#xff1a;手艺人百度百科的词条名称应直接使用手工艺人的姓名。…

智慧教室课堂-专注度及考试作弊系统、课堂动态点名,情绪识别、表情识别和人脸识别结合

课堂专注度分析&#xff1a; 课堂专注度表情识别 作弊检测&#xff1a; 关键点计算方法 转头(probe)低头(peep)传递物品(passing) 侧面的传递物品识别 逻辑回归关键点 使用&#xff1a; 运行setup.py安装必要内容 python setup.py build develop 运行demo_inference.py 将…

uniappx 获取设备唯一标识(OAID、AAID、AndroidID、IMEI等) Ba-IdCode-U

简介&#xff08;下载地址&#xff09; Ba-IdCode-U 是一款可以获取国内各大手机厂商 OAID&#xff08;开放匿名设备标识&#xff09;及海外手机平台 AAID&#xff08;安卓广告标识&#xff09;的uniapp插件。另外也支持获取 IMEI/MEID、AndroidID、WidevineID、PseudoID、GUI…

ComfyUI 本地部署指南:概念、部署过程、生成图片、共享 WebUI 模型

本文收录于《AI绘画从入门到精通》专栏&#xff0c;专栏总目录&#xff1a;点这里&#xff0c;订阅后可阅读专栏内所有文章。 大家好&#xff0c;我是水滴~~ 本文主要讲解 ComfyUI 的本地部署指南&#xff0c;内容主要包括&#xff1a;ComfyUI 的概念、ComfyUI 本地部署过程、使…

关于光照模型

关于光照模型 早期学习笔记&#xff0c;转载自早期Excel。 存在大量格式错误、可读性非常低&#xff0c;建议等待作者修复后阅读、或者作为查找性材料使用。 中文名英文名/缩写说明长什么样兰伯特光照模型Lambert Lighting1.兰伯特反射(Lambert)是最常见的一种漫反射&#x…

VUE3-form表单保存附件与基本信息

element-ui代码 <el-dialog :title"上传附件" v-model"dialogAdds.visible" width"500px" append-to-body> <el-form-item label"唯一标识"> <dict-tag v-if"form.groupId" :options"unique_identifica…

倍福CX7000PLC PWM/PTO输出功能块编程应用

如果大家是第一次用倍福的控制器和PLC,建议大家看看下面的文章链接: 从零开始倍福TwinCAT 3 PLC 的一个简单项目-CSDN博客https://rxxw-control.blog.csdn.net/article/details/139124427倍福TwinCAT3软件下载安装 倍福TwinCAT3 PLC编程软件下载安装-CSDN博客

设计模式——职责链(责任链)模式

目录 职责链模式 小俱求实习 结构图 实例 职责链模式优点 职责链模式缺点 使用场景 1.springmvc流程 ​2.mybatis的执行流程 3.spring的过滤器和拦截器 职责链模式 使多个对象都有机会处理请求&#xff0c;从而避免请求的发送者和接受者之间的耦合关系。将这个对象连成…

怎么清理C盘空间?5个清理方法要掌握好!

“我的电脑太满了&#xff0c;想清理一下电脑&#xff0c;但是根本不知道怎么操作&#xff0c;有什么方法可以快速清理c盘空间吗&#xff1f;希望大家给我出出主意&#xff01;” 随着电脑使用时间的增长&#xff0c;C盘&#xff08;通常是系统盘&#xff09;的空间会逐渐被占用…

Web开发——HTMLCSS

1、概述 Web开发分前端开发和后端开发&#xff0c;前端开发负责展示数据&#xff0c;后端开发负责处理数据。 HTML&CSS是浏览器数据展示相关的内容。 1&#xff09;网页的组成部分 文字、图片、音频、视频、超链接、表格等等 2&#xff09;网页背后的本质 程序员写的前端…

如何确定SolidWorks文件是哪个版本的软件创建

由于 SolidWorks 低版本无法打开高版本的文件&#xff0c;我们有时候从网络上下载一些模型时可能现当前的 SolidWorks 版本无法打开模型的问题&#xff0c;这时候具需要确定模型究竟是哪个版本的以便于我们安装相应的版本或高版本的 SolidWorks。 那么我们就需要方法确定如何查…