- <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>