<template>
    <div class="w100">
        <!--  表格头部按钮  -->
        <el-row :gutter="10" style="margin: 0 0 8px 0;">
            <template v-if="config && config.tableButton && config.tableButton.top">
              <el-col :span="1.5" v-for="item of config.tableButton.top">
<!--                <el-button :type="item.type" plain size="mini" :icon="item.icon" @click="handleClick(item,{})" :hasPermi="[item.hasPermi]">{{item.content}}</el-button>-->
                <el-button :type="item.type" plain size="mini" :icon="item.icon" @click="handleClick(item,{})" v-if="checkPermi([item.hasPermi])">{{item.content}}</el-button>
              </el-col>
            </template>
            <right-toolbar v-if="!(config && config.colTopHiddenIcon)" :modelIdent="this.modelIdent" :showSearch.sync="showSearch" @queryTable="renderList" @columnsChange="columnsChange" :columns="columns"></right-toolbar>
        </el-row>
        <!-- 表格数据 -->
        <el-table v-loading="loading" :data="tableList" :ref="config && config.tableKey ? `tableRef_${config.tableKey}` : `selChangeList`" :key="tableKey" :highlight-current-row="config && config.currentSel || false" @current-change="(val) => handleClick({fnCode: 'currentData'},val)" highlight-selection-row @select-all="handleSelectAll" @select="handleSelectionChange" @sort-change="handleSortChange" :row-class-name="tableRowClassName">
