<template>
  <div id="pro-table">
    <!-- 表格工具栏 -->
    <div class="pro-table-tool" :style="proTableToolStyle">
      <!-- 自定义工具栏 -->
      <div class="pro-table-prev" >
        <!-- 将工具栏改为合并后的 mergedToolbar，包含外部传入与内置的 打印/导出 按钮 -->
        <template :key="index" v-for="(item, index) in mergedToolbar">
          <!-- 更多按钮 -->
          <pro-authority :value="item.code ? item.code : false" v-if="item.children && item.children.length > 0">
            <a-dropdown>
              <!-- 支持 danger 与 icon 插槽 -->
              <a-button :danger="item.danger === true || item.type === 'danger'"
                        @click="item.event(selectedRowKeys)">
                <template v-if="item.icon" #icon>
                  <component :is="item.icon" />
                </template>
                {{ item.label }}
              </a-button>
              <template #overlay>
                <a-menu>
                  <!-- 遍历子集 -->
                  <pro-authority v-for="(child, i) in item.children" :key="i" :value="child.code ? item.code : false">
                    <a-menu-item>
                      <a @click="child.event(selectedRowKeys)">{{ child.label }}</a>
                    </a-menu-item>
                  </pro-authority>
                </a-menu>
              </template>
            </a-dropdown>
          </pro-authority>
          <pro-authority :value="item.code ? item.code : false" v-else>
            <a-button size="small"
              :type="item.type&&['primary','ghost','dashed','link','text','default',].includes(item.type) ? item.type : 'default'"
              :danger="item.danger === true || item.type === 'danger'"
              @click="item.event(selectedRowKeys)" :style="item.style ?? ''">
              <template v-if="item.icon" #icon>
                <component :is="item.icon" />
              </template>
              {{ item.label }}
            </a-button>
          </pro-authority>
        </template>
      </div>
      <!-- 默认工具栏：使用 Antd a-table-settings 呈现（列设置 + 行高），并保留刷新按钮 -->
      <div class="pro-table-next" v-if="defaultToolbar">
        <a-table-settings v-model:columns="columnsModel" :sizeOptions="[]" size="small"/>
        <!-- <a-button @click="reload" style="margin-left: 8px">
          <template #icon>
            <SyncOutlined />
          </template>
        </a-button> -->
      </div>
    </div>
    <!--数据导出栏-->
    <!-- <excelExport ref = "excelExportRef" :columns="columns" :data-source="datasourceExport" >
    </excelExport> -->
    <a-table bordered :columns="columns" :data-source="datasourceExport" :id="tableId" :rowKey="rowKey"
      :pagination="exportExcelPagination" style="display: none">
    </a-table>
    <!-- 表格组件 -->
    <a-table id="table" :rowKey="rowKey" @change="fetch" :columns="columnsModel" :loading="loading" :pagination="pagination"
      :dataSource="datasource" :row-selection="rowSelection"
      :row-height="100" :customRow="rowClick" :sortDirections="['descend', 'ascend', '']"
      :rowClassName="setRowClassName" @resizeColumn="handleResizeColumn">
      <!--列搜索组件封装-->
      <template #customFilterDropdown="{ setSelectedKeys, selectedKeys, confirm, clearFilters, column }">
        <div style="padding: 8px">
          <a-input ref="searchInput" :placeholder="'请输入'" :value="selectedKeys[0]"
            style="width: 188px; margin-bottom: 8px; display: block"
            @change="(e) => {
              setSelectedKeys(e.target.value ? [e.target.value] : []);
              setSelectedKeysOnChange(e, e.target.value ? {[column.dataIndex]:e.target.value} : {[column.dataIndex]:e.target.value});}"
            @pressEnter="handleSearch(selectedKeys, confirm, column.dataIndex)" />
          <a-button type="primary" size="small" style="width: 90px; margin-right: 8px"
            @click="handleSearch(selectedKeys, confirm, column.dataIndex)">
            <template #icon>
              <SearchOutlined />
            </template>
            搜索
          </a-button>
          <a-button size="small" style="width: 90px" @click="handleReset(clearFilters, setSelectedKeys, column.dataIndex, confirm)">重置</a-button>
        </div>
      </template>
      <!--列过滤组件封装-->
      <template #columnfilter="{ setSelectedKeys, selectedKeys, confirm, clearFilters, column }">
        <div style="padding: 8px">
          <!--多选 -->
          <div v-if="column.filterMultiple && column.filterMultiple===true"
            style="width: 120px; margin-bottom: 8px; display: block">
            <a-checkbox-group @change="(values) => {
                  changeFilteredStatus(column.dataIndex, true);
                  setSelectedKeys(values ? values : []);
                  setSelectedKeysOnChange(values, values ? {[column.dataIndex]:values} : {[column.dataIndex]:[]});
                  }" :value="selectedKeys">
              <a-checkbox v-for="d in column.filters" :key="d" :value="d.value">{{d.label}}</a-checkbox>
            </a-checkbox-group>
          </div>
          <!--单选 -->
          <div v-else style="width: 120px; margin-bottom: 8px; display: block">
            <a-radio-group @change="(e) => {
                  changeFilteredStatus(column.dataIndex, true);
                  setSelectedKeys(e.target.value ? [e.target.value] : []);
                  setSelectedKeysOnChange(e, e.target.value ? {[column.dataIndex]:e.target.value} : {[column.dataIndex]:e.target.value});
                  }" :value="selectedKeys[0]">
              <a-radio v-for="d in column.filters" :key="d" :value="d.value">{{d.label}}</a-radio>
            </a-radio-group>
          </div>
          <a-button type="primary" size="small" style="width: 60px; margin-right: 8px"
            @click="handleSearch(selectedKeys, confirm, column.dataIndex)">
            <template #icon>
              <SearchOutlined />
            </template>
            确认
          </a-button>
          <a-button size="small" style="width: 60px" @click="handleReset(clearFilters)">重置</a-button>
        </div>
      </template>
      <!--列排序组件封装-->
      <template #customFilterIcon="filtered">
        <search-outlined :style="{ color: filtered ? '#108ee9' : undefined }" />
      </template>

      <!-- 表格头部单元格插槽 -->
      <template #headerCell="{ column }">
        <span>{{ column.title }}</span>
      </template>

      <!-- 表格内容单元格插槽 -->
      <template #bodyCell="{ column, record, index }">
        <!-- 序号 列 -->
         <template v-if="column.dataIndex === 'index'">
            {{ index + 1 }}
        </template>
        <!-- 行操作 -->
        <template v-if="column.dataIndex === 'operate'">
          <template :key="i" v-for="(item, i) in operate">
            <!-- 下拉操作 -->
            <a-dropdown v-if="item.children && item.children.length > 0">
              <a> {{ item.label }} </a>
              <template #overlay>
                <a-menu>
                  <!-- 遍历子集 -->
                  <pro-authority v-for="(child, i) in item.children" :key="i" :value="child.code ? item.code : false">
                    <a-menu-item>
                      <a @click="child.event(selectedRowKeys)">
                        {{ child.label }}
                      </a>
                    </a-menu-item>
                  </pro-authority>
                </a-menu>
              </template>
            </a-dropdown>
            <!-- 单个操作 -->
            <pro-authority :value="item.code ? item.code : false" v-else>
              <a-popconfirm v-if="item.isDel" title="确认删除?" ok-text="确认" cancel-text="取消"
                @confirm="item.delEvent && item.delEvent(record)"
                @cancel="item.cancelEvent ? item.cancelEvent(record) : null">
                <a-button type="text" danger >{{ item.label || '删除' }}</a-button>
              </a-popconfirm>
              <div style="display: inline-block" v-else>
                <a @click="item.event(record)"> {{ item.label }} </a>
              </div>
              <a-divider type="vertical" v-if="i != operate.length - 1" />
            </pro-authority>
          </template>
        </template>

        <!-- 开关转换 -->
        <template v-else-if="column.switch">
          <a-switch @change="column.switch.event($event, record)"
            :checked="record[column.dataIndex] === column.switch.yes" checked-children="启用" un-checked-children="禁用" />
        </template>

        <!-- 文本转换 -->
        <template v-else-if="column.conver">
          <template v-for="(data, index) in column.conver">
            <span :key="index" v-if="data.value === record[column.dataIndex]">
              {{ data.label }}
            </span>
          </template>
        </template>

        <!-- 头像 -->
        <template v-else-if="column.avatar">
          <!-- 空头像 -->
          <a-avatar v-if="record[column.dataIndex] == null" :size="column.avatar.size" :shape="column.avatar.shape">
            <template #icon>
              <UserOutlined />
            </template>
          </a-avatar>
          <!-- 非头像 -->
          <a-avatar v-else :src="record[column.dataIndex]" :size="column.avatar.size" :shape="column.avatar.shape" />
        </template>

        <!-- 数据字典 -->
        <template v-else-if="column.dictionary">
          <pro-dictionary :code="column.dictionary.code" :type="column.dictionary.type"
            v-model="record[column.dataIndex]"></pro-dictionary>
        </template>

        <!-- 预览 -->
        <template v-else-if="column.image">
          <a-image :width="column.image.width" :src="record[column.dataIndex]" />
        </template>

        <!-- 右对齐数字列：千位分隔格式化显示 -->
        <template v-else-if="column.align === 'right'">
          {{ formatNumber(record[column.dataIndex]) }}
        </template>

        <!-- 原样输出 -->
        <template v-else>
          {{ record[column.dataIndex] }}
        </template>
      </template>

      <!-- 内容插槽 -->
      <template v-for="name in slotsData" #[name]="{ record }">
        <slot :name="name" :record="record"></slot>
      </template>
      <!--分页插件-->
      <template>
        <a-pagination v-if="pagination"
          v-model:current="pagination.current"
          :page-size-options="pagination.pageSizeOptions"
          :total="pagination.total"
          show-size-changer
          :page-size="pagination.pageSize"
          @showSizeChange="onShowSizeChange">
          <template #buildOptionText="props">
            <span v-if="props.value !== '50'">{{ props.value }}条/页</span>
            <span v-else>全部</span>
          </template>
        </a-pagination>
      </template>

      <!-- 页脚字段汇总模板,取datasource中的第一条数据渲染table -->
      <template #footer="" v-if="showPageTotal && datasource.length>0">
        <a-table id="totalTable" :rowKey="rowKey" :data-source=" datasource.slice(0, 1)" :columns="columns"
          :pagination="false" :showHeader="false" :bordered=false size="small">
          <template #bodyCell="{ column, record }">
            <!-- 开关转换 -->
            <template v-if="column.dataIndex === 'operate'">
              <span :style="{fontSize: '14px', color: '#08c'}">合计</span>
            </template>
            <template v-else-if="column.showTotal">
              <span :style="{fontSize: '14px', color: '#08c'}">
                {{column.title}}<br />合计：{{ getSum(datasource, column.dataIndex,record) }}{{ column.totalUnit || '' }}
              </span>
            </template>
            <template v-else>
              <!-- 原样输出 -->
            </template>
          </template>
        </a-table>
      </template>
    </a-table>
  </div>
