123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184 |
- <script setup lang="ts">
- import { ref, provide, onMounted } from 'vue'
- import { post, get } from "@/utils/request";
- import { GET_RES_BY_FORM_JSON } from '../api';
- import type { TableColumnCtx, SummaryMethod } from 'element-plus'
- import rangeFilter from "./rangeFilter.vue";
- import { rangeGetSql } from '../function';
- import { formatDate } from '@/utils/times';
- const rangeFilterRef = ref<InstanceType<typeof rangeFilter> | null>(null);
- const SQLstr = ref<string>('')
- const driginalDataTableList = ref<any[]>([])
- const addEditData = JSON.parse(sessionStorage.getItem('reportJson') || '{}')
- const tableHeader = ref<any[]>([])
- const tableData = ref<any[]>([])
- const tableLoading = ref(false)
- const dataRangeData = ref<any[]>([])
- const dataRangeDataVisable = ref(false)
- const listThatNeedsToBeGrouped = ref<number[]>([]) // 分组索引
- const listStatisticsList = ref<number[]>([]) // 统计索引
- const tableKey = ref<number>(1)
- // 统计
- const getSummaries: SummaryMethod<any> = (params) => {
- const { columns, data } = params
- const sums: (string)[] = []
- columns.forEach((column, index) => {
- if (index === 0) {
- sums[index] = '合计'
- return
- }
- const values = data.map(item => Number(item[column.property as string]))
- if (!values.every(value => isNaN(value)) && listStatisticsList.value.includes(index)) {
- const total = values.reduce((prev, curr) => {
- const value = Number(curr)
- if (!isNaN(value)) {
- return prev + curr
- } else {
- return prev
- }
- }, 0)
- sums[index] = total.toFixed(2) // 保证返回 string,解决类型报错
- } else {
- sums[index] = ''
- }
- })
- return sums
- }
- // 合并分组
- function mergeColumns({ row, rowIndex, columnIndex }: { row: any, rowIndex: number, columnIndex: number }) {
- // 只处理需要合并的列
- if (!listThatNeedsToBeGrouped.value.includes(columnIndex)) {
- return { rowspan: 1, colspan: 1 };
- }
- const field = tableHeader.value[columnIndex]?.label;
- if (!field) return { rowspan: 1, colspan: 1 };
- // 当前行之前的内容已经合并过,直接跳过
- if (rowIndex > 0 && tableData.value[rowIndex - 1][field] === row[field]) {
- return { rowspan: 0, colspan: 0 }; // 隐藏
- }
- // 计算当前单元格应该合并多少行
- let rowspan = 1;
- for (let i = rowIndex + 1; i < tableData.value.length; i++) {
- if (tableData.value[i][field] === row[field]) {
- rowspan++;
- } else {
- break;
- }
- }
- return { rowspan, colspan: 1 };
- }
- function determinationOfDataRange() {
- const rangeFilterData = rangeFilterRef.value?.getRangeData()
- const rangeSQL = rangeGetSql(rangeFilterData, addEditData)
- const sqlList = SQLstr.value.split('where')[0]
- SQLstr.value = `${sqlList}${rangeSQL}`
- dataRangeDataVisable.value = false
- getData()
- }
- function setDataRange() {
- dataRangeDataVisable.value = true
- setTimeout(() => {
- rangeFilterRef.value?.setRangeData(dataRangeData.value)
- }, 100)
- }
- function getData() {
- tableLoading.value = true
- post(GET_RES_BY_FORM_JSON, { formJson: SQLstr.value }).then(res => {
- tableData.value = res.data
- setTimeout(() => {
- tableKey.value++
- }, 100)
- }).finally(() => {
- tableLoading.value = false
- })
- }
- async function initializedData(SQL: string, rangeFilterList: any[], tableData: any[]) {
- await filterGroupStatistics(tableData)
-
- const heading = tableData.map(item => ({
- filed: `${item.tableName}_${item.columnName}`,
- label: item.columnComment,
- type: item.dataType,
- }))
-
- driginalDataTableList.value = tableData
- tableHeader.value = heading
- dataRangeData.value = rangeFilterList
- SQLstr.value = SQL
- console.log(tableHeader.value, '<==== tableHeader.value')
- getData()
- }
- // 过滤出需要分组和统计的数组
- function filterGroupStatistics(tableData: any[]) {
- return new Promise<void>((resolve) => {
- const numberList = tableData.map((item: any, index: number) => item?.singleColumnOperation?.grouping ? index : 9999)
- const statisticsList = tableData.map((item: any, index: number) => item?.singleColumnOperation?.statistics ? index : 9999)
- listThatNeedsToBeGrouped.value = numberList.filter((item: any) => item != 9999)
- listStatisticsList.value = statisticsList.filter((item: any) => item != 9999)
- resolve()
- })
- }
- defineExpose({
- initializedData
- });
- onMounted(() => { })
- </script>
- <template>
- <div class="h-full flex flex-col">
- <div class="flex items-center mb-4 h-[5%]">
- <el-button type="primary" @click="setDataRange()">设置数据范围</el-button>
- </div>
- <div class="flex-1 h-[92%]">
- <el-table :data="tableData" border style="width: 100%;height: 100%" v-loading="tableLoading" :span-method="mergeColumns" :summary-method="getSummaries" :show-summary="listStatisticsList.length > 0 ? true : false" :key="tableKey">
- <el-table-column :prop="item.label" :label="item.label" min-width="240" v-for="(item, index) in tableHeader">
- <template #default="scope">
- <template v-if="item.type == 'timestamp' || item.type == 'datetime' || item.type == 'timestamp' || item.type == 'date'">
- {{ scope.row[item.label] ? formatDate(new Date(scope.row[item.label])) : '' }}
- </template>
- <template v-else>
- {{ scope.row[item.label] }}
- </template>
- </template>
- </el-table-column>
- </el-table>
- </div>
- <!-- 数据范围弹框 -->
- <el-dialog v-model="dataRangeDataVisable" width="680" :show-close="false" top="10vh">
- <template #header="{ close, titleId, titleClass }">
- <div class="flex justify-between items-center border-b pb-3 dialog-header">
- <h4 :id="titleId">数据范围</h4>
- <div class="flex">
- <el-button @click="dataRangeDataVisable = false">取消</el-button>
- <el-button type="primary" @click="determinationOfDataRange()">确定</el-button>
- </div>
- </div>
- </template>
- <div class="p-8">
- <rangeFilter ref="rangeFilterRef" />
- </div>
- </el-dialog>
- </div>
- </template>
- <style lang="scss"></style>
|