<!--          :selectable="() => config && config.selectable ? false : true"  -->
            <el-table-column v-if="!(config && config.colHiddenCheck)" fixed="left" type="selection" width="40" :selectable="() => config && config.selectable ? false : true" align="center" />
            <!--      展开列内容        -->
            <el-table-column v-if="config && config.expand" type="expand">
              <template #default="props">
                <slot
                  name="tableExpand"
                  :row="props.row"
                  :rowIndex="props.$index"
                  :props="props"
                ></slot>
              </template>
            </el-table-column>
            <template v-for="(column, key, index) of columns">
                <!--      customTooltip:true 走  自定义tooltip 展示    -->
                <template v-if="column.customTooltip">
                  <el-table-column v-if="column && column.visible" :label="column.label" :key="key" :prop="key" :sortable="column.sortable" :width="column.width" :min-width="column.minWidth || '100px'" align="left">
                    <template #header="{ column }" v-if="column.sortable">
                      <div style="display: flex; align-items: center;">
                        <span>{{ column.label }}</span>
                        <template v-if="column.order === 'ascending'">
                          <i class="el-icon-sort-down" style="margin-left: -2px;margin-top: 2px;font-weight: 700;color: #c0c4cc;"></i>
                          <i class="el-icon-sort-up" style="color: #409EFF; margin-left: -8px;margin-top: 2px;font-weight: 700;"></i>
                        </template>
                        <template v-else-if="column.order === 'descending'">
                          <i class="el-icon-sort-down" style="color: #409EFF;margin-left: -2px;margin-top: 2px;font-weight: 700;"></i>
                          <i class="el-icon-sort-up" style="margin-left: -8px;margin-top: 2px;font-weight: 700;color: #c0c4cc;"></i>
                        </template>
                        <i v-else class="el-icon-sort" style="color: #C0C4CC;margin-top: 2px;font-weight: 700;"></i>
                      </div>
                    </template>

                    <template #default="scope">
                      <el-tooltip
                        :disabled="!isCellOverflow(scope.row[key], `cell-${key}-${scope.row.id}`)"
                        placement="top"
                        effect="dark"
                        popper-class="my-custom-tooltip">
                        <div slot="content" v-html="formatCellContent(scope.row[key])"></div>
                        <div :ref="`cell-${key}-${scope.row.id}`" class="cell-content">
                          {{ scope.row[key] }}
                        </div>
                      </el-tooltip>
                    </template>
                  </el-table-column>
                </template>
              <!--        原tooltip展示逻辑     -->
              <template v-else>
                <el-table-column v-if="column && column.visible" :label="column.label" :key="key" :prop="key" :sortable="column.sortable" :width="column.width" :min-width="column.minWidth || '100px'" align="left" :show-overflow-tooltip="true">
                  <!--  插槽 自定义列表表头数据格式  -->
                  <template #header v-if="column && column.slotHeaderName">
                    <span>{{column.label}}</span>
                    <el-tooltip trigger="click" effect="dark" placement="top">
                      <template #content>{{column.slotHeaderName}}</template>
                      <i class="el-icon-question"></i>
                    </el-tooltip>
                  </template>
                  <!--    插槽 自定义列表表头的排序图标按钮      -->
                  <template #header="{ column }" v-if="column.sortable">
                    <div style="display: flex; align-items: center;">
                      <span>{{ column.label }}</span>
                      <template v-if="column.order === 'ascending'">
                        <i class="el-icon-sort-down" style="margin-left: -2px;margin-top: 2px;font-weight: 700;color: #c0c4cc;"></i>
                        <i class="el-icon-sort-up" style="color: #409EFF;margin-left: -8px;margin-top: 2px;font-weight: 700;"></i>
                      </template>
                      <template v-else-if="column.order === 'descending'">
                        <i class="el-icon-sort-down" style="color: #409EFF;margin-left: -2px;margin-top: 2px;font-weight: 700;"></i>
                        <i class="el-icon-sort-up" style="margin-left: -8px;margin-top: 2px;font-weight: 700;color: #c0c4cc;"></i>
                      </template>
                      <i v-else class="el-icon-sort" style="color: #C0C4CC;margin-top: 2px;font-weight: 700;"></i>
                    </div>
                  </template>
                  <!--  插槽 自定义列表内数据格式  -->
                  <template #default="scope" v-if="column && column.slotName">
                    <!-- 传递行数据、行索引等信息到父组件的插槽 -->
                    <slot
                      :name="column.slotName"
                      :valueKey="key"
                      :row="scope.row"
                      :rowIndex="scope.$index"
                      :column="column"
                      :scope="scope"
                    ></slot>
                  </template>
                </el-table-column>
              </template>
            </template>
            <!--  表格行内按钮   -->
            <el-table-column v-if="config && config.tableButton && config.tableButton.line" :width="calculateOperationColumnWidth(config.tableButton.line, tableList)" label="操作" fixed="right" align="center" class-name="small-padding fixed-width handleContSty">
                <template #default="scope">
                  <template v-for="item of config.tableButton.line">
                    <template v-if="item && item.more && item.more.length > 0 && checkPermi(item.hasPermi)">
                      <el-dropdown size="mini" trigger="click" @command="(command) => handleClick({fnCode: command}, scope.row)">
                        <el-button size="mini" type="primary" plain icon="el-icon-d-arrow-right"><span style="margin-left: -5px;">{{item && item.title ? item.title : '更多'}}</span></el-button>
                        <el-dropdown-menu slot="dropdown">
<!--                          <el-dropdown-item v-for="dropBut of item.more" :command="dropBut.fnCode" :icon="dropBut.icon" :hasPermi="[dropBut.hasPermi]">{{dropBut.content}}</el-dropdown-item>-->
                          <el-dropdown-item v-for="dropBut of item.more" :command="dropBut.fnCode" :icon="dropBut.icon" v-show="dropBut && dropBut.showName ? dropBut.showVal.includes(scope.row[dropBut.showName]) : true" v-if="checkPermi([dropBut.hasPermi])">{{dropBut.content}}</el-dropdown-item>
                        </el-dropdown-menu>
                      </el-dropdown>
                    </template>
                    <template v-else>
                      <!--                    <el-tooltip v-if="item && item.content" :content="item.content" placement="top">-->
                      <template v-if="item && item.content">
                        <el-button :ref="`${item.content}_${scope.row.id}`" size="mini" plain link :type="item.type || 'primary'" :icon="item.icon" v-show="item && item.showName ? item.showVal.includes(scope.row[item.showName]) : true" @click="handleClick(item, scope.row)" v-if="item && item.hasPermi ? checkPermi([item.hasPermi]) : true">{{item.content}}</el-button>
                      </template>
