anonResultView.vue 6.5 KB
<route lang="yaml">
    name: anonResultView
    </route>

<script lang="ts" setup name="anonResultView">
import { ref } from "vue";
import {
  getAnonPageData,
  getAnonAnalyzeResult,
  exportAnonExecData,
} from "@/api/modules/dataAnonymization";
import { calcColumnWidth } from "@/utils/index";
import Moment from 'moment';
import { TableColumnWidth } from "@/utils/enum";
import { ElMessage } from "element-plus";
import { commonPageConfig } from '@/components/PageNav/index';
import { download } from "@/utils/common";

const { proxy } = getCurrentInstance() as any;

const route = useRoute();

const props = defineProps({
  isPage: {
    default: true,
    type: Boolean
  },
  execGuid: {
    default: '',
    type: String
  }
});

const tableData: any = ref([]);
const tableDataLoading = ref(false);

const tableFields: any = ref([]);

const pageInfo: any = ref({
  ...commonPageConfig,
  rows: 0,
})

const getData = () => {
  tableData.value = [];
  if (!tableFields.value?.length) {
    return;
  }
  tableDataLoading.value = true;
  getAnonPageData({
    pageIndex: pageInfo.value.curr,
    pageSize: pageInfo.value.limit,
    taskExecGuid: props.isPage ? route.query.execGuid : props.execGuid,
  }).then((res: any) => {
    tableDataLoading.value = false;
    if (res.code == proxy.$passCode) {
      tableData.value = [];
      res.data?.records?.forEach(d => {
        let obj = {};
        tableFields.value.forEach(t => {
          obj[t.enName] = d.fieldValue?.[t.enName];
        });
        tableData.value.push(obj);
      });
      pageInfo.value.rows = res.data?.totalRows ?? 0;
    } else {
      ElMessage.error(res.msg);
    }
  });
}

const getTextAlign = (field) => {
  if (field.dataType === 'decimal' || field.dataType === 'int' || field.dataType == 'bit' || field.dataType == 'tinyint') {
    return 'right';
  }
  return 'left'
}

/** otherWidth表示使用标题宽度时添加标题排序图标等宽度 */
const calcTableColumnWidth = (data: any[], prop, title, otherWidth = 0) => {
  let d: any[] = [];
  data.forEach((dt) => d.push(dt[prop]));
  return calcColumnWidth(
    d,
    title,
    {
      fontSize: 14,
      fontFamily: "SimSun",
    },
    {
      fontSize: 14,
      fontFamily: "SimSun",
    },
    otherWidth
  );
};

/** 每列字段对应的列宽计算结果。 */
const originTableFieldColumn = ref({});

watch(
  tableData,
  (val: any[], oldVal) => {
    if (!tableFields.value?.length) {
      originTableFieldColumn.value = {};
      return;
    }
    originTableFieldColumn.value = {};
    tableFields.value.forEach((field, index) => {
      originTableFieldColumn.value[field.enName] = calcTableColumnWidth(
        val?.slice(0, 20) || [],
        field.enName,
        field.chName,
        24
      );
    });
  },
  {
    deep: true,
  }
);

watch(() => props.execGuid, (val) => {
  if (!val) {
    return;
  }
  tableDataLoading.value = true;
  getAnonAnalyzeResult(val).then((res: any) => {
    tableDataLoading.value = false;
    if (res.code == proxy.$passCode) {
      let column = res.data?.column || {};
      tableFields.value = column;
      pageInfo.value.curr = 1;
      getData();
    } else {
      ElMessage.error(res.msg);
    }
  });
}, {
  immediate: true
})

onBeforeMount(() => {
  if (!props.isPage) {
    return;
  }
  tableDataLoading.value = true;
  getAnonAnalyzeResult(route.query.execGuid).then((res: any) => {
    tableDataLoading.value = false;
    if (res.code == proxy.$passCode) {
      let column = res.data?.column || {};
      tableFields.value = column;
      getData();
    } else {
      ElMessage.error(res.msg);
    }
  });
});

const formatterPreviewDate = (row, info) => {
  let enName = info.enName;
  let v = row[enName];
  if (v === 0) {
    return v;
  }
  if (!v || v == 'null') {
    return '--';
  }
  if (info.dataType === 'datetime') {
    return Moment(v).format('YYYY-MM-DD HH:mm:ss');
  }
  if (info.dataType === 'date') {
    if (isNaN(<any>(new Date(v)))) {
      return Moment(parseInt(v)).format('YYYY-MM-DD');
    } else {
      return Moment(v).format('YYYY-MM-DD');
    }
  }
  return v;
};

const pageChange = (info) => {
  pageInfo.value.curr = Number(info.curr);
  pageInfo.value.limit = Number(info.limit);
  getData();
}

const promise: any = ref(null);

const exportData = () => {
  if (promise.value) {
    return;
  }
  promise.value = exportAnonExecData({
    taskGuid: route.query.guid,
    execGuid: route.query.execGuid
  }).then((res: any) => {
    promise.value = null;
    if (res && !res.msg) {
      download(res, route.query.taskName + '_匿名化数据.xlsx', 'excel')
    } else {
      res?.msg && ElMessage.error(res?.msg);
    }
  }).catch(() => {
    promise.value = null;
  })
}

</script>

<template>
  <div class="table_tool_wrap" v-loading="tableDataLoading">
    <el-button v-show="props.isPage" style="margin-bottom: 8px;" type="primary" @click="exportData"
      v-preReClick>导出数据</el-button>
    <el-table ref="tableRef" v-show="tableFields.length" :data="tableData" :highlight-current-row="true" stripe border
      tooltip-effect="light" height="100%" row-key="guid" :style="{ width: '100%', height: !props.isPage ? 'calc(100% - 34px)' : 'calc(100% - 64px)' }">
      <template v-for="(item, index) in (tableFields || [])">
        <el-table-column :label="item.chName" :width="item.dataType === 'datetime'
          ? TableColumnWidth.DATETIME
          : item.dataType === 'date'
            ? TableColumnWidth.DATE
            : originTableFieldColumn[item.enName]
          " :align="getTextAlign(item)" :header-align="getTextAlign(item)"
          :formatter="(row) => formatterPreviewDate(row, item)" :show-overflow-tooltip="true">
        </el-table-column>
      </template>
    </el-table>
    <div v-show="!tableFields.length" class="empty-content">
      <img src="../../assets/images/empty-data.png" :style="{ width: '168px', height: '96px' }" />
      <div class="empty-text">暂无数据</div>
    </div>
    <PageNav :class="[pageInfo.type]" :pageInfo="pageInfo" @pageChange="pageChange" />
  </div>
</template>

<style lang="scss" scoped>
.table_tool_wrap {
  width: 100%;
  height: 100%;
  padding: 8px 16px 16px;

  .tips_text {
    font-size: 14px;
    color: var(--el-text-color-tip);
    display: block;
    font-weight: normal;
    margin-bottom: 8px;
    line-height: 21px;
  }

  .el-table {
    display: inline-block;
  }

  .empty-content {
    display: flex;
    align-items: center;
    justify-content: center;
    height: 100%;
    width: 100%;
    flex-direction: column;

    .empty-text {
      font-size: 14px;
      color: #b2b2b2;
    }
  }
}
</style>