Newer
Older
KaiFengPC / src / views / preassess / evaluation / mark.vue
@zhangdeliang zhangdeliang on 23 May 8 KB 初始化项目
<template>
  <el-card class="box-card">
    <el-table
      :data="tableData"
      v-loading="loading"
      element-loading-text="数据加载中..."
      :span-method="objectSpanMethod"
      :border="true"
      max-height="400px"
    >
      <el-table-column label="评价类型" prop="evaluationType" width="100" />
      <el-table-column label="类型分值" prop="evaluationTypeScore" width="60" />
      <el-table-column label="评价内容" prop="evaluationContent" width="100" />
      <el-table-column label="分项分值" prop="evaluationContentScore" width="60" />
      <el-table-column label="评价规则" prop="evaluationRule" />
      <el-table-column label="细项分值" prop="evaluationRuleScore" width="60" />
      <el-table-column label="评估结果" prop="operateList" width="180">
        <template #default="{ row }">
          <el-radio-group v-model="row.operateInfo.status" :disabled="row.canOperate === 0 || opts.type === 'view'">
            <el-radio v-for="item in row.operateInfo.list" :label="item.value" :key="item.value" @click="operateChange(row, item)">
              {{ item.label }}
            </el-radio>
          </el-radio-group>
        </template>
      </el-table-column>
      <el-table-column label="细项得分" prop="fineScore" width="60" />
      <el-table-column label="分项得分" prop="itemizedScore" width="60" />
      <el-table-column label="类型得分" prop="typeScore" width="60" />
      <el-table-column label="佐证材料" width="200">
        <template #default="{ row }">
          <upload
            :file-list="row.fileSaveRequestList"
            :disabled="opts.type === 'view'"
            @success="
              file => {
                uploadSuccess(file, row);
              }
            "
          >
            <el-icon :size="20" class="pointer" :class="{ disabled: opts.type === 'view' }"><Upload /></el-icon>
          </upload>
          <div class="file-list">
            <div class="file" v-for="file in row.fileSaveRequestList">
              <span class="ellipsis" :title="file.name" :class="{ disabled: opts.type === 'view' }" @click="handlePreview(file)">{{
                file.name
              }}</span>
              <span class="del" @click="removeFile(file, row)" v-if="opts.type !== 'view'">删除</span>
            </div>
          </div>
        </template>
      </el-table-column>
    </el-table>
  </el-card>
</template>

<script setup>
import { onMounted, nextTick } from 'vue';
import { getScoreList } from '@/api/preassess/evaluation';
import upload from './upload';
import useTable from './mixins';
const { proxy } = getCurrentInstance();

const props = defineProps({
  id: {
    type: [String, Number],
    default: '',
  },
  opts: {
    type: Object,
    default: () => {},
  },
  projectInfo: {
    type: Object,
    default: () => {},
  },
});
const { id, projectInfo, opts } = props;
const { treeData, loading, tableData, getTreeCurRow, setMergeData, handlePreview, uploadSuccess, removeFile } = useTable(
  proxy,
  opts,
  'evaluationRule'
);

const getTableList = async () => {
  const res = await getScoreList(projectInfo.engineeringType);
  if (res?.code !== 200) return;
  setFields(res.data, '0');
  setSort(res.data);
  computedScore(res.data);
  setMergeData(res.data);
  treeData.value = res.data;
  nextTick(() => {
    console.log(tableData.value);
  });
};

const getDetail = data => {
  setFields(data, '0');
  setSort(data);
  computedScore(data);
  setMergeData(data);
  treeData.value = data;
};

const setFields = (data, level) => {
  for (const item of data) {
    item.level = level;
    if (!item.fileSaveRequestList) {
      item.fileSaveRequestList = [];
    }
    switch (level) {
      case '0':
        item.sort = item.evaluationTypeRank;
        break;
      case '1':
        item.sort = item.evaluationContentRank;
        break;
      case '2':
        item.sort = item.evaluationRuleRank;
        if (item.calculateStandard === 'reach') {
          if (id) {
            const operateJson = JSON.parse(item.operateJson);
            item.operateInfo = operateJson;
          } else {
            item.operateInfo = {
              status: '1',
              list: [
                {
                  value: '1',
                  label: '是',
                  score: item.evaluationRuleScore,
                },
                {
                  value: '0',
                  label: '否',
                  score: 0,
                },
              ],
            };
          }
        } else {
          const operateJson = JSON.parse(item.operateJson);
          if (id) {
            item.operateInfo = operateJson;
          } else {
            const list = operateJson.map(item => ({
              value: item.value,
              label: item.name,
              score: item.value,
            }));
            const scorelist = list.map(item => item.value);
            const max = Math.max(...scorelist);
            const maxItem = list.find(it => it.value * 1 === max);
            item.operateInfo = {
              status: maxItem.value,
              list,
            };
          }
        }
        item.operateJson = JSON.stringify(item.operateInfo);
        break;
      default:
        break;
    }
    if (item.children) {
      setFields(item.children, level * 1 + 1 + '');
    }
  }
};

