<template> <div class="mark" v-loading.fullscreen.lock="loading" element-loading-text="加载中..." element-loading-background="rgba(0, 0, 0, 0.6)"> <div class="body"> <el-form ref="ruleForm" :model="form"> <el-row :gutter="20"> <el-col :span="5"> <el-form-item label="评价规则:" prop="name"> <el-input v-model="form.name" placeholder="请输入评价规则" /> </el-form-item> </el-col> <el-col :span="4"> <el-form-item> <el-button type="primary" icon="Search" @click="search"> 查询</el-button> <el-button icon="Refresh" @click="resetQuery">重置</el-button> </el-form-item> </el-col> <el-col :span="15"> <el-button type="primary" style="float: right; margin-left: 10px" @click="save" :disabled="type === 'view'">保存</el-button> <el-button type="primary" style="float: right; margin-left: 10px" @click="enable" :disabled="type === 'view'">{{ statusText }}</el-button> <el-button type="primary" icon="Plus" style="float: right" :disabled="type === 'view'" @click="openDialog({}, '0', 'add')"> 新增评价类型</el-button > <upload class="upload" style="float: right" action="/prod-api/sponge/assessTargetConfigGradeItem/exportTargetConfigGradeItem" :data="{ targetId: markId }" :disabled="type === 'view'" @success=" data => { uploadSuccess(data); } " > <el-button type="primary" icon="Upload" :disabled="type === 'view'"> 导入</el-button> </upload> </el-col> </el-row> </el-form> <el-table ref="tableRef" :data="treeData" :max-height="600" row-key="nodeCode" v-loading="tableLoading"> <el-table-column label="评价类型" prop="evaluationType" width="120px"> <template #default="{ row }"> <span>{{ row.level === '0' ? row.evaluationType : '' }}</span> </template> </el-table-column> <el-table-column label="评价内容" prop="evaluationContent" width="120px"> <template #default="{ row }"> <span>{{ row.level === '1' ? row.evaluationContent : '' }}</span> </template> </el-table-column> <el-table-column label="评价规则" prop="evaluationRule" width="300px"> <template #default="{ row, $index }"> <div v-html="formatSearch(row, $index, row.evaluationRule)" v-if="row.level === '2'"></div> <span v-else></span> </template> </el-table-column> <el-table-column label="分值" prop="score" show-overflow-tooltip width="80px"> <template #default="{ row }"> <span v-if="row.level === '0'">{{ row.evaluationTypeScore }}</span> <span v-else-if="row.level === '1'">{{ row.evaluationContentScore }}</span> <span v-else-if="row.level === '2'">{{ row.evaluationRuleScore }}</span> </template> </el-table-column> <el-table-column label="评价标准" prop="calculateStandard" show-overflow-tooltip width="80px"> <template #default="{ row }"> <span>{{ calculateStandardText.get(row.calculateStandard) }}</span> </template> </el-table-column> <el-table-column label="是否可操作" prop="canOperate" width="90px"> <template #default="{ row }"> <el-switch v-model="row.canOperate" :active-value="1" :inactive-value="0" :disabled="row.canOperateDisabled || type === 'view'" @change=" val => { canOperateChange(row, val); } " /> </template> </el-table-column> <el-table-column label="启用状态" prop="status" width="90px"> <template #default="{ row }"> <el-switch v-model="row.status" active-value="1" inactive-value="0" @change=" val => { statusChange(row, val); } " :disabled="row.statusDisabled || type === 'view'" /> </template> </el-table-column> <el-table-column label="启用时间" prop="enableTime" show-overflow-tooltip width="160px" /> <el-table-column label="停用时间" prop="stopTime" show-overflow-tooltip width="160px" /> <el-table-column label="修改人" prop="updateBy" show-overflow-tooltip /> <el-table-column label="修改日期" prop="updateTime" show-overflow-tooltip width="160px" /> <el-table-column label="排序" show-overflow-tooltip width="110px"> <template #default="{ row }"> <el-button type="primary" link :disabled="getSortIsDisabled(row, 'ascending') || type === 'view'" @click="ascHandle(row)" >升序</el-button > <el-button type="primary" link :disabled="getSortIsDisabled(row, 'descending') || type === 'view'" @click="descHandle(row)" >降序</el-button > </template> </el-table-column> <el-table-column label="操作" width="260"> <template #default="{ row }"> <el-button type="primary" link v-if="row.level === '0'" @click="openDialog(row, row.level * 1 + 1 + '', 'add')" :disabled="type === 'view'" >新增评价内容</el-button > <el-button type="primary" link v-if="row.level === '1'" @click="openDialog(row, row.level * 1 + 1 + '', 'add')" :disabled="type === 'view'" >新增评价规则</el-button > <el-button type="primary" link v-if="row.level === '2'" @click="copy(row)" :disabled="type === 'view'">复制</el-button> <el-button type="primary" link @click="openDialog(row, row.level, 'view')">查看</el-button> <el-button type="primary" link @click="openDialog(row, row.level, 'edit')" :disabled="type === 'view'">修改</el-button> <el-button type="danger" link @click="del(row)" :disabled="type === 'view'">删除</el-button> </template> </el-table-column> </el-table> </div> <el-dialog v-model="visible" :title="`${operateInfo.text}`" :close-on-click-modal="false" :width="operateInfo.width" :before-close="close" class="dialog" > <el-form ref="dialogFormRef" :model="dialogForm" :rules="dialogFormRules" v-if="operateInfo.level" :disabled="operateInfo.type === 'view' || type === 'view'" > <el-row v-if="operateInfo.level === '0'"> <el-col :span="20" :offset="2"> <el-form-item label="评价类型:" prop="evaluationType"> <el-input v-model="dialogForm.evaluationType" placeholder="请输入评价类型" /> </el-form-item> </el-col> </el-row> <el-row :gutter="20" v-if="operateInfo.level === '1'"> <el-col :span="12"> <el-form-item label="评价内容:" prop="evaluationContent"> <el-input v-model="dialogForm.evaluationContent" placeholder="请输入评价内容" /> </el-form-item> </el-col> <el-col :span="12"> <el-form-item label="评价类型:" prop="evaluationType"> <el-input v-model="dialogForm.evaluationType" :disabled="true" /> </el-form-item> </el-col> </el-row> <el-row :gutter="20" v-if="operateInfo.level === '2'"> <el-col :span="12"> <el-form-item label="评价规则:" prop="evaluationRule"> <el-input v-model="dialogForm.evaluationRule" placeholder="请输入评价规则" /> </el-form-item> </el-col> <el-col :span="12"> <el-form-item label="评价标准:" prop="calculateStandard"> <el-select v-model="dialogForm.calculateStandard" placeholder="请选择评价标准" style="width: 100%"> <el-option label="达标" value="reach" /> <el-option label="评级" value="rate" /> </el-select> </el-form-item> </el-col> <el-col :span="12" v-if="dialogForm.calculateStandard === 'reach'"> <el-form-item label="分值:" prop="evaluationRuleScore"> <el-input v-model="dialogForm.evaluationRuleScore" placeholder="请输入分值" /> </el-form-item> </el-col> <el-col :span="12"> <el-form-item label="评价内容:" prop="evaluationContent"> <el-input v-model="dialogForm.evaluationContent" :disabled="true" /> </el-form-item> </el-col> <el-col :span="12"> <el-form-item label="评价类型:" prop="evaluationType"> <el-input v-model="dialogForm.evaluationType" :disabled="true" /> </el-form-item> </el-col> </el-row> </el-form> <rate ref="rateRef" :type="operateInfo.type" :operateJson="dialogForm.operateJson" v-if="operateInfo.level && dialogForm.calculateStandard === 'rate'" /> <template #footer v-if="operateInfo.type !== 'view'"> <div class="dialog-footer"> <el-button type="primary" @click="submit">保存</el-button> <el-button @click="close">取消</el-button> </div> </template> </el-dialog> </div> </template> <script setup> import { ref, nextTick, onMounted, reactive } from 'vue'; import { v4 as uuidv4 } from 'uuid'; import useUserStore from '@/store/modules/user'; import { getAssessTargetConfigGradeItem, assessTargetConfigGradeItemBatchUpdate, assessTargetConfigOpen, assessTargetConfigClose, } from '@/api/preassess/examineManage.js'; import { optTextMap } from '@/utils/map'; import { inheritAttr } from '@/utils/v3'; import { numberValidate } from '../validate'; import useTable from '../mixins'; import rate from './rate.vue'; import upload from '../upload.vue'; const { proxy } = getCurrentInstance(); const props = defineProps({ editObj: { type: Object, default: {}, }, }); let { type, status, engineeringType, markId } = props.editObj; const statusText = ref(status === '1' ? '停用' : '启用'); const { form, treeData, visible, curRow, operateInfo, getTreeCurRow, search, resetQuery, goBack, close, statusChange, setStatusDisabled, canOperateChange, setCanOperateDisabled, getSortIsDisabled, copy, del, ascHandle, descHandle, formatSearch, computedScore, expand, checkData, } = useTable(proxy, uuidv4); const dialogForm = reactive({ evaluationType: '', evaluationContent: '', evaluationRule: '', evaluationRuleScore: '', calculateStandard: '', operateJson: '', }); const loading = ref(false); const tableLoading = ref(false); const dialogFormRules = reactive({ evaluationType: [{ required: true, trigger: 'blur', message: '评价类型不能为空' }], evaluationContent: [{ required: true, trigger: 'blur', message: '评价内容不能为空' }], evaluationRule: [{ required: true, trigger: 'blur', message: '评价规则不能为空' }], calculateStandard: [{ required: true, trigger: 'blur', message: '评价标准不能为空' }], evaluationRuleScore: [{ required: true, trigger: 'blur', validator: numberValidate }], }); const calculateStandardText = new Map([ ['acc', '累加'], ['reach', '达标'], ['rate', '评级'], ]); const operateMap = new Map([ ['0', { width: '24%', text: '评价类型' }], ['1', { width: '48%', text: '评价内容' }], ['2', { width: '48%', text: '评价规则' }], ]); const openDialog = (row, level, type) => { console.log(row); curRow.value = row; operateInfo.level = level; operateInfo.type = type; operateInfo.text = optTextMap.get(type) + operateMap.get(level).text; operateInfo.width = operateMap.get(level).width; visible.value = true; nextTick(() => { setDialogForm(row, level, type); }); }; const setDialogForm = (row, level, type) => { inheritAttr(row, dialogForm); switch (level) { case '1': dialogForm.evaluationType = row.evaluationType; break; case '2': dialogForm.evaluationType = row.evaluationType; dialogForm.evaluationContent = row.evaluationContent; default: break; } if (type === 'add') { dialogForm.calculateStandard = ''; dialogForm.operateJson = ''; } }; const submit = () => { console.log(operateInfo, dialogForm); proxy.$refs.dialogFormRef.validate(valid => { if (valid) { const treeDataCurRow = getTreeCurRow(treeData.value, curRow.value); const row = { assessTargetConfigId: markId, evaluationType: '', evaluationTypeScore: '', evaluationContent: '', evaluationContentScore: '', evaluationRule: '', evaluationRuleScore: '', calculateStandard: '', canOperate: '0', enableTime: '', stopTime: proxy.moment().format('YYYY-MM-DD HH:mm:ss'), updateBy: useUserStore().name, updateTime: proxy.moment().format('YYYY-MM-DD HH:mm:ss'), status: '0', parentNodeCode: '0', operateJson: '', }; if (operateInfo.type === 'add') { row.nodeCode = uuidv4(); row.level = operateInfo.level; switch (operateInfo.level) { case '0': row.evaluationType = dialogForm.evaluationType; // row.evaluationTypeScore = dialogForm.evaluationTypeScore row.calculateStandard = 'acc'; row.statusDisabled = false; treeData.value.unshift(row); row.sort = treeData.value.length; break; case '1': row.evaluationType = dialogForm.evaluationType; row.evaluationContent = dialogForm.evaluationContent; // row.evaluationContentScore = dialogForm.evaluationContentScore row.calculateStandard = 'acc'; row.parentNodeCode = curRow.value.nodeCode; row.statusDisabled = curRow.value.status === '0'; if (!treeDataCurRow.children) treeDataCurRow.children = []; row.sort = treeDataCurRow.children.length + 1; treeDataCurRow.children.unshift(row); break; case '2': if (dialogForm.calculateStandard === 'rate') { const list = proxy.$refs.rateRef.rateTableData; if (!list?.length) return proxy.$modal.msgError('请至少添加一条评级规则'); const scorelist = list.map(it => it.value * 1); row.evaluationRuleScore = Math.max(...scorelist) + ''; row.operateJson = JSON.stringify(list); } else { row.operateJson = ''; row.evaluationRuleScore = dialogForm.evaluationRuleScore; } row.evaluationType = dialogForm.evaluationType; row.evaluationContent = dialogForm.evaluationContent; row.evaluationRule = dialogForm.evaluationRule; row.calculateStandard = dialogForm.calculateStandard; row.parentNodeCode = curRow.value.nodeCode; row.statusDisabled = curRow.value.status === '0'; if (!treeDataCurRow.children) treeDataCurRow.children = []; row.sort = treeDataCurRow.children.length + 1; treeDataCurRow.children.unshift(row); //计算分值 computedScore(treeDataCurRow.nodeCode); break; default: break; } nextTick(() => { proxy.$refs.tableRef.toggleRowExpansion(treeDataCurRow, true); }); } else if (operateInfo.type === 'edit') { switch (operateInfo.level) { case '0': treeDataCurRow.evaluationType = dialogForm.evaluationType; if (treeDataCurRow?.children?.length) { for (const item of treeDataCurRow.children) { item.evaluationType = treeDataCurRow.evaluationType; if (item?.children?.length) { for (const it of item.children) { it.evaluationType = treeDataCurRow.evaluationType; } } } } // treeDataCurRow.evaluationTypeScore = dialogForm.evaluationTypeScore break; case '1': treeDataCurRow.evaluationContent = dialogForm.evaluationContent; if (treeDataCurRow?.children?.length) { for (const item of treeDataCurRow.children) { item.evaluationContent = treeDataCurRow.evaluationContent; } } // treeDataCurRow.evaluationContentScore = dialogForm.evaluationContentScore break; case '2': if (dialogForm.calculateStandard === 'rate') { const list = proxy.$refs.rateRef.rateTableData; if (!list?.length) return proxy.$modal.msgError('请至少添加一条评级规则'); const scorelist = list.map(it => it.value * 1); treeDataCurRow.evaluationRuleScore = Math.max(...scorelist) + ''; treeDataCurRow.operateJson = JSON.stringify(list); } else { treeDataCurRow.operateJson = ''; treeDataCurRow.evaluationRuleScore = dialogForm.evaluationRuleScore; } treeDataCurRow.evaluationRule = dialogForm.evaluationRule; treeDataCurRow.calculateStandard = dialogForm.calculateStandard; //计算分值 computedScore(treeDataCurRow.parentNodeCode); break; default: break; } } close(); } }); }; const getTableData = async () => { tableLoading.value = true; const res = await getAssessTargetConfigGradeItem(markId); tableLoading.value = false; if (res?.code !== 200) return; treeData.value = res?.data || []; setFields(treeData.value, '0'); setSort(treeData.value); setCanOperateDisabled(treeData.value); setStatusDisabled(treeData.value); nextTick(() => { expand(); }); console.log(treeData.value); }; const setFields = (data, level) => { for (const item of data) { item.level = level; switch (level) { case '0': item.sort = item.evaluationTypeRank; break; case '1': item.sort = item.evaluationContentRank; break; case '2': item.sort = item.evaluationRuleRank; 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 save = async () => { loading.value = true; const params = JSON.parse(JSON.stringify(treeData.value)); const flag = checkData(params); if (flag) return proxy.$modal.msgError('表格数据至少要填写到评价规则'); setParams(params); console.log(params); const res = await assessTargetConfigGradeItemBatchUpdate(params); loading.value = false; if (res?.code !== 200) return; proxy.$modal.msgSuccess('操作成功!'); }; const setParams = data => { for (const item of data) { if (item.level === '0') { item.evaluationTypeRank = item.sort; } else if (item.level === '1') { item.evaluationContentRank = item.sort; } else if (item.level === '2') { item.evaluationRuleRank = item.sort; } if (item.children) { setParams(item.children); } } }; const enable = () => { proxy.$modal .confirm(`是否确认${statusText.value}?`) .then(async () => { let method = status === '1' ? assessTargetConfigClose : assessTargetConfigOpen; const formData = new FormData(); formData.append('id', markId); formData.append('engineeringType', engineeringType); formData.append('assessType', 'score'); const res = await method(formData); if (res?.code !== 200) return; proxy.$modal.msgSuccess('操作成功!'); if (status === '1') { status = '0'; statusText.value = '启用'; } else { status = '1'; statusText.value = '停用'; } }) .catch(() => {}); }; const uploadSuccess = data => { console.log(data); if (data) getTableData(); }; onMounted(() => { getTableData(); }); </script> <style lang="scss" scoped> .mark { padding: 10px; height: 92vh; overflow-y: hidden; .header { padding: 10px; border-radius: 4px; box-shadow: 0px 0px 12px rgba(0, 0, 0, 0.12); border: 1px solid #e4e7ed; margin-bottom: 10px; .title { font-size: 16px; } :deep(.el-page-header__header) { .el-page-header__left { .el-page-header__back { .el-page-header__icon { font-size: 20px; font-weight: 700; } .el-page-header__title { font-size: 16px; } } } } } .body { height: calc(100% - 74px); overflow: auto; overflow-x: hidden; background-color: #fff; border-radius: 4px; box-shadow: 0px 0px 12px rgba(0, 0, 0, 0.12); border: 1px solid #e4e7ed; padding: 20px; :deep(.el-table) { .light { background-color: rgb(252, 247, 0); } } } } :deep(.dialog) { .el-dialog__body { padding-bottom: 20px !important; .el-form { .el-form-item { .el-form-item__label { width: 80px; word-break: keep-all; white-space: nowrap; } } } } .el-dialog__footer { padding-top: 0 !important; } } </style>