2025-11-27 16:14:04 +08:00
|
|
|
<template>
|
|
|
|
|
<div class="container">
|
|
|
|
|
<div class="indicator-container">
|
|
|
|
|
<div class="title-container">
|
|
|
|
|
<div class="title-left">
|
|
|
|
|
<el-tag>二级指标</el-tag>
|
2026-02-03 09:06:58 +08:00
|
|
|
<div class="title">指标名称:<span class="text">{{ props.name }}</span></div>
|
2025-11-27 16:14:04 +08:00
|
|
|
</div>
|
2026-01-30 14:53:55 +08:00
|
|
|
<div>指标权重:{{ props.weight }}%</div>
|
2025-11-27 16:14:04 +08:00
|
|
|
<div>
|
2026-02-03 09:06:58 +08:00
|
|
|
<el-button size="small" :icon="Edit" @click="handleEdit" />
|
|
|
|
|
<el-button size="small" type="danger" :icon="Delete" @click="handleDelete" />
|
2025-11-27 16:14:04 +08:00
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div>
|
2026-02-03 09:06:58 +08:00
|
|
|
<div style="text-align: right; margin: 10px 0px; ">
|
|
|
|
|
<el-button size="small" type="primary" @click="handleAddTab">
|
|
|
|
|
<el-icon><Plus /></el-icon>
|
|
|
|
|
添加三级指标
|
|
|
|
|
</el-button>
|
|
|
|
|
</div>
|
|
|
|
|
<el-tabs v-model="activeTab" closable @tab-remove="removeTab">
|
2025-11-27 16:14:04 +08:00
|
|
|
<el-tab-pane
|
|
|
|
|
v-for="item in tabList"
|
2026-02-03 09:06:58 +08:00
|
|
|
:key="item.id"
|
|
|
|
|
:label="item.name"
|
|
|
|
|
:name="item.id"
|
2025-11-27 16:14:04 +08:00
|
|
|
>
|
2026-02-03 09:06:58 +08:00
|
|
|
<template #label>
|
|
|
|
|
<span>
|
|
|
|
|
<span>{{ item.name }}</span>
|
|
|
|
|
<el-icon :size="12" style="margin-left: 5px; cursor: pointer;" @click="($event) => handleEditTab($event, item)"><Edit /></el-icon>
|
|
|
|
|
</span>
|
|
|
|
|
</template>
|
|
|
|
|
<ScoreTable :title="item.name" :indicatorId="item.id" />
|
2025-11-27 16:14:04 +08:00
|
|
|
</el-tab-pane>
|
|
|
|
|
</el-tabs>
|
|
|
|
|
</div>
|
2026-02-03 09:06:58 +08:00
|
|
|
|
|
|
|
|
<el-dialog v-model="showUpdateDialog" :title="dialogTitle" width="500px">
|
|
|
|
|
<el-form
|
|
|
|
|
ref="formRef"
|
|
|
|
|
:model="metric"
|
|
|
|
|
:rules="rules"
|
|
|
|
|
label-width="100px"
|
|
|
|
|
>
|
|
|
|
|
<el-form-item label="指标名称" prop="name">
|
|
|
|
|
<el-input v-model="metric.name" placeholder="请输入指标名称" />
|
|
|
|
|
</el-form-item>
|
|
|
|
|
<el-form-item v-if="level === 2" label="指标权重" prop="weight">
|
|
|
|
|
<el-input-number v-model="metric.weight" placeholder="请输入指标权重" controls-position="right" />
|
|
|
|
|
</el-form-item>
|
|
|
|
|
</el-form>
|
|
|
|
|
<template #footer>
|
|
|
|
|
<span class="dialog-footer">
|
|
|
|
|
<el-button @click="resetForm">取消</el-button>
|
|
|
|
|
<el-button type="primary" @click="submitMetricForm">确认</el-button>
|
|
|
|
|
</span>
|
|
|
|
|
</template>
|
|
|
|
|
</el-dialog>
|
2025-11-27 16:14:04 +08:00
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</template>
|
|
|
|
|
<script setup>
|
|
|
|
|
import { Delete, Edit } from "@element-plus/icons-vue";
|
|
|
|
|
import ScoreTable from "./components/ScoreTable.vue";
|
2026-02-03 09:06:58 +08:00
|
|
|
import { ElMessageBox, ElMessage } from 'element-plus'
|
|
|
|
|
import { deleteIndicator, updateIndicator, getIndicatorByParentId, addIndicator } from "@/api/evaluate/indicator";
|
|
|
|
|
import { onMounted } from "vue";
|
2026-01-30 14:53:55 +08:00
|
|
|
|
|
|
|
|
const props = defineProps({
|
2026-02-03 09:06:58 +08:00
|
|
|
indicatorId: {
|
|
|
|
|
type: Number,
|
|
|
|
|
default: 0
|
|
|
|
|
},
|
|
|
|
|
name: {
|
2026-01-30 14:53:55 +08:00
|
|
|
type: String,
|
|
|
|
|
default: "无噪声唤醒",
|
|
|
|
|
},
|
|
|
|
|
weight: {
|
|
|
|
|
type: Number,
|
|
|
|
|
default: 30,
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
|
2026-02-03 09:06:58 +08:00
|
|
|
const emit = defineEmits(['refresh'])
|
|
|
|
|
|
2025-11-27 16:14:04 +08:00
|
|
|
const activeTab = ref('1');
|
|
|
|
|
|
2026-02-03 09:06:58 +08:00
|
|
|
const tabList = ref([]);
|
|
|
|
|
|
|
|
|
|
const level = ref(2);
|
|
|
|
|
const isNew = ref(false)
|
|
|
|
|
|
|
|
|
|
const formRef = ref(null);
|
|
|
|
|
const showUpdateDialog = ref(false);
|
|
|
|
|
|
|
|
|
|
const metric = ref({
|
|
|
|
|
name: props.name,
|
|
|
|
|
weight: props.weight,
|
|
|
|
|
id: props.indicatorId
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
const handleEdit = () => {
|
|
|
|
|
level.value = 2;
|
|
|
|
|
isNew.value = false;
|
|
|
|
|
showUpdateDialog.value = true;
|
|
|
|
|
metric.value = {
|
|
|
|
|
name: props.name,
|
|
|
|
|
weight: props.weight,
|
|
|
|
|
id: props.indicatorId
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const dialogTitle = computed(() => {
|
|
|
|
|
return `${isNew.value ? '添加' : '编辑'}${level.value === 2 ? '二级' : '三级'}指标`;
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const resetForm = () => {
|
|
|
|
|
showUpdateDialog.value = false;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const submitMetricForm = () => {
|
|
|
|
|
formRef.value.validate(async (valid) => {
|
|
|
|
|
if (valid) {
|
|
|
|
|
if (!isNew.value) { // 编辑
|
|
|
|
|
const res = await updateIndicator({ id: metric.value.id, name: metric.value.name, weight: metric.value.weight })
|
|
|
|
|
if (res.code === 200) {
|
|
|
|
|
ElMessage.success('指标修改成功')
|
|
|
|
|
resetForm()
|
|
|
|
|
if (level.value === 2) {
|
|
|
|
|
emit('refresh')
|
|
|
|
|
} else {
|
|
|
|
|
getIndicatorByParentIdData(props.indicatorId);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
ElMessage.error(res.message || '指标修改失败')
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
addIndicator({
|
|
|
|
|
name: metric.value.name,
|
|
|
|
|
parentId: props.indicatorId,
|
|
|
|
|
level: level.value,
|
|
|
|
|
weight: metric.value.weight,
|
|
|
|
|
type: 1
|
|
|
|
|
}).then(res => {
|
|
|
|
|
if (res.code === 200) {
|
|
|
|
|
ElMessage.success('指标添加成功')
|
|
|
|
|
getIndicatorByParentIdData(props.indicatorId);
|
|
|
|
|
resetForm()
|
|
|
|
|
} else {
|
|
|
|
|
ElMessage.error(res.message || '指标添加失败')
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
console.log("表单验证失败");
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const handleDelete = () => {
|
|
|
|
|
ElMessageBox.confirm(
|
|
|
|
|
"确定要删除该指标及其所有子指标吗?",
|
|
|
|
|
"删除确认",
|
|
|
|
|
{
|
|
|
|
|
confirmButtonText: "确认",
|
|
|
|
|
cancelButtonText: "取消",
|
|
|
|
|
type: "warning",
|
|
|
|
|
}
|
|
|
|
|
).then(async () => {
|
|
|
|
|
try {
|
|
|
|
|
const res = await deleteIndicator(props.indicatorId);
|
|
|
|
|
if (res.code === 200) {
|
|
|
|
|
ElMessage.success("指标删除成功");
|
|
|
|
|
if (level.value === 2) {
|
|
|
|
|
emit('refresh')
|
|
|
|
|
} else {
|
|
|
|
|
getIndicatorByParentIdData(props.indicatorId);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
ElMessage.error(res.message || "指标删除失败");
|
|
|
|
|
}
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error("删除指标失败:", error);
|
|
|
|
|
ElMessage.error("删除指标失败");
|
|
|
|
|
}
|
|
|
|
|
}).catch(() => {
|
|
|
|
|
// 取消删除
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const handleAddTab = () => {
|
|
|
|
|
level.value = 3;
|
|
|
|
|
isNew.value = true;
|
|
|
|
|
metric.value = {
|
|
|
|
|
name: '',
|
|
|
|
|
weight: 0,
|
|
|
|
|
id: null
|
|
|
|
|
}
|
|
|
|
|
showUpdateDialog.value = true;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const removeTab = (targetName) => {
|
|
|
|
|
console.log("删除了标签:", targetName);
|
|
|
|
|
ElMessageBox.confirm(
|
|
|
|
|
"确定要删除该指标及其所有子指标吗?",
|
|
|
|
|
"删除确认",
|
|
|
|
|
{
|
|
|
|
|
confirmButtonText: "确认",
|
|
|
|
|
cancelButtonText: "取消",
|
|
|
|
|
type: "warning",
|
|
|
|
|
}
|
|
|
|
|
).then(async () => {
|
|
|
|
|
try {
|
|
|
|
|
const res = await deleteIndicator(targetName);
|
|
|
|
|
if (res.code === 200) {
|
|
|
|
|
ElMessage.success("指标删除成功");
|
|
|
|
|
getIndicatorByParentIdData(props.indicatorId);
|
|
|
|
|
} else {
|
|
|
|
|
ElMessage.error(res.message || "指标删除失败");
|
|
|
|
|
}
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error("删除指标失败:", error);
|
|
|
|
|
ElMessage.error("删除指标失败");
|
|
|
|
|
}
|
|
|
|
|
}).catch(() => {
|
|
|
|
|
// 取消删除
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const handleEditTab = (event, item) => {
|
|
|
|
|
event.stopPropagation();
|
|
|
|
|
event.preventDefault();
|
|
|
|
|
level.value = 3;
|
|
|
|
|
isNew.value = false;
|
|
|
|
|
metric.value = {
|
|
|
|
|
name: item.name,
|
|
|
|
|
weight: item.weight,
|
|
|
|
|
id: item.id
|
|
|
|
|
}
|
|
|
|
|
showUpdateDialog.value = true;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const getIndicatorByParentIdData = async (parentId) => {
|
|
|
|
|
try {
|
|
|
|
|
const res = await getIndicatorByParentId(parentId, 1);
|
|
|
|
|
if (res.code === 200) {
|
|
|
|
|
tabList.value = res.data;
|
|
|
|
|
activeTab.value = tabList.value[0]?.id || '1';
|
|
|
|
|
}
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error("获取指标数据失败:", error);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
onMounted(() => {
|
|
|
|
|
getIndicatorByParentIdData(props.indicatorId);
|
|
|
|
|
});
|
2025-11-27 16:14:04 +08:00
|
|
|
</script>
|
|
|
|
|
<style lang="scss" scoped>
|
|
|
|
|
.container {
|
|
|
|
|
margin: 20px 0;
|
|
|
|
|
|
|
|
|
|
.indicator-container {
|
|
|
|
|
border: 1px solid #dbdbdb;
|
|
|
|
|
border-radius: 5px;
|
|
|
|
|
padding: 20px;
|
|
|
|
|
|
|
|
|
|
.title-container {
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
justify-content: space-between;
|
|
|
|
|
|
|
|
|
|
.title-left {
|
|
|
|
|
display: flex;
|
|
|
|
|
gap: 20px;
|
|
|
|
|
|
|
|
|
|
.title {
|
|
|
|
|
margin-left: 8px;
|
|
|
|
|
|
|
|
|
|
.text {
|
|
|
|
|
font-weight: bold;
|
|
|
|
|
margin-left: 8px;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
</style>
|