<!--                      <el-button v-if="item && item.content" size="mini" link :type="item.type" :icon="item.icon" v-show="item && item.showName ? item.showVal.includes(scope.row[item.showName]) : true" @click="handleClick(item, scope.row)" :hasPermi="[item.hasPermi]">{{item.content}}</el-button>-->
                      <!--                    </el-tooltip>-->
                    </template>
                  </template>
                </template>
            </el-table-column>
        </el-table>
        <pagination v-show="queryParams.total > 0" :layout="queryParams && queryParams.layout" :total="queryParams.total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize" @pagination="renderList" />

        <el-dialog title="导出项" :visible.sync="dialogOpen" width="900px" append-to-body>
          <el-checkbox-group v-model="checkColumns">
            <template v-for="(item, key, index) of columns">
              <el-checkbox v-if="key !== 'id'" :label="key" :key="key" style="width: 25%;margin-right: 0px;">{{item.label}}</el-checkbox>
            </template>
          </el-checkbox-group>
          <div slot="footer" class="dialog-footer">
            <el-button type="primary" @click="diaColSubmit">确 定</el-button>
            <el-button @click="diaColCancel">取 消</el-button>
          </div>
        </el-dialog>
    </div>
</template>

<script setup>
  import { checkPermi } from "@/utils/permission";
  export default {
      name: 'table-list',
      props: {
        modelIdent: {
          type: String,
          default: ''
        },
        tableList: {
          type: Array,
          default: () => []
        },
        columns: {
          type: Object,
          default: () => {}
        },
        queryParams: {
          type: Object,
          default: () => ({
            total: 0,
            pageNum: 1,
            pageSize: 10,
            layout: 'total, sizes, prev, pager, next, jumper'
          })
        },
        config: {
          type: Object,
          default: () => ({
            colHiddenCheck: false,
            colTopHiddenIcon: false,
            currentSel: false,
          })
        }
      },
      data() {
        return {
          tableKey: 0,
          loading: false,
          showSearch: true,
          dialogOpen: false,
          ids: [],
          selectList: [],
          isProcessing: false,  // 防止事件循环的标志位
          checkColumns: []
        }
      },
      // 监听showSearch的变化，并且把变化后的值传给父组件
      watch: {
        showSearch: {
          handler(val) {
            this.$emit('value-change', val)
          }
        },
        queryParams: {
          handler(val) {
            // 重置后，重新渲染组件，起到排序图标重置功能
            if (val && val.resetVal) {
              this.tableKey++;
            }
          },
          deep: true,
          immediate: true
        }
      },
      created() {
        if (!(this.config && this.config.colTopHiddenIcon)) {
          // this.$modal.loading();
        }
      },
      methods: {
        checkPermi,
        // 1. 格式化单元格内容：将\n替换为<br>，支持HTML渲染
        formatCellContent(content) {
          if (!content) return '';
          // 若内容是对象/数组，先转为字符串（避免[object Object]）
          const strContent = typeof content === 'object' ? JSON.stringify(content) : String(content);
          return strContent.replace(/\n/g, '<br/>');
        },

        // 2. 判断单元格内容是否溢出（决定是否显示tooltip）
        isCellOverflow(content, refName) {
          // 获取单元格DOM（注意：ref在v-for中是数组，需取[0]）
          const cellDom = this.$refs[refName]?.[0];
          if (!cellDom || !content) return false;
          // 内容实际宽度 > 单元格可见宽度 → 溢出
          return cellDom.scrollWidth > cellDom.offsetWidth;
        },
        setCurrent(row) {
          this.$nextTick(() => {
            const targetRow = this.tableList.find(item => item.id === row.id); // 用id匹配原对象
            this.$refs.selChangeList.setCurrentRow(targetRow); // 使用传入的row参数
          });
        },
        // 计算操作列宽度
        calculateOperationColumnWidth(buttonConfigs, rowData) {
          let maxTotalWidth = 0;
          // 遍历每一行数据
          rowData.forEach(row => {
            let currentLineWidth = 0;
            let visibleButtonCount = 0;

            // 计算当前行所有可见按钮的总宽度
            buttonConfigs.forEach(config => {
              // 判断按钮是否显示
              if (this.isButtonVisible(config, row)) {
                let iconWid = 0;
                if (config.icon || config.more) {
                  iconWid = 14;
                }
                // iconWid:是图标的宽度 8是按钮padding宽度
                const btnWidth = this.calculateButtonWidth(config) + iconWid + 8;
                currentLineWidth += btnWidth;
                visibleButtonCount++;
              }
            });

            // 加上按钮间距（假设每个按钮左右有5px间距）
            if (visibleButtonCount > 0) {
              currentLineWidth += (visibleButtonCount - 1) * 5;
            }
            // 更新最大宽度
            if (currentLineWidth > maxTotalWidth) {
              maxTotalWidth = currentLineWidth;
            }
          });
          if (maxTotalWidth === 0) {
            maxTotalWidth = 20;
          }
          // 加上单元格内边距
          return Math.max(maxTotalWidth + 30); // 最小宽度120px
        },

        // 计算单个按钮宽度（根据字符数）
        calculateButtonWidth(buttonConfig) {
          const text = buttonConfig.content || buttonConfig.title || '';
          let width = 0;

          // 计算文本宽度（根据中英文字符不同宽度）
          for (const char of text) {
            if (char >= '\u4e00' && char <= '\u9fa5') {
              // 中文字符约15px
              width += 12;
            } else {
              // 英文字符约8px
              width += 4;
            }
          }
          // 加上按钮内边距和边框（约60px基础宽度）
          return Math.max(width);
        },

        // 判断按钮是否显示
        isButtonVisible(buttonConfig, row) {
          if (buttonConfig && buttonConfig.more) {
            if (!checkPermi(buttonConfig.hasPermi)) {
              return false;
            }
            if (buttonConfig.showName) {
              return buttonConfig.showVal.includes(row[buttonConfig.showName]);
            }
            return true;
          } else {
            if (buttonConfig && buttonConfig.hasPermi && !checkPermi([buttonConfig.hasPermi])) {
              return false;
            }
            if (buttonConfig.showName) {
              return buttonConfig.showVal.includes(row[buttonConfig.showName]);
            }
            return true;
          }
        },
        // 所有方法都抛出到父组件里去
        handleClick(result, row) {
          if (result && result.fnCode) {
            switch (result.fnCode) {
              case 'export':
                this.dialogOpen = true;
                this.diaColumnCheck();
                break;
              default:
                this.$emit("fnClick", result, row, this.ids, this.selectList);
            }
            // 点击按钮后，通过设置失去焦点使其按钮恢复点击前状态
            if (row && this.$refs && this.$refs[result.content +'_'+row.id]) {
              if (Array.isArray(this.$refs[result.content +'_'+row.id])) {
                this.$refs[result.content +'_'+row.id].forEach(refItem => {
                  refItem.$el.blur();
                });
              } else {
                this.$refs[result.content +'_'+row.id].$el.blur();
              }
            }
          }
        },
        // 导出弹窗 默认选中项
        diaColumnCheck() {
          this.checkColumns = [];
          Object.keys(this.columns).forEach(item => {
            if (item !== 'id' && this.columns[item] && this.columns[item].visible) {
              this.checkColumns.push(item);
            }
          });
        },
        // 弹窗确认
        diaColSubmit(){
          this.$emit("fnClick", {fnCode: 'export'}, {properties: this.checkColumns});
          this.dialogOpen = false;
        },
        // 弹窗取消
        diaColCancel() {
          this.dialogOpen = false;
        },

        /** 多选框选中数据 */
        handleSelectionChange(selection) {
          if (this.config && this.config['tableKey']) {
            this.selectList = [];
            this.ids = [];
            if (this.isProcessing) return;
            this.isProcessing = true;
            // 当选中行有关联值时，默认把所关联的的行选中
            selection.forEach(res => {
              if (res && res.relevance) {
                let selArr = [res];
                Object.keys(res.relevance).forEach(item => {
                  res.relevance[item].forEach(val => {
                    this.tableList.some(tabVal => {
                      if (tabVal[item] === val) {
                        selArr.push(tabVal);
                        return true;
                      }
                    });
                  });
                });
                this.selectList = this.selectList.concat(selArr);
                this.ids = this.ids.concat(selArr.map(item => item.id));
              } else {
                if (!this.ids.includes(res.id)) {
                  this.selectList = this.selectList.concat(res);
                  this.ids = this.ids.concat(res.id);
                }
              }
            });
            this.selectList.forEach(val => {
              this.$refs[`tableRef_${this.config.tableKey}`].toggleRowSelection(val,true);
            });
            this.isProcessing = false;
          } else {
            this.selectList = selection;
            this.ids = selection.map(item => item.id);
          }
        },
        // 全选按钮操作
        handleSelectAll(tabAll){
          // 资源监控策略和资源监控模块使用 selectable: 控制列是否可选，值为false则不可选--this.config.selectable为判断
          if (this.config && this.config.tableKey && this.config.selectable === true) {
            if (tabAll && tabAll.length > 0) {
              this.defaultSelectRows([]); //  取消全选
            } else {
              this.selectAllRows(); // 全选
            }
          } else {
            if (tabAll && tabAll.length > 0) {
              this.selectList = tabAll;
              this.ids = tabAll.map(tabId => tabId.id);
            } else {
              // 清空
              this.selectList = [];
              this.ids = [];
            }
          }
        },
        // 提供给父组件调用的方法：返回当前表格的选中数据 资源监控策略和资源监控模块使用
        getSelectedData() {
          return {
            tableKey: this.config.tableKey, // 表格唯一标识
            data: [...this.selectList] // 选中的数据
          };
        },
        // 提供给父组件调用的方法：全选所有行  资源监控策略和资源监控模块使用
        selectAllRows() {
          const table = this.config && this.config.tableKey ? this.$refs[`tableRef_${this.config.tableKey}`] : this.$refs.selChangeList;
          if (!table) return;
          // 清空现有选中状态
          this.selectList = [];
          this.ids = [];
          // 遍历所有行，执行选中
          this.tableList.forEach(row => {
            // 跳过不可选的行（根据selectable配置）
            // const isSelectable = !(this.config && this.config.selectable);
            // if (isSelectable) {
            table.toggleRowSelection(row, true); // 选中行
            this.selectList.push(row); // 同步到选中列表
            this.ids.push(row.id); // 同步到选中ID列表
            // }
          });
        },
        // 提供给父组件调用的方法：默认选中值
        defaultSelectRows(rows){
          const tableInstance = this.config && this.config.tableKey ? this.$refs[`tableRef_${this.config.tableKey}`] : this.$refs.selChangeList;
          this.selectList = [];
          this.ids = [];
          if (tableInstance) {
            if (rows && rows.length > 0) {
              rows.forEach(row => {
                tableInstance.toggleRowSelection(row, true);
                this.selectList.push(row);
                this.ids.push(row.id);
              });
            } else {
              tableInstance.clearSelection();
            }
          }
        },
        // 提供给父组件调用的方法：默认选中值 otherRow:新的回显方式，防止破坏原来rows判断的逻辑与回显
        defaultSelectRowsAll(rows,otherRow){
          const tableInstance = this.config && this.config.tableKey ? this.$refs[`tableRef_${this.config.tableKey}`] : this.$refs.selChangeList;
          this.selectList = [];
          this.ids = [];
          if (tableInstance) {
            if (otherRow && otherRow.length > 0) {
              otherRow.forEach(rowVal => {
                this.tableList.some(tabVal => {
                  if (rowVal.id === tabVal.id) {
                    tableInstance.toggleRowSelection(tabVal, true);
                    this.selectList.push(tabVal);
                    this.ids.push(tabVal.id);
                    return true;
                  }
                });
              });
            } else if (rows && rows.length > 0) {
              rows.forEach(row => {
                tableInstance.toggleRowSelection(row, true);
                this.selectList.push(row);
                this.ids.push(row.id);
              });
            } else {
              tableInstance.clearSelection();
            }
          }
        },
        renderList() {
          this.$emit("fnRenderList");
        },
        // columns改变时触发，重新计算样式并渲染列表(解决：新增列，多选框和操作按钮错位)
        columnsChange(val, col) {
          if (col) {
            this.$modal.closeLoading();
          }
          this.tableKey++;
        },
        // 排序发生变化时
        handleSortChange({column, prop, order}) {
          let sortType = 3;
          if (order === 'ascending') {
            sortType = 1;
          } else if (order === 'descending') {
            sortType = 2;
          }
          this.$emit("fnClick", {fnCode: 'sortTable'}, {sortType: sortType});
        },
        // 高亮展示列
        tableRowClassName({row, rowIndex}) {
          if (row.alarmFlag) {
            return 'tabColBgc'
          }
        },
      }
    }