const setSort = data => {
  data.sort((a, b) => {
    return b.sort - a.sort;
  });
  for (const item of data) {
    if (item.children) {
      setSort(item.children);
    }
  }
};

// 计算分数
const computedScore = data => {
  for (const item1 of data) {
    const children1 = item1.children || [];
    for (const item2 of children1) {
      const children2 = item2.children || [];
      for (const item3 of children2) {
        item3.evaluationTypeScore = item1.evaluationTypeScore;
        item3.evaluationContentScore = item2.evaluationContentScore;
        if (!id) {
          item3.fineScore = item3.evaluationRuleScore;
          item3.itemizedScore = item3.evaluationContentScore;
          item3.typeScore = item3.evaluationTypeScore;
        }
      }
    }
  }
};

const operateChange = (row, item) => {
  if (row.canOperate === 0 || opts.type === 'view') return;
  const treeDataCurRow = getTreeCurRow(treeData.value, { nodeCode: row.nodeCode });
  treeDataCurRow.operateInfo.status = item.value;
  treeDataCurRow.operateJson = JSON.stringify(treeDataCurRow.operateInfo);
  dynamicComputedScore(row.nodeCode, item.score * 1);
};

const dynamicComputedScore = (nodeCode, score) => {
  const treeDataCurRow = getTreeCurRow(treeData.value, { nodeCode });
  treeDataCurRow.fineScore = score;

  const treeDataCurParentRow = getTreeCurRow(treeData.value, { nodeCode: treeDataCurRow.parentNodeCode });
  const itemizedScore = treeDataCurParentRow.children.reduce((pre, item) => {
    return (pre += item.fineScore * 1);
  }, 0);
  treeDataCurParentRow.children.forEach(item => {
    item.itemizedScore = itemizedScore;
  });
  const rootRow = getTreeCurRow(treeData.value, { nodeCode: treeDataCurParentRow.parentNodeCode });
  const typeScore = getTypeScore(rootRow.children);
  for (const item of rootRow.children) {
    for (const it of item.children) {
      it.typeScore = typeScore;
    }
  }
};

const getTypeScore = data => {
  let typeScore = 0;
  for (const item of data) {
    typeScore += item.children.reduce((pre, it) => {
      return (pre += it.fineScore * 1);
    }, 0);
  }
  return typeScore;
};

const getSum = data => {
  let sum = 0;
  for (const item of data) {
    const children = item.children || [];
    for (const it of children) {
      sum++;
      if (it.children) {
        getSum(it.children);
      }
    }
  }
  return sum;
};

// 表数据合并
const objectSpanMethod = ({ row, column, rowIndex, columnIndex }) => {
  if ([0, 1, 9].includes(columnIndex)) {
    const rowspan = row.length1 - rowIndex === row.sum1 ? row.sum1 : 0;
    return {
      rowspan,
      colspan: 1,
    };
  } else if ([2, 3, 8].includes(columnIndex)) {
    const rowspan = row.length2 - rowIndex === row.sum2 ? row.sum2 : 0;
    return {
      rowspan,
      colspan: 1,
    };
  }
};

onMounted(() => {
  if (!id) getTableList();
});

defineExpose({
  treeData,
  getDetail,
});
</script>

<style lang="scss" scoped>
.pointer {
  cursor: pointer;
}
.disabled {
  cursor: not-allowed !important;
}
.file-list {
  .file {
    display: flex;
    align-items: center;
  }
  .del {
    flex-shrink: 0;
    color: #f56c6c;
    cursor: pointer;
    margin-left: 10px;
  }
  .disabled {
    cursor: not-allowed !important;
  }
}
.ellipsis {
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
  cursor: pointer;
}
</style>