assessDetail.vue 10.7 KB
<route lang="yaml">
  name: assessDetail
</route>

<script lang="ts" setup name="assessDetail">
import { ref } from "vue";
import { useRouter, useRoute } from "vue-router";
import Table from "@/components/Table/index.vue";
import {
  getRecordRuleConfDetail,
  getExecPlanDetailTableData,
  getAssessTableRulesData,
  downloadDirtyData
} from '@/api/modules/dataQualityAssess';
import { ElMessage } from "element-plus";
import { changeNum, download } from '@/utils/common';
import ruleForm from "../data_quality/ruleForm.vue";

const { proxy } = getCurrentInstance() as any;

const router = useRouter();
const route = useRoute();

const planGuid = route.query.planGuid;
const planExecGuid = route.query.planExecGuid;

const page = ref({
  limit: 50,
  curr: 1,
  sizes: [
    { label: "10", value: 10 },
    { label: "50", value: 50 },
    { label: "100", value: 100 },
    { label: "150", value: 150 },
    { label: "200", value: 200 },
  ],
});

const tableInfo = ref({
  id: "quality-table",
  loading: false,
  fields: [
    { label: "表名", field: "qualityModelName", width: 140 },
    { label: "执行结果", field: "execResult", type: "tag", width: 100, align: "center" },
    { label: "评估时间", field: "execTime", width: 180, },
    {
      label: "耗时(秒)", field: "execDuration", width: 100, align: "right", getName: (scope) => {
        return scope.row.execDuration != null ? changeNum(scope.row.execDuration ?? 0) : '--';
      }
    },
    {
      label: "规则数", field: "ruleNum", width: 100, align: "right", getName: (scope) => {
        return scope.row.ruleNum != null ? changeNum(scope.row.ruleNum ?? 0) : '--';
      }
    },
    {
      label: "评估总数", field: "totalNum", width: 100, align: "right", getName: (scope) => {
        return scope.row.totalNum != null ? changeNum(scope.row.totalNum ?? 0) : '--';
      }
    },
    {
      label: "合格条数", field: "qualifiedNum", width: 100, align: "right", getName: (scope) => {
        return scope.row.qualifiedNum != null ? changeNum(scope.row.qualifiedNum ?? 0) : '--';
      }
    },
    {
      label: "不合格条数", field: "unqualifiedNum", width: 100, align: "right", getName: (scope) => {
        return scope.row.unqualifiedNum != null ? changeNum(scope.row.unqualifiedNum ?? 0) : '--';
      }
    },
    {
      label: "合格率", field: "qualifiedRate", width: 100, align: "right", getName: (scope) => {
        return scope.row.qualifiedRate != null ? ((scope.row.qualifiedRate ?? 0).toFixed(2) + '%') : '--';
      }
    },
    { label: "评估范围", field: "dataRange", width: 180 },
  ],
  data: [],
  showPage: false,
  actionInfo: {
    label: "操作",
    type: "btn",
    width: 220,
    fixed: 'right',
    btns: (scope) => {
      let unqualifiedNum = scope.row.unqualifiedNum ?? 0;
      return [
        { label: "查看规则", value: "rule" },
        { label: "脏数据", value: "path_dirty", disabled: unqualifiedNum == 0 || scope.row.isTable == 'Y' },
        { label: "脏数据下载", value: "download", disabled: unqualifiedNum == 0 || scope.row.isTable == 'Y' },
      ]
    },
  }
});

/** 获取方案详情列表数据。 */
const getAssessDetail = () => {
  tableInfo.value.loading = true;
  getExecPlanDetailTableData({ planGuid: planGuid, planExecGuid: planExecGuid }).then((res: any) => {
    tableInfo.value.loading = false;
    if (res.code == proxy.$passCode) {
      tableInfo.value.data = res.data || []
    } else {
      ElMessage.error(res.msg);
    }
  });
}

