CMVR-IOT-UI/src/views/evaluate/il/touch/secondaryIndicator.vue

294 lines
7.5 KiB
Vue
Raw Normal View History

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>