</script>
<style scoped>
  /* 单元格内容样式：强制单行显示，溢出截断 */
  .cell-content {
    width: 100%;
    white-space: nowrap; /* 关键：确保内容单行显示 */
    overflow: hidden;
    text-overflow: ellipsis; /* 溢出显示... */
    word-break: keep-all; /* 避免英文单词截断 */
  }
  ::v-deep .el-table .fixed-width .el-button--mini {
    padding: 4px!important;
  }

  /* 自定义tooltip样式：支持换行+限制宽度 */
  ::v-deep .el-tooltip__popper {
    max-width: 400px; /* 限制tooltip宽度，避免过宽 */
    white-space: normal; /* 允许自动换行 */
    line-height: 1.6; /* 调整行高，提升可读性 */
  }
  ::v-deep .caret-wrapper {
    display: none !important;
  }
  ::v-deep .handleContSty .cell{
    white-space: nowrap !important;
  }
  /* 高亮闪烁 */
  ::v-deep .tabColBgc {
    /*background-color: #fa9550!important;*/
    animation: flashing 1s infinite ease-in-out;
  }
  @keyframes flashing {
    0%   { background-color: #fa9550; } /* 起始颜色 */
    50%  { background-color: #fff; }    /* 中间颜色 */
    100% { background-color: #fa9550; } /* 结束颜色 */
  }
  ::v-deep .el-table__body .tabColBgc.hover-row > td.el-table__cell,
            .el-table__body .tabColBgc.hover-row.current-row > td.el-table__cell,
            .el-table__body .tabColBgc.hover-row.selection-row > td.el-table__cell,
            .el-table__body .tabColBgc.hover-row.el-table__row--striped > td.el-table__cell,
            .el-table__body .tabColBgc.hover-row.el-table__row--striped.current-row > td.el-table__cell,
            .el-table__body .tabColBgc.hover-row.el-table__row--striped.selection-row > td.el-table__cell {
    background-color: #ffb98c!important;
  }
  ::v-deep .el-table-column--selection .cell {
    padding-left: 2px!important;
    padding-right: 2px!important;
  }
  ::v-deep .el-table th.el-table__cell > .cell {
    padding-left: 2px!important;
    padding-right: 2px!important;
  }
  ::v-deep .el-table .cell {
    padding-left: 0px!important;
    padding-right: 0px!important;
  }
  ::v-deep .el-button + .el-button {
    margin-left: 5px!important;
  }
</style>
<style>
  .my-custom-tooltip {
    box-sizing: border-box !important;
    max-height: 300px !important; /* 设置最大高度 */
    overflow-y: auto !important; /* 内容超出时显示垂直滚动条 */
    line-height: 1.5 !important; /* 设置行高，提升可读性 */
    padding: 8px 12px !important; /* 设置内边距 */
  }
</style>