</template>
<script>
  import FileSaver from 'file-saver';
  import * as XLSX from 'xlsx/xlsx.mjs';
  import T from "@hwork/ant-design-vue/es/table/Table";
  //import excelExport from "../module/ExportExcel"
  import {
    list
  } from '../../../api/module/dictData.js';
  import {
    useStore
  } from 'vuex';
  import { message } from '@hwork/ant-design-vue';
  import {
    defineComponent,
    onMounted,
    reactive,
    toRefs,
    toRef,
    watch,
    ref,
    nextTick,
    computed
  } from "vue";
  import {
    SyncOutlined,
    UserOutlined,
    SearchOutlined,
  } from "@ant-design/icons-vue";
  //table搜索列插槽
  const searchInput = ref();
  const excelExportRef = ref();

  const TProps = T.props;
  // const currentRow = [];
  export default defineComponent({
    name: "pro-table",
    currentRowI: 999,
    components: {
      SyncOutlined,
      UserOutlined,
      SearchOutlined,
      //excelExport
    },
    /// 数据来源
    props: Object.assign({}, TProps, {
      /// 扩展参数
      param: {
        type: Object,
        default: {},
      },
      /// 数据来源
      fetch: {
        type: Function,
        required: false,
      },
      /// 数据解析
      columns: {
        type: Array,
        required: true,
      },
      /// 头工具栏（外部传入）
      toolbar: {
        type: Array,
      },
      /// 是否自动添加序号列（默认关闭：只有 columns 明确包含 index 才显示）
      autoIndex: {
        type: Boolean,
        default: false,
      },
      /// 是否存在查询条件（用于控制工具栏上边距）
      hasSearch: {
        type: Boolean,
        default: true,
      },
      /// 是否在左侧工具栏追加内置按钮（打印、导出）
      showPrint: {
        type: Boolean,
        default: true,
      },
      showExport: {
        type: Boolean,
        default: true,
      },
      defaultToolbar: {
        type: Boolean,
        default: true,
      },
      /// 行工具栏
      operate: {
        type: Array || Boolean,
        default: false,
      },
      /// 分页参数
      pagination: {
        type: [Object, Boolean],
        default: false,
      },
      rowSelection: {
        type: Object,
      },
      rowKey: {
        type: String,
        default: "id",
      },
      //用于导出数据定位时使用
      tableId: {
        type: String,
        default: "tableExport",
      },
      //是否展示table的统计插件
      showPageTotal: {
        type: Boolean,
        default: false,
      },
    }),
    setup(props) {
      const slotsData = ref([]);
      const store = useStore();
      // 更新 slotsData 的处理逻辑，不再依赖 column.slots
      props.columns.map((value) => {
        if (value.slots && value.slots.customRender) {
          slotsData.value.push(value.slots.customRender);
        }
      });

      /// 状态共享
      const state = reactive({
        pagination: props.pagination == false ? false : props.pagination, // 分页
        datasource: [], // 数据源
        datasourceExport: [], // 导出数据源
        currentRow: [], // 选择行
        loading: true, // 加载
        //excel导出表单所需的分页信息
        exportExcelPagination: {
          pageNum: 1,
          pageSize: 2000
        }, // 加载
        columns: props.columns, // 字段（与 a-table-settings v-model:columns 双向绑定）
        filtrationColumnKeys: [], // 过滤
        selectedRowKeys: [], // 选中项
        size: "small", // 表格大小
        //列搜索的查询条件
        columnSearchParams: {},
        //受列过滤的列下标
        filterColumnsIndex: [],
      });

      /// 默认操作
      // 序号列：如果外部未提供，且开启 autoIndex，则自动在最左侧追加
      const hasIndexCol = (cols) => (cols || []).some(col => col && (col.dataIndex === 'index' || col.key === 'index'))
      if (props.autoIndex && !hasIndexCol(state.columns)) {
        state.columns.unshift({
          dataIndex: 'index',
          key: 'index',
          title: '序号',
          width: 60,
          fixed: 'left',
          align: 'center',
          customRender: ({ index }) => {
            try {
              if (state.pagination !== false) {
                const current = Number(state.pagination.current || state.pagination.pageNum || 1)
                const pageSize = Number(state.pagination.pageSize || 20)
                return (current - 1) * pageSize + index + 1
              }
            } catch (e) {}
            return index + 1
          },
        })
      }

      if (props.operate != false) {
        // 基于可见操作项估算更贴合的列宽（考虑权限过滤、文案长度、分隔符）
        const estimateOperateWidth = () => {
          const items = Array.isArray(props.operate) ? props.operate : []
          // 过滤权限不可见的操作；有 children 的看父项本身
          const powerList = (store.getters && store.getters.power) ? store.getters.power : []
          const isVisible = (it) => {
            if (!it) return false
            if (!it.code) return true
            return powerList.indexOf(it.code) !== -1
          }
          const visible = items.filter(it => isVisible(it))

          // 文本测量：使用 canvas 估算宽度
          const getTextWidth = (text) => {
            try {
              const canvas = document.createElement('canvas')
              const ctx = canvas.getContext('2d')
              if (!ctx) return 0
              ctx.font = '14px -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans"'
              return Math.ceil(ctx.measureText(String(text || '')).width)
            } catch (e) {
              return (String(text || '').length) * 14
            }
          }
          // 每个操作项：文本宽度 + 左右间距（约16）
          const itemsWidth = visible.reduce((acc, it) => acc + getTextWidth(it.label || '') + 16, 0)
          // 分隔符（竖线）与间距：约 12px * (n-1)
          const sepWidth = visible.length > 1 ? (visible.length - 1) * 12 : 0
          // 左右安全内边距
          const padding = 12
          const total = padding + itemsWidth + sepWidth + padding
          // 兜底区间
          return Math.min(Math.max(total, 96), 260)
        }

        const operateCol = {
          dataIndex: 'operate',
          key: 'operate',
          title: '操作',
          fixed: 'right',
          width: estimateOperateWidth(),
        }
        state.columns.push(operateCol)

        // 权限/操作项变化后，动态更新宽度
        const recompute = () => {
          const idx = state.columns.findIndex(c => c.dataIndex === 'operate')
          if (idx !== -1) state.columns[idx].width = estimateOperateWidth()
        }
        // 监听权限与传入的 operate 变化
        watch(() => store.getters && store.getters.power, recompute)
        watch(() => props.operate, recompute, { deep: true })
      }

      // 内置左侧工具栏按钮：打印、导出（可通过 props.showPrint / props.showExport 控制）
      const builtinPrevToolbar = () => {
        const items = [];
        if (props.showPrint) {
          items.push({ label: "打印", event: print, icon: 'PrinterOutlined' });
        }
        if (props.showExport) {
          items.push({ label: "导出", event: ExportExcel, icon: 'CloudDownloadOutlined' });
        }
        return items;
      };

      // 合并外部 toolbar 和内置按钮
      const mergedToolbar = computed(() => {
        const ext = Array.isArray(props.toolbar) ? props.toolbar : [];
        return [...ext, ...builtinPrevToolbar()];
      });
      // 无查询条件时，为外层工具栏增加上内边距
      const proTableToolStyle = computed(() => (props.hasSearch ? {} : { paddingTop: '16px' }));

      /**
       * 从服务端获取下拉字典数据，并对数据进行格式化
       * @param code 字典值
       * @returns []
       */
      // const getDictData = async function(code) {
      //   await list({
      //     code: code
      //   }).then((response) => {
      //      console.log("获取字典", code)
      //     if(response.success){
      //       var dict = response.data.map(item => {
      //         let { id, label, value, color, code, remark } = item
      //         return { id, label, text: label, value, color, code, remark };
      //       });
      //       store.dispatch("user/addDictData", {
      //         "code": code,
      //         "value": dict
      //       });
      //       return dict;
      //     }else{
      //       console.log(response.msg)
      //       return []
      //     }
      //   });
      // };
      const getDictData = async function(code) {
        try {
          const response = await list({ code: code });
          var dict = response.data.map(item => {
            let { id, label, value, color, code: dictCode, remark } = item;
            return { id, label, text: label, value, color, dictCode, remark };
          });
          store.dispatch("user/addDictData", { "code": code, "value": dict });
          return dict;
        } catch (error) {
          console.error('获取字典数据失败:', error);
          throw error;
        }
      };

      /**
       * 从本地获取缓存的字典数据，单本地不存在时，从远端获取
       * @param code
       * @returns {{label: *, value: string}[]}
       */
      const getListData = async function(code) {
        if (code && code.length > 0) {
          let dictData = store.getters.dict; //.length > 0 ? store.getters.dict : store.getters.dictData;
          if (dictData && dictData.length > 0) {
            const index = dictData.findIndex(item => item.code === code);
            if (index != -1) {
              return dictData[index].value;
            } else {
              console.log("table 没有 第一次添加", code)
              return await getDictData(code)
            }
          } else {
            console.log("table 字典未初始化 从后端获取", code)
            return await getDictData(code);
          }
        } else {
          return [];
        }
      };

      /// 初始化列：设置字典/过滤等；兼容 antdv4 新 API（customFilterDropdown/customFilterIcon），避免 column.slots 警告
      state.columns.forEach(async (column) => {
        //因为列过滤的渲染优先于dictionary组件的渲染，所以字典的初始化放在table列初始化中
        let dict = [];
        if (column.dictionary && column.dictionary.code) {
          dict = await getListData(column.dictionary.code);
        }
        if (column.showSearch ? column.showSearch : false) {
          column.filtered = false;
          if (column.dictionary) {
            //添加列过滤模板
            state.filterColumnsIndex.push(column.dataIndex);
            column.filters = dict;
            column.filterSearch = true;
          }
          // 新 API：使用 customFilterDropdown 开启自定义下拉，图标使用插槽或默认样式
          column.customFilterDropdown = true;
        }
        // 兼容：若非 showSearch 但需要显示自定义过滤图标/下拉，可在外部传入 column.slots 自定义
      });

      /// 过滤字段
      const filtrationColumns = [];
      props.columns.forEach(function(item) {
        filtrationColumns.push({
          label: item.title,
          value: item.key,
        });
        state.filtrationColumnKeys.push(item.key);
      });

      /// 过滤字段
      const filtration = function(value) {
        state.columns = props.columns.filter((item) => value.includes(item.key));
        state.filtrationColumnKeys = value;
      };

      // 与 a-table-settings 建立明确的 v-model 引用
      const columnsModel = toRef(state, 'columns');
      // 如果需要自定义控制，也可用 visibleColumns 过滤 display=false；
      // 现在直接将 columnsModel 传给 a-table，交由组件库内部处理 display 过滤
      //table 开启列可自由托动大小
      const handleResizeColumn = function(w, col) {
        console.log("handleResizeColumn")
        col.width = w;
      }

      /// 选中回调
      const onSelectChange = (selectedRowKeys) => {
        state.selectedRowKeys = selectedRowKeys;
      };
      /**
       * 列搜索 条件改变事件
       * 将旧的查询条件替换为新的值
       * @param e 下拉值改变事件
       * @param columnData 被输入搜索条件的键值对 eg :{"invoiceCode":"12"}
       */
      const setSelectedKeysOnChange = (e, columnData) => {
        state.columnSearchParams = Object.assign({}, state.columnSearchParams, columnData)
        console.log("setSelectedKeysOnChange", state.columnSearchParams)
      };
      /**
       * 列搜索 搜索按钮触发
       * 查询条件的优先级
       * 1.pro-search组件中的props.param；
       * 2.列搜索中的参数对象 state.columnSearchParams；
       * @param selectedKeys 输入框中输入的值，array
       * @param confirm 确认时执行的方法
       * @param dataIndex 当前字段的 key
       * @returns 触发表单重写加载
       */
      const handleSearch = async (selectedKeys, confirm, dataIndex) => {
        confirm();
        state.loading = true;
        try {
          // 将请求参数与列搜索参数进行合并
          const pageInfo = await getPageInfo(undefined);
          let searchParams = Object.assign({}, pageInfo, state.columnSearchParams, props.param)
          console.log("查询条件", searchParams)
          const { total, data } = await props.fetch(searchParams);
          if (state.pagination != false) {
            state.pagination.total = total || 0;
          }
          state.datasource = data || [];
        } catch (error) {
          console.error('列搜索请求失败:', error);
          if (state.pagination != false) state.pagination.total = 0;
          state.datasource = [];
        } finally {
          state.loading = false;
        }
      };

      /**
       * 列过滤触发后，改变列过滤字段的风格
       * @param dataIndex 当前字段的 key
       * @param status 当前字段的 key
       */
      const changeFilteredStatus = async (dataIndex, nweStatus) => {
        console.log("changeFilteredStatus")
        state.filterColumnsIndex.push(dataIndex);
        const index = state.columns.findIndex(item => item.dataIndex === dataIndex);
        if (index != -1) {
          state.columns[index].filtered = nweStatus;
        }
      };

      /// 列搜索条件重置：清空 UI 与内部条件并刷新
      const handleReset = (clearFilters, setSelectedKeys, dataIndex, confirm) => {
        console.log("列搜索条件重置")
        // 清空该列的 UI 值
        if (typeof setSelectedKeys === 'function') setSelectedKeys([])
        // 清空内存中的查询条件
        if (dataIndex) {
          const { [dataIndex]: _, ...rest } = state.columnSearchParams
          state.columnSearchParams = rest
        } else {
          state.columnSearchParams = {}
        }
        //重置列搜索的相关条件
        if (state.filterColumnsIndex.length > 0) {
          state.filterColumnsIndex.forEach((columnIndex) => {
            //找到指定下标的数据，修改选中状态
            const index = state.columns.findIndex(item => item.dataIndex === columnIndex);
            if (index != -1) {
              state.columns[index].filtered = false;
            }
          });
          state.filterColumnsIndex = []
        }
        // 清理 antd 内部选中并同步到表格
        if (typeof clearFilters === 'function') clearFilters()
        if (typeof confirm === 'function') confirm()
        fetchData();
      };

      /**
       * 将小驼峰转换为下划线连接
       *  eg : palletCode --> pallet_code,sourceLocCode -->source_loc_code
       * @param str 需要转换的字符串
       * @param targetStr
       */
      const toUnderline = function(str) {
        return str.replace(/([a-z])([A-Z])/g, '$1_$2').toLowerCase();
      }

      // 数字格式化（千位分隔），保留原有小数位
      const formatNumber = function(val) {
        if (val === null || val === undefined || val === '') return ''
        if (typeof val === 'string' && val.trim() === '-') return val
        const raw = String(val).replace(/,/g, '')
        if (!/^[-+]?\d*(\.\d+)?$/.test(raw)) return val
        const negative = raw.startsWith('-')
        const numStr = negative ? raw.slice(1) : raw
        const [intPart, decPart] = numStr.split('.')
        const intWithSep = intPart.replace(/\B(?=(\d{3})+(?!\d))/g, ',')
        return (negative ? '-' : '') + intWithSep + (decPart ? '.' + decPart : '')
      }

      /// 数据请求
      const fetchData = async (pagination, filters, sorter) => {
        console.log("filters 列过滤条件", filters)
        // 与 a-table 的变更同步分页状态
        if (state.pagination !== false) {
          if (pagination && typeof pagination.current !== 'undefined') {
            state.pagination.current = pagination.current;
            state.pagination.pageNum = pagination.current;
            state.pagination.pageSize = pagination.pageSize;
          } else {
            if (typeof state.pagination.current === 'undefined') {
              state.pagination.current = state.pagination.pageNum || 1;
            }
          }
        }
        // 分页信息：包含queryType，当queryType = 'like'时，配合后端使用模糊查询
        const pageInfo = await getPageInfo(pagination);
        state.loading = true;
        try {
          let sortFeild = null
          if (sorter && sorter.columnKey && sorter.order) {
            sortFeild = {
              sortColumn: toUnderline(sorter.columnKey),
              sortType: sorter.order ? (sorter.order === 'ascend' ? 'ASC' : sorter.order === 'descend' ? 'DESC' : '') : ''
            }
            console.log('sortFeild 列排序条件', sortFeild)
          }
          const searchParams = Object.assign({}, pageInfo, state.columnSearchParams, props.param, sortFeild)
          console.log('查询条件', searchParams)
          const { total, data } = await props.fetch(searchParams)
          if (state.pagination != false) state.pagination.total = total || 0
          state.datasource = data || []
        } catch (error) {
          console.error('表格加载失败:', error)
          if (state.pagination != false) state.pagination.total = 0
          state.datasource = []
          // 可选：给出全局提示
          // message.error('数据加载失败')
        } finally {
          state.loading = false
        }
      };

      ///从上下文中获取分页信息，随着分页属性的复杂化，并不是所有分页属性都需要放到请求消息中
      const getPageInfo = async (pagination) => {
        let pageInfo = {};
        if (pagination != undefined) {
          //分页查询触发搜索
          const { pageNum, pageSize, current } = pagination
          pageInfo['pageNum'] = current;
          pageInfo['pageSize'] = pageSize;
          pageInfo['queryType'] = 'like';
        } else {
          //搜索组件触发搜索：此时没有current
          const { pageNum, pageSize, current } = state.pagination
          pageInfo['pageNum'] = pageNum;
          pageInfo['pageSize'] = pageSize;
          pageInfo['queryType'] = '';
        }
        return pageInfo;
      };

      // 分页器尺寸变更处理（配合自定义分页器）
      const onShowSizeChange = (current, pageSize) => {
        if (state.pagination !== false) {
          state.pagination.pageSize = pageSize;
          state.pagination.current = current;
          state.pagination.pageNum = current;
        }
        fetchData({ current, pageSize });
      };

      /// 刷新方法
      const reload = function() {
        console.log("刷新方法")
        state.columnSearchParams = {};
        fetchData();
      };

      /// 初始数据
      onMounted(async () => {
        console.log("初始数据")
        await fetchData();
      });

      /// 监听扩展参数, 触发表格刷新
      watch(
        () => props.param,
        () => {
          console.log("监听扩展参数, 触发表格刷新")
          fetchData();
        }, {
          deep: true,
        }
      );

      /// 改变按钮尺寸
      const changeSize = (target) => {
        state.size = target;
      };

      /// 表格打印
      const print = function() {
        let subOutputRankPrint = document.getElementById("pro-table");
        let newContent = subOutputRankPrint.innerHTML;
        let oldContent = document.body.innerHTML;
        document.body.innerHTML = newContent;
        window.print();
        window.location.reload();
        document.body.innerHTML = oldContent;
      };
      //数据导出
      const ExportExcel = async function() {
        console.log(" props.tableId",  props.tableId)
        state.loading = true;
        //主表携带的查询条件
        let panes = store.getters.panes;
        let activeKey = store.getters.activeKey;
        var exportFileName =  panes.filter(item => item.path == activeKey)[0].title+new Date().toLocaleString().replace(/[/]/g, '_').replace(/[:]/g, '');
        console.log("ExportExcel tablename", exportFileName)
        try {
          state.exportExcelPagination.pageNum = 1;
          state.exportExcelPagination.pageSize = state.pagination.total;
          let searchParams = Object.assign({}, state.exportExcelPagination, state.columnSearchParams, props.param)
          console.log('导出数据条件', searchParams)
          const { total, data } = await props.fetch(searchParams)
          if (data) {
            state.datasourceExport = data;
            nextTick(() => {
              exportDataMethod(props.tableId, exportFileName);
            })
          }
        } catch (error) {
          console.error('导出失败:', error)
          message.error('导出失败')
        } finally {
          state.loading = false
        }
      };

      const exportDataMethod = function(elementId ,fileName) {
        let element = XLSX.utils.table_to_book(document.querySelector('#'+elementId));
        //console.log('workbook: ', element);
        // element.Sheets.Sheet1['!cols'][0]={hidden:true}
        let etout = XLSX.write(element, {
          bookType: 'xlsx',
          bookSST: true,
          type: 'array'
        });
        try {
          FileSaver.saveAs(new Blob([etout], {
            type: 'application/octet-stream'
          }), fileName+".xlsx");
        } catch (e) {
          console.log(e, etout);
        }
        return etout;
      };
       const exportExcelWithData = function(fileName,dataSource) {
        console.log("组件中的导出");
        // this.downloadLoading = true;
        // 将数据源转换为工作表
        const ws = XLSX.utils.json_to_sheet(dataSource);
        // 创建工作簿并添加工作表
        const wb = XLSX.utils.book_new();
        XLSX.utils.book_append_sheet(wb, ws, 'Sheet1');

        // 获取二进制字符串作为输出
        const wbout = XLSX.write(wb, {
          bookType: 'xlsx',
          bookSST: true,
          type: 'array'
        });

        try {
          FileSaver.saveAs(
            new Blob([wbout], {
              type: 'application/octet-stream'
            }),
            fileName + '.xlsx'
          );
        } catch (e) {
          if (typeof console !== 'undefined') console.log(e, wbout);
        }

        // this.downloadLoading = false;
        return wbout;
      }

      return {
        state,
        /// 数据信息
        ...toRefs(state),
        /// 数据加载
        fetch: fetchData,
        /// 刷新方法
        reload,
        /// 过滤字段
        filtrationColumns,
        filtration,
        handleResizeColumn,
        /// 选中字段
        onSelectChange,
        /// 改变大小
        changeSize,
        /// 打印/导出
        print,
        ExportExcel,
        /// 合并后的工具栏
        mergedToolbar,
        proTableToolStyle,

        columnsModel,

        slotsData,
        handleReset,
        handleSearch,
        setSelectedKeysOnChange,
        changeFilteredStatus,
        onShowSizeChange,

        // 工具函数
        formatNumber
      };
    },

    methods: {
      rowClick: function(record, index) {
        return {
          onClick: (event) => {
            this.currentRow = record; //自己定义个变量，用于保存点击行的数据
          },
        };
      },
      // 行样式设置
      setRowClassName: function(record, index) {
        let rowColor = index % 2 === 0 ? "evenRowStyl" : ""; //判断单双行，赋予不同样式
        return record === this.currentRow ? "clickRowStyl" : rowColor; //赋予点击行样式
        // return  rowColor;//赋予点击行样式
      },
      compare: function(a, b) {
        return a.length - b.length;
      },
      // 底部统计数据计算
      getSum: function(data, dataIndex, record) {
        console.log("getSum")
        console.log("record", record)
        const sum = data.reduce((acc, cur) => {
          return acc + Number(cur[dataIndex]);
        }, 0);
        return sum;
      },

    },
  });
</script>