/** 获取每个表的规则详情。 */
const getModelRulesDetail = (qualityModelGuid: string) => {
  rulesDetailTableInfo.value.loading = true;
  getAssessTableRulesData({ planExecGuid: planExecGuid, qualityModelGuid: qualityModelGuid }).then((res: any) => {
    rulesDetailTableInfo.value.loading = false;
    if (res.code == proxy.$passCode) {
      rulesDetailTableInfo.value.data = res.data || [];
    } else {
      ElMessage.error(res.msg);
    }
  });
}

/** 下载脏数据。 */
const exportDirtyData = (row) => {
  downloadDirtyData({
    planExecGuid: row.planExecGuid,
    qualityModelGuid: row.qualityModelGuid
  }).then((res: any) => {
    if (res && !res.msg) {
      download(res, `脏数据-${row.qualityModelName}.xlsx`, 'excel');
    } else {
      res?.msg && ElMessage.error(res?.msg);
    }
  })
}

const tableBtnClick = (scope, btn) => {
  const type = btn.value;
  const row = scope.row;
  if (type == 'rule') {
    rulesDetailDialogVisible.value = true;
    getModelRulesDetail(row.qualityModelGuid);
  } else if (type == 'path_dirty') {
    router.push({
      name: 'assessDirty',
      query: {
        planExecGuid: row.planExecGuid,
        name: row.qualityModelName,
        qualityModelGuid: row.qualityModelGuid
      }
    });
  } else if (type == 'download') {
    exportDirtyData(row);
  }
};

onActivated(() => {
  getAssessDetail();
});

/** 查看表规则详情的对话框显示隐藏。 */
const rulesDetailDialogVisible = ref(false);

const rulesDetailTableInfo: any = ref({
  id: "rules-detail-table",
  loading: false,
  fields: [
    { label: "序号", type: "index", width: 56, align: "center" },
    { label: "表名", field: "qualityModelName", width: 140 },
    { label: "规则类型", field: "ruleName", width: 140 },
    { label: "规则名称", field: "ruleConfName", width: 140 },
    { label: "规则大类", field: "largeCategory", width: 100 },
    { label: "规则小类", field: "smallCategory", width: 140 },
    { label: "规则字段", field: "ruleField", width: 140 },
    { label: "执行结果", field: "execResult", type: "tag", width: 100, align: "center" },
    // { label: "规则权重", field: "weight", width: 100, align: 'right' },
    {
      label: "评估总数", field: "totalNum", width: 100, align: "right", getName: (scope) => {
        return scope.row.totalNum != null ? changeNum(scope.row.totalNum ?? 0) : '--';
      }
    },
    {
      label: "合格条数", field: "qualifiedNum", width: 100, align: "right", getName: (scope) => {
        return scope.row.qualifiedNum != null ? changeNum(scope.row.qualifiedNum ?? 0) : '--';
      }
    },
    {
      label: "不合格条数", field: "unqualifiedNum", width: 100, align: "right", getName: (scope) => {
        return scope.row.unqualifiedNum != null ? changeNum(scope.row.unqualifiedNum ?? 0) : '--';
      }
    },
    {
      label: "合格率", field: "qualifiedRate", width: 100, align: "right", getName: (scope) => {
        return scope.row.qualifiedRate != null ? ((scope.row.qualifiedRate ?? 0).toFixed(2) + '%') : '--';
      }
    },
    { label: "失败原因", field: "errorLog", width: 140 },
  ],
  data: [],
  showPage: false,
  actionInfo: {
    label: "操作",
    type: "btn",
    width: 90,
    fixed: 'right',
    btns: [
      { label: "规则详情 ", value: "ruleDetail" },
    ],
  }
});

/** 单个规则详情对话框 */
const oneRulesDetailDialogVisible = ref(false);

const toSubjectTables: any = ref([]);
const ruleType = ref('');
const detailInfo: any = ref({});
const detailLoading = ref(false);
const ruleTypeList: any = ref([]);
const smallCategoryList: any = ref([]);
const largeCategoryList: any = ref([]);
const detailJson: any = ref({});

