zouyu
2026-05-07 b0d4df5f39525ae7fe252e8ee65d85fd71dca721
src/components/Table/lims-table.vue
@@ -2,11 +2,11 @@
  <div>
    <!-- 表格 -->
    <el-table ref="multipleTable" v-loading="tableLoading" :border="border" :data="tableData"
      :header-cell-style="{ background: '#f8f8f9', color: '#515a6e' }" :height="height"
      :header-cell-style="{ background: '#f8f8f9', color: '#515a6e' }" :height="tableHeight"
      :highlight-current-row="highlightCurrentRow" :row-class-name="rowClassName" :row-style="rowStyle"
      :row-key="rowKey" :span-method="spanMethod" stripe style="width: 100%" tooltip-effect="dark" @row-click="rowClick"
      :row-key="rowKey" :span-method="spanMethod" :show-summary="showSummary" :summary-method="summaryMethod" stripe style="width: 100%" tooltip-effect="dark" @row-click="rowClick"
      @current-change="currentChange" @selection-change="handleSelectionChange" class="lims-table">
      <el-table-column align="center" type="selection" width="55" v-if="isSelection" />
      <el-table-column align="center" type="selection" width="55" :selectable="selectionSelectable" v-if="isSelection" />
      <el-table-column align="center" label="序号" type="index" width="60" :index="indexMethod" />
      <el-table-column v-for="(item, index) in column" :key="index" :column-key="item.columnKey"
@@ -39,7 +39,7 @@
          <div v-else-if="item.dataType == 'tag'">
            <el-tag v-if="
              typeof dataTypeFn(scope.row[item.prop], item.formatData) ==
              'string'
              'string' && item.formatType!=null
            " :title="scope.row[item.prop] | formatters(item.formatData)"
              :type="formatType(scope.row[item.prop], item.formatType)">{{ scope.row[item.prop] |
                formatters(item.formatData) }}</el-tag>
@@ -48,7 +48,7 @@
              item.formatData
            )" v-else-if="
              typeof dataTypeFn(scope.row[item.prop], item.formatData) ==
              'object'
              'object' && item.formatType!=null
            " :key="index" :title="scope.row[item.prop] | formatters(item.formatData)"
              :type="formatType(tag, item.formatType)">{{
                item.tagGroup
@@ -57,9 +57,10 @@
                    : tag
                  : tag
              }}</el-tag>
            <el-tag v-else :title="scope.row[item.prop] | formatters(item.formatData)"
            <el-tag v-else-if="item.formatType!=null" :title="scope.row[item.prop] | formatters(item.formatData)"
              :type="formatType(scope.row[item.prop], item.formatType)">{{ scope.row[item.prop] |
                formatters(item.formatData) }}</el-tag>
            <span v-else>{{item.formatData}}</span>
          </div>
          <!-- 按钮 -->
@@ -70,7 +71,7 @@
                :disabled="o.disabled ? o.disabled(scope.row) : false" :icon="iconFn(o)" :plain="o.plain"
                :style="{ color: o.name === '删除' ? '#f56c6c' : o.color }" :type="o.type | typeFn(scope.row)"
                @click="o.clickFun(scope.row)" :key="key">
                {{ o.name }}
                {{ typeof o.name === 'function'? o.name(scope.row) : o.name }}
              </el-button>
              <el-upload :action="javaApi + o.url + '?id=' + (o.uploadIdFun ? o.uploadIdFun(scope.row) : scope.row.id)"
                         :key="uploadKeys[scope.$index]"
@@ -186,8 +187,12 @@
      default: false,
    },
    height: {
      type: String,
      default: null,
      type: Number,
      default: 0,
    },
    more:{
      type:Boolean,
      default: false,
    },
    tableLoading: {
      type: Boolean,
@@ -198,6 +203,10 @@
      default: () => {
        return () => { };
      },
    },
    selectionSelectable: {
      type: Function,
      default: () => true,
    },
    rowClick: {
      type: Function,
@@ -260,6 +269,14 @@
        };
      },
    },
    showSummary: {
      type: Boolean,
      default: false
    },
    summaryMethod: {
      type: Function,
      default: null
    }
  },
  data() {
    return {
@@ -267,10 +284,22 @@
      btnWidth: "120px",
      uploadRefs: [],
      currentFiles: {}, // 用于存储每行的当前文件
      uploadKeys: {} // 用于动态重置组件
      uploadKeys: {}, // 用于动态重置组件
      tableHeight:0,
      resizeHandler: null, // 防抖函数引用
    };
  },
  created(){
    this.calcTableHeight()
    this.resizeHandler = this.debounce(() => {
      this.calcTableHeight();
    }, 200);
  },
  beforeDestroy(){
    window.removeEventListener("resize",this.resizeHandler)
  },
  mounted() {
    window.addEventListener("resize",this.resizeHandler)
    this.calculateSpanInfo();
    this.$nextTick(() => {
      this.$refs.multipleTable.doLayout();
@@ -284,15 +313,47 @@
  watch: {
    tableData: {
      handler() {
        // 当表格数据变化时,初始化 uploadKeys
        this.tableData.forEach((_, index) => {
          this.$set(this.uploadKeys, index, Date.now());
        });
        this.refreshTableLayout();
      },
      immediate: true
    }
    },
    more() {
      this.refreshTableLayout();
    },
    height() {
      this.refreshTableLayout();
    },
  },
  methods: {
    refreshTableLayout() {
      this.$nextTick(() => {
        this.calcTableHeight();
        if (this.$refs.multipleTable) {
          this.$refs.multipleTable.doLayout();
        }
      });
    },
    calcTableHeight(){
      const innerHeight = window.innerHeight;
      const naviHeight = 96;//导航栏高度
      const pageHeight = this.page?52:0;//分页组件高度
      const mainMarginHeight = 40;//主组件上下间距
      const otherHeight = this.height;//其余高度
      const searchHeight = this.more?101:51;//搜索栏高度
      this.tableHeight = innerHeight - naviHeight - pageHeight - mainMarginHeight - otherHeight - searchHeight
    },
    //防抖函数
    debounce(fn, delay) {
      let timer = null;
      return (...args) => {
        clearTimeout(timer);
        timer = setTimeout(() => fn.apply(this, args), delay);
      };
    },
    getWidth(row, row0) {
      let count = 0;
      row.forEach((a) => {
@@ -471,7 +532,7 @@
</script>
<style scoped>
.el-table>>>.el-table__empty-text {
.el-table ::v-deep .el-table__empty-text {
  text-align: center;
}
@@ -479,7 +540,7 @@
  color: rgb(64, 158, 255);
  cursor: pointer;
}
>>>.cell {
::v-deep .cell {
  padding: 0 !important;
}
.cell {
@@ -490,19 +551,19 @@
  padding-left: 10px !important;
}
.lims-table .highlight-warning-row-border td:first-child {
.lims-table >>>.highlight-warning-row-border td:first-child {
  border-left: 4px solid #ffcd29;
}
.lims-table .highlight-warning-row-border td:last-child {
.lims-table >>>.highlight-warning-row-border td:last-child {
  border-right: 4px solid #ffcd29;
}
.lims-table .highlight-danger-row-border td:first-child {
.lims-table >>>.highlight-danger-row-border td:first-child {
  border-left: 4px solid #f56c6c;
}
.lims-table .highlight-danger-row-border td:last-child {
.lims-table >>>.highlight-danger-row-border td:last-child {
  border-right: 4px solid #f56c6c;
}
>>>.red-row td {