|
@@ -8,11 +8,20 @@ import type {
|
|
|
import type { TableData } from '@/types/Tables/table'
|
|
|
import type { PaginationConfig } from '@/types/Tables/pagination'
|
|
|
|
|
|
-import { computed, nextTick, onMounted, reactive, ref, watch } from 'vue'
|
|
|
+import {
|
|
|
+ computed,
|
|
|
+ nextTick,
|
|
|
+ onMounted,
|
|
|
+ reactive,
|
|
|
+ ref,
|
|
|
+ watch,
|
|
|
+ type Ref,
|
|
|
+} from 'vue'
|
|
|
|
|
|
import { Plus, Operation } from '@element-plus/icons-vue'
|
|
|
import { useTable } from '@/hooks/useTable'
|
|
|
import { useTableScroll } from '@/hooks/useTableScroll'
|
|
|
+import { generateUniqueFilename } from '@/utils/common'
|
|
|
|
|
|
import customIndicatorDialog from '../dialog/customIndicatorDialog.vue'
|
|
|
import TableQueryForm from './TableQueryForm.vue'
|
|
@@ -22,8 +31,12 @@ type CustomIndicatorDialog = InstanceType<typeof customIndicatorDialog>
|
|
|
|
|
|
const props = withDefaults(defineProps<TableProps>(), {
|
|
|
remotePagination: false,
|
|
|
+ excludeExportFields: () => ['action'],
|
|
|
})
|
|
|
|
|
|
+// tableRef
|
|
|
+const tableRef = ref<HTMLElement | null>(null)
|
|
|
+
|
|
|
// table 容器
|
|
|
const tableContent = ref<HTMLElement | null>(null)
|
|
|
|
|
@@ -55,6 +68,7 @@ const {
|
|
|
initTableFields,
|
|
|
initIndicatorFields,
|
|
|
setCacheTableData,
|
|
|
+ exportDataToExcel,
|
|
|
} = useTable()
|
|
|
|
|
|
const { initScroll, setScrollAndHeader, obScroll } = useTableScroll(
|
|
@@ -100,6 +114,9 @@ const tableSizeOb = new ResizeObserver((entries: ResizeObserverEntry[]) => {
|
|
|
elScrollBarH.value.style.left = left + 'px'
|
|
|
})
|
|
|
|
|
|
+// 表格加载状态
|
|
|
+const tableLoading = ref<boolean>(false)
|
|
|
+
|
|
|
// 表格字段信息
|
|
|
const tableFieldsInfo = reactive<Array<TableFields>>([])
|
|
|
|
|
@@ -132,6 +149,9 @@ const batchOperList = reactive<
|
|
|
},
|
|
|
])
|
|
|
|
|
|
+// 导出对话框的可见性
|
|
|
+const exportDialogVisble = ref<boolean>(false)
|
|
|
+
|
|
|
// 当前选中的方案,传给dialog
|
|
|
const nowScheme = computed(() => {
|
|
|
return {
|
|
@@ -140,6 +160,21 @@ const nowScheme = computed(() => {
|
|
|
}
|
|
|
})
|
|
|
|
|
|
+// 被排除的字段名
|
|
|
+const excludeFields = computed<Array<string>>(() => {
|
|
|
+ let result: Array<string> = []
|
|
|
+ props.tableFields.forEach(item => {
|
|
|
+ item.children.forEach(child => {
|
|
|
+ if (
|
|
|
+ props.excludeExportFields.includes(child.name) &&
|
|
|
+ child.name !== 'action'
|
|
|
+ )
|
|
|
+ result.push(child.label)
|
|
|
+ })
|
|
|
+ })
|
|
|
+ return result
|
|
|
+})
|
|
|
+
|
|
|
// 分页后的表格数据
|
|
|
const paginationTableData = computed<Array<TableData>>(() => {
|
|
|
let result: Array<TableData> = []
|
|
@@ -240,9 +275,28 @@ const updateIndicatorScheme = () => {
|
|
|
})
|
|
|
}
|
|
|
|
|
|
-// const initDialog = () => {
|
|
|
-// schemeActive.value = '默认'
|
|
|
-// }
|
|
|
+/**
|
|
|
+ * @description: 导出表格数据
|
|
|
+ * @return {*}
|
|
|
+ */
|
|
|
+const exportData = () => {
|
|
|
+ exportDataToExcel(
|
|
|
+ props.tableFields,
|
|
|
+ tableData,
|
|
|
+ generateUniqueFilename(),
|
|
|
+ props.excludeExportFields,
|
|
|
+ )
|
|
|
+ exportDialogVisble.value = false
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * @description: 更新表格状态
|
|
|
+ * @param {*} state
|
|
|
+ * @return {*}
|
|
|
+ */
|
|
|
+const changeTableLoading = (state: boolean) => {
|
|
|
+ tableLoading.value = state
|
|
|
+}
|
|
|
|
|
|
watch(
|
|
|
() => props.tableData,
|
|
@@ -256,7 +310,7 @@ watch(
|
|
|
newData,
|
|
|
)
|
|
|
|
|
|
- tableQueryFormRef.value?.initfilterForm()
|
|
|
+ tableQueryFormRef.value?.initFilterForm()
|
|
|
tableQueryFormRef.value?.initFilterFields()
|
|
|
updateIndicatorScheme() // 更新指标方案
|
|
|
schemeActive.value = '默认'
|
|
@@ -267,12 +321,15 @@ watch(
|
|
|
)
|
|
|
onMounted(() => {
|
|
|
initScroll()
|
|
|
+ tableQueryFormRef.value?.initFilterForm()
|
|
|
+ tableQueryFormRef.value?.initFilterFields()
|
|
|
tableVisOb.observe(tableContent.value as HTMLElement)
|
|
|
tableSizeOb.observe(tableContainer.value as HTMLElement)
|
|
|
})
|
|
|
|
|
|
defineExpose({
|
|
|
updateIndicatorScheme,
|
|
|
+ changeTableLoading,
|
|
|
})
|
|
|
</script>
|
|
|
|
|
@@ -309,7 +366,12 @@ defineExpose({
|
|
|
</div>
|
|
|
<div class="tableOperationRight">
|
|
|
<slot name="exportData">
|
|
|
- <el-button class="exportData w120 ml16" plain>导出数据</el-button>
|
|
|
+ <el-button
|
|
|
+ class="exportData w120 ml16"
|
|
|
+ plain
|
|
|
+ @click="exportDialogVisble = true"
|
|
|
+ >导出数据</el-button
|
|
|
+ >
|
|
|
</slot>
|
|
|
<slot name="customIndicator">
|
|
|
<el-popover
|
|
@@ -343,6 +405,7 @@ defineExpose({
|
|
|
</div>
|
|
|
<div class="tableContent" ref="tableContent">
|
|
|
<el-table
|
|
|
+ v-loading="tableLoading"
|
|
|
v-bind="{ ...$attrs, data: paginationTableData }"
|
|
|
style="width: 100%"
|
|
|
border
|
|
@@ -350,6 +413,8 @@ defineExpose({
|
|
|
:scrollbar-always-on="true"
|
|
|
:row-style="() => `height:${rowHeight}px;color:#333;`"
|
|
|
:header-row-style="() => `color:black`"
|
|
|
+ ref="tableRef"
|
|
|
+ id="table"
|
|
|
>
|
|
|
<template v-for="item in tableFieldsInfo" :key="item.name">
|
|
|
<el-table-column
|
|
@@ -401,6 +466,34 @@ defineExpose({
|
|
|
ref="customIndicatorDialogRef"
|
|
|
@update-fields="applyCustomIndicator"
|
|
|
></customIndicatorDialog>
|
|
|
+ <div class="exportDialog">
|
|
|
+ <el-dialog
|
|
|
+ v-model="exportDialogVisble"
|
|
|
+ title="提示"
|
|
|
+ width="550"
|
|
|
+ :show-close="false"
|
|
|
+ align-center
|
|
|
+ >
|
|
|
+ <template #header>
|
|
|
+ <div class="exportDialogHeader">
|
|
|
+ <span class="exportDialogHeaderTitle">提示</span>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ <div class="exportDialogBody">
|
|
|
+ <div style="font-size: 14px; font-weight: bold; margin-bottom: 8px">
|
|
|
+ 导出时,将自动过滤掉部分暂不支持导出的指标列内容:
|
|
|
+ </div>
|
|
|
+ <div style="font-size: 12px">{{ excludeFields.join('、') }}</div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <template #footer>
|
|
|
+ <div class="dialog-footer">
|
|
|
+ <el-button @click="exportDialogVisble = false">取消</el-button>
|
|
|
+ <el-button @click="exportData" color="#197afb"> 确定 </el-button>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ </el-dialog>
|
|
|
+ </div>
|
|
|
</div>
|
|
|
</template>
|
|
|
|
|
@@ -510,4 +603,33 @@ defineExpose({
|
|
|
.activeScheme {
|
|
|
color: #409eff;
|
|
|
}
|
|
|
+
|
|
|
+.exportDialogHeader {
|
|
|
+ box-sizing: content-box;
|
|
|
+ height: 18px;
|
|
|
+ padding: 10px 32px;
|
|
|
+ font-size: 18px;
|
|
|
+ font-weight: 700;
|
|
|
+ line-height: 18px;
|
|
|
+ border-bottom: 1px solid #e8eaec;
|
|
|
+}
|
|
|
+
|
|
|
+.exportDialogHeaderTitle {
|
|
|
+ display: block;
|
|
|
+ height: 18px;
|
|
|
+ font-size: 16px;
|
|
|
+ font-weight: 700;
|
|
|
+ line-height: 18px;
|
|
|
+ color: #333;
|
|
|
+ text-align: left;
|
|
|
+}
|
|
|
+
|
|
|
+.exportDialogBody {
|
|
|
+ width: 100%;
|
|
|
+ color: #606266;
|
|
|
+ font-size: 14px;
|
|
|
+ word-break: break-all;
|
|
|
+ // padding: 24px 32px 32px;
|
|
|
+ padding: 10px 32px;
|
|
|
+}
|
|
|
</style>
|