const rulesDetailTableBtnClick = (scope, btn) => {
  const type = btn.value;
  const row = scope.row;
  if (type == 'ruleDetail') {
    detailLoading.value = true;
    if (detailJson.value[row.ruleConfGuid]) {
      ruleType.value = detailInfo.value.ruleCode;
      toSubjectTables.value = [{
        guid: detailInfo.value.subjectGuid,
        enName: detailInfo.value.subjectName,
        chName: detailInfo.value.subjectZhName,
        label: `${detailInfo.value.subjectName}(${detailInfo.value.subjectZhName})`
      }]
      ruleTypeList.value = [{
        value: detailInfo.value.ruleCode,
        label: row.ruleName
      }];
      smallCategoryList.value = [{
        value: detailInfo.value.smallCategory,
        label: row.smallCategory
      }];
      largeCategoryList.value = [{
        value: detailInfo.value.largeCategory,
        label: row.largeCategory
      }];
      oneRulesDetailDialogVisible.value = true;
    } else {
      detailJson.value[row.ruleConfGuid] = { isRequest: true };
      getRecordRuleConfDetail({ruleConfGuid: row.ruleConfGuid, planExecGuid: planExecGuid }).then((res: any) => {
        detailLoading.value = false;
        oneRulesDetailDialogVisible.value = true;
        if (res.code == proxy.$passCode) {
          let data = res.data || {};
          detailInfo.value = data;
          detailJson.value[row.ruleConfGuid] = detailInfo.value;
          detailJson.value[row.ruleConfGuid].isRequest = false;
          ruleType.value = detailInfo.value.ruleCode;
          toSubjectTables.value = [{
            guid: detailInfo.value.subjectGuid,
            enName: detailInfo.value.subjectName,
            chName: detailInfo.value.subjectZhName,
            label: `${detailInfo.value.subjectName}(${detailInfo.value.subjectZhName})`
          }]
          ruleTypeList.value = [{
            value: detailInfo.value.ruleCode,
            label: row.ruleName
          }];
          smallCategoryList.value = [{
            value: detailInfo.value.smallCategory,
            label: row.smallCategory
          }];
          largeCategoryList.value = [{
            value: detailInfo.value.largeCategory,
            label: row.largeCategory
          }];
        } else {
          ElMessage.error(res.msg);
          delete detailJson.value[row.ruleConfGuid];
        }
      })
    }
  }
};

</script>

<template>
  <div class="container_wrap">
    <div class="table_panel_wrap">
      <Table :tableInfo="tableInfo" @tableBtnClick="tableBtnClick" />
    </div>
    <el-dialog v-model="rulesDetailDialogVisible" title="查看规则" width="800" :modal="true" :close-on-click-modal="false"
      destroy-on-close align-center>
      <div class="rules-detail-dialog-content">
        <Table class="long-tooltip-table" :tableInfo="rulesDetailTableInfo" @tableBtnClick="rulesDetailTableBtnClick" />
      </div>
    </el-dialog>
    <el-dialog v-model="oneRulesDetailDialogVisible" title="规则详情" width="800" :modal="true"
      :close-on-click-modal="false" destroy-on-close align-center>
      <ruleForm ref="ruleFormRef" :readonly="true" :toSubjectTables="toSubjectTables" :ruleTypeValue="ruleType"
        :value="detailInfo" :ruleTypeList="ruleTypeList" :largeCategoryList="largeCategoryList"
        :smallCategoryList="smallCategoryList">
      </ruleForm>
    </el-dialog>
  </div>
</template>

<style lang="scss" scoped>
.container_wrap {
  padding: 16px;
}

.table_panel_wrap {
  height: 100%;
}

.rules-detail-dialog-content {
  height: 450px;
}

.long-tooltip-table {
  :deep(.el-table) {
    .table_cell_tooltip {
      max-width: 500px;
      // max-height: 100px;
      // overflow: auto;
    }
  }
}
</style>