123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184 |
- <template>
- <div>
- <div class="table-container" :style="props.tableStyle">
- <div class="btn-toggle-table" :class="{ 'hide-table': hideTable }" @click="hideTable = !hideTable">
- {{ hideTable ? '展开' : '收起' }}明细数据<svg width="14" height="14" viewBox="0 0 14 14" fill="none"
- xmlns="http://www.w3.org/2000/svg">
- <path d="M10.5 8.75L7 5.25L3.5 8.75" stroke="#167AF0" stroke-width="1.5" stroke-linecap="round"
- stroke-linejoin="round" />
- </svg>
- </div>
- <div v-if="fileName" class="export-button" @click="handleExportData(dataList, columns, fileName)">导出
- <span style="vertical-align: middle; margin: 0 0 0 8px;">
- <Svg name="export2"></Svg>
- </span>
- </div>
- <el-table class="table" :data="paginatedData" row-key="name" style="width: 100%"
- :cell-style="cellStyle" :header-cell-style="headerCellStyle" v-if="!hideTable">
- <el-table-column v-for="(column, index) in columns" :key="column.prop" :label="column.label"
- :prop="column.prop" show-overflow-tooltip :formatter="statusFormatter">
- <template #default="scope">
- {{ scope.row[column.prop] }}
- </template>
- </el-table-column>
- </el-table>
- <pagination v-if="!hideTable && !hidePage" @current-change="handleCurrentChange" @size-change="handleSizeChange"
- v-bind="state.pagination">
- </pagination>
- </div>
- </div>
- </template>
- <script setup lang="ts">
- import { BasicTableProps, useTable } from '/@/hooks/table';
- import { ref, reactive, PropType, watch, computed } from 'vue'
- import { exportToExcel, formatTableDataForExport } from '/@/utils/exportExcel';
- import { useMessage } from '/@/hooks/message';
- import Svg from '/@/components/Svg.vue';
- const cellStyle = ref({
- textAlign: 'center',
- fontSize: '14px',
- height: '50px',
- background: 'transparent !important'
- })
- const headerCellStyle = ref({
- textAlign: 'center',
- border: 'none',
- background: 'rgba(244, 245, 250, 1)',
- height: '32px',
- color: 'rgba(100, 100, 100, 1)',
- fontSize: '14px',
- })
- const props = defineProps({
- data: {
- type: Array,
- default: () => []
- },
- columns: {
- type: Array as PropType<{ prop: string; label: string }[]>,
- default: () => []
- },
- fileName: {
- type: String,
- default: ''
- },
- hideTable: {
- type: Boolean,
- default: true
- },
- tableStyle: {
- type: Object,
- default: () => ({})
- },
- hidePage: {
- type: Boolean,
- default: false
- }
- })
- // 表格数据
- const dataList = ref(props.data);
- const hideTable = ref(props.hideTable);
- const state: BasicTableProps = reactive<BasicTableProps>({
- queryForm: {
- ip: '',
- },
- pageList: () => Promise.resolve([]),
- pagination: {
- current: 1,
- size: 5,
- total: 0,
- pageSizes: [5, 10, 20, 50, 100]
- },
- // dataList: []
- });
- // 计算分页后的数据
- const paginatedData = computed(() => {
- if (!state.pagination || typeof state.pagination.current === 'undefined' || typeof state.pagination.size === 'undefined') {
- return dataList.value;
- }
- const start = (state.pagination.current - 1) * state.pagination.size;
- const end = start + state.pagination.size;
- return dataList.value.slice(start, end);
- });
- watch(() => props.data, (newVal) => {
- dataList.value = newVal;
- console.log(`dataList: `);
- console.log(dataList.value);
- state.pagination!.total = dataList.value.length;
- }, { immediate: true, deep: true })
- const { getDataList, currentChangeHandle, sizeChangeHandle, tableStyle } = useTable(state);
- // 重写分页处理函数,实现本地分页
- const handleCurrentChange = (val: number) => {
- state.pagination!.current = val;
- };
- const handleSizeChange = (val: number) => {
- state.pagination!.size = val;
- state.pagination!.current = 1; // 切换每页条数时重置到第一页
- };
- const statusFormatter = (row: any, column: any, cellValue: any, index: any) => {
- return cellValue || '--';
- }
- const handleExportData = (data: any, columns: any, fileName: string) => {
- try {
- // 检查是否有数据
- if (!data || data.length === 0) {
- useMessage().warning('没有数据可导出');
- return;
- }
- const exportData = formatTableDataForExport(data, columns);
- exportToExcel(exportData, fileName);
- } catch (error) {
- console.error('导出失败:', error);
- useMessage().error('导出失败,请检查数据格式');
- }
- }
- </script>
- <style scoped lang="scss">
- @import '/@/views/count/styles/common.scss';
- svg {
- vertical-align: middle;
- margin: 0 0 0 12px;
- }
- .table-container {
- margin: 0 auto;
- width: 100%;
- max-width: 1360px;
- }
- .export-button {
- font-size: 14px;
- font-family: Source Han Sans SC;
- font-weight: 500;
- font-size: 14px;
- color: rgba(22, 122, 240, 1);
- svg {
- margin-left: 8px;
- margin-right: 0;
- }
- }
- :deep(.el-input__inner),
- :deep(.el-date-editor--dates .el-input__wrapper) {
- cursor: pointer;
- }
- </style>
|