feat: 操作以及指标
This commit is contained in:
parent
a6aa3cc514
commit
ad75493b3e
47
src/api/evaluate/indicator.js
Normal file
47
src/api/evaluate/indicator.js
Normal file
@ -0,0 +1,47 @@
|
||||
import request from "@/utils/request";
|
||||
|
||||
// 查询根据层级指标库
|
||||
export function getIndicatorByParentId(parentId) {
|
||||
return request({
|
||||
url: `/evaluate/indicator/getIndicatorByParentId/${parentId}`,
|
||||
method: "get",
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增指标
|
||||
* @param {*} data
|
||||
* @returns
|
||||
*/
|
||||
export function addIndicator(data) {
|
||||
return request({
|
||||
url: `/evaluate/indicator/indicator/insert`,
|
||||
method: "post",
|
||||
data
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除指标
|
||||
* @param {*} id
|
||||
* @returns
|
||||
*/
|
||||
export function deleteIndicator(id) {
|
||||
return request({
|
||||
url: `/evaluate/indicator/${id}`,
|
||||
method: "delete",
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改指标
|
||||
* @param {*} id
|
||||
* @returns
|
||||
*/
|
||||
export function updateIndicator(data) {
|
||||
return request({
|
||||
url: `/evaluate/indicator`,
|
||||
method: "put",
|
||||
data
|
||||
});
|
||||
}
|
||||
@ -1,6 +1,6 @@
|
||||
<!-- MetricCategory.vue - 一级指标组件 -->
|
||||
<template>
|
||||
<div class="metric-category">
|
||||
<div class="metric-category" @click="activeCategory(category.id)" :class="{ activeCategory: activeId === category.id }">
|
||||
<el-card class="category-card">
|
||||
<div class="card-container">
|
||||
<div class="category-info">
|
||||
@ -19,12 +19,13 @@
|
||||
<MetricForm
|
||||
ref="metricFormRef"
|
||||
:metric="editingCategory"
|
||||
@submit="handleUpdateCategory"
|
||||
:isNew="false"
|
||||
@refresh="handleRefresh"
|
||||
/>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="showEditDialog = false">取消</el-button>
|
||||
<el-button type="primary" @click="submitMetricForm">确认</el-button>
|
||||
<el-button type="primary" @click="submitMetricForm">确认111</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
@ -40,10 +41,15 @@ const props = defineProps({
|
||||
category: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
// 新增props:接收父组件的全局激活ID(支持字符串/数字/空值)
|
||||
activeId: {
|
||||
type: [String, Number],
|
||||
default: ''
|
||||
}
|
||||
})
|
||||
|
||||
const emit = defineEmits(['update-category', 'add-submetric', 'remove-category'])
|
||||
const emit = defineEmits(['update-category', 'remove-category', 'active'])
|
||||
|
||||
const showEditDialog = ref(false)
|
||||
const metricFormRef = ref(null)
|
||||
@ -65,17 +71,22 @@ const submitMetricForm = () => {
|
||||
}
|
||||
}
|
||||
|
||||
const handleUpdateCategory = (metricData) => {
|
||||
emit('update-category', {
|
||||
...props.category,
|
||||
...metricData
|
||||
})
|
||||
const handleRefresh = () => {
|
||||
emit('refresh')
|
||||
showEditDialog.value = false
|
||||
}
|
||||
|
||||
const activeCategory = (categoryId) => {
|
||||
// 可以在这里处理点击一级指标卡片时的逻辑
|
||||
console.log("点击了一级指标:", categoryId);
|
||||
emit('active', categoryId) // 通知父组件更新全局激活ID
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.metric-category {
|
||||
cursor: pointer;
|
||||
|
||||
.category-card {
|
||||
border-radius: 8px;
|
||||
|
||||
@ -98,4 +109,9 @@ const handleUpdateCategory = (metricData) => {
|
||||
}
|
||||
}
|
||||
|
||||
.activeCategory {
|
||||
border: 2px solid #409EFF;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
</style>
|
||||
@ -15,15 +15,21 @@
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive } from 'vue'
|
||||
import { addIndicator, updateIndicator } from '@/api/evaluate/indicator'
|
||||
import { ElMessage } from 'element-plus'
|
||||
|
||||
const props = defineProps({
|
||||
metric: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
isNew: {
|
||||
type: Boolean,
|
||||
required: true
|
||||
}
|
||||
})
|
||||
|
||||
const emit = defineEmits(['submit'])
|
||||
const emit = defineEmits(['refresh'])
|
||||
|
||||
const formRef = ref(null)
|
||||
|
||||
@ -35,10 +41,25 @@ const rules = reactive({
|
||||
|
||||
const submitForm = () => {
|
||||
if (!formRef.value) return
|
||||
|
||||
formRef.value.validate((valid) => {
|
||||
formRef.value.validate(async (valid) => {
|
||||
if (valid) {
|
||||
emit('submit', { ...props.metric })
|
||||
if (props.isNew) {
|
||||
const res = await addIndicator({ name: props.metric.name, parentId: 0, level: 1 })
|
||||
if (res.code === 200) {
|
||||
ElMessage.success('指标添加成功')
|
||||
emit('refresh')
|
||||
} else {
|
||||
ElMessage.error(res.message || '指标添加失败')
|
||||
}
|
||||
} else {
|
||||
const res = await updateIndicator({ id: props.metric.id, name: props.metric.name })
|
||||
if (res.code === 200) {
|
||||
ElMessage.success('指标修改成功')
|
||||
emit('refresh')
|
||||
} else {
|
||||
ElMessage.error(res.message || '指标修改失败')
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div class="evaluation-metrics">
|
||||
<div class="left">
|
||||
<Indicator />
|
||||
<Indicator @activeMetricCategory="handleActiveMetricCategory" />
|
||||
</div>
|
||||
<div class="right">
|
||||
<div class="title">
|
||||
@ -11,8 +11,8 @@
|
||||
添加二级指标
|
||||
</el-button>
|
||||
</div>
|
||||
<div class="secondaryIndicator-container">
|
||||
<SecondaryIndicator v-for="value in 3" />
|
||||
<div class="secondaryIndicator-container" v-if="listData.length > 0">
|
||||
<SecondaryIndicator v-for="value in listData" :key="value.id" :title="value.title" :weight="value.weight" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -21,7 +21,35 @@
|
||||
<script setup>
|
||||
import Indicator from './indicator.vue';
|
||||
import SecondaryIndicator from './secondaryIndicator.vue';
|
||||
import { getIndicatorByParentId } from "@/api/evaluate/indicator";
|
||||
|
||||
const activeIndicatorId = ref(null);
|
||||
|
||||
const listData = ref([])
|
||||
/**
|
||||
*
|
||||
{ id: 1, title: '无噪声唤醒', weight: 30 },
|
||||
{ id: 2, title: '有噪声唤醒', weight: 40 },
|
||||
{ id: 3, title: '免唤醒', weight: 50 },
|
||||
{ id: 4, title: '误唤醒', weight: 30 }
|
||||
|
||||
*/
|
||||
|
||||
const handleActiveMetricCategory = (data) => {
|
||||
activeIndicatorId.value = data;
|
||||
getIndicatorByParentIdData(data);
|
||||
};
|
||||
|
||||
const getIndicatorByParentIdData = async (parentId) => {
|
||||
try {
|
||||
const res = await getIndicatorByParentId(parentId);
|
||||
if (res.code === 200) {
|
||||
listData.value = res.data;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("获取指标数据失败:", error);
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
@ -15,14 +15,15 @@
|
||||
v-for="category in metricCategories"
|
||||
:key="category.id"
|
||||
:category="category"
|
||||
@update-category="updateCategory"
|
||||
@add-submetric="addSubmetric"
|
||||
:active-id="activeCategoryId"
|
||||
@active="activeCategory"
|
||||
@refresh="handleRefresh"
|
||||
@remove-category="removeCategory"
|
||||
/>
|
||||
</div>
|
||||
<!-- 添加一级指标对话框 -->
|
||||
<el-dialog v-model="showAddDialog" title="添加一级指标" width="500px">
|
||||
<MetricForm ref="metricFormRef" :metric="newMetric" @submit="handleAddCategory" />
|
||||
<MetricForm ref="metricFormRef" :isNew="true" :metric="newMetric" @refresh="handleRefresh" />
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="showAddDialog = false">取消</el-button>
|
||||
@ -36,90 +37,54 @@
|
||||
import { Plus } from "@element-plus/icons-vue";
|
||||
import MetricCategory from "./components/MetricCategory.vue";
|
||||
import MetricForm from "./components/MetricForm.vue";
|
||||
import { getIndicatorByParentId, deleteIndicator } from "@/api/evaluate/indicator";
|
||||
import { ElMessage, ElMessageBox } from "element-plus";
|
||||
|
||||
const emit = defineEmits(['activeMetricCategory'])
|
||||
|
||||
// 模拟数据
|
||||
const metricCategories = ref([
|
||||
{
|
||||
id: 1,
|
||||
name: "语音唤醒",
|
||||
weight: 30,
|
||||
subMetrics: [
|
||||
{
|
||||
id: 11,
|
||||
name: "指挥名称:无噪声唤醒",
|
||||
weight: 30,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: "语音识别",
|
||||
weight: 20,
|
||||
subMetrics: [],
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
name: "智能交互",
|
||||
weight: 20,
|
||||
subMetrics: [],
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
name: "数据分析",
|
||||
weight: 10,
|
||||
subMetrics: [],
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
name: "能智能力",
|
||||
weight: 50,
|
||||
subMetrics: [
|
||||
{
|
||||
id: 51,
|
||||
name: "情绪分析:免唤醒",
|
||||
weight: 50,
|
||||
},
|
||||
],
|
||||
},
|
||||
]);
|
||||
const metricCategories = ref([]);
|
||||
|
||||
const activeCategoryId = ref('')
|
||||
|
||||
const handleAddMetric = () => {
|
||||
newMetric.name = "";
|
||||
newMetric.weight = 0;
|
||||
newMetric.subMetrics = [];
|
||||
showAddDialog.value = true;
|
||||
};
|
||||
|
||||
const updateCategory = (updatedCategory) => {
|
||||
const index = metricCategories.value.findIndex((cat) => cat.id === updatedCategory.id);
|
||||
if (index !== -1) {
|
||||
metricCategories.value[index] = updatedCategory;
|
||||
}
|
||||
};
|
||||
|
||||
const addSubmetric = (categoryId, submetric) => {
|
||||
const category = metricCategories.value.find((cat) => cat.id === categoryId);
|
||||
if (category) {
|
||||
category.subMetrics.push({
|
||||
id: Date.now(),
|
||||
...submetric,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const removeCategory = (categoryId) => {
|
||||
const index = metricCategories.value.findIndex((cat) => cat.id === categoryId);
|
||||
if (index !== -1) {
|
||||
metricCategories.value.splice(index, 1);
|
||||
console.log("-----------",categoryId)
|
||||
ElMessageBox.confirm(
|
||||
"确定要删除该指标及其所有子指标吗?",
|
||||
"删除确认",
|
||||
{
|
||||
confirmButtonText: "确认",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning",
|
||||
}
|
||||
).then(async () => {
|
||||
try {
|
||||
const res = await deleteIndicator(categoryId);
|
||||
if (res.code === 200) {
|
||||
ElMessage.success("指标删除成功");
|
||||
getIndicatorByParentIdData(0);
|
||||
} else {
|
||||
ElMessage.error(res.message || "指标删除失败");
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("删除指标失败:", error);
|
||||
ElMessage.error("删除指标失败");
|
||||
}
|
||||
}).catch(() => {
|
||||
// 取消删除
|
||||
});
|
||||
};
|
||||
|
||||
const showAddDialog = ref(false);
|
||||
const metricFormRef = ref(null);
|
||||
const newMetric = reactive({
|
||||
name: "",
|
||||
weight: 0,
|
||||
subMetrics: [],
|
||||
name: ""
|
||||
});
|
||||
|
||||
const submitMetricForm = () => {
|
||||
@ -128,14 +93,32 @@ const submitMetricForm = () => {
|
||||
}
|
||||
};
|
||||
|
||||
const handleAddCategory = (metricData) => {
|
||||
const newCategory = {
|
||||
id: Date.now(),
|
||||
...metricData,
|
||||
};
|
||||
metricCategories.value.push(newCategory);
|
||||
const handleRefresh = () => {
|
||||
getIndicatorByParentIdData(0);
|
||||
showAddDialog.value = false;
|
||||
};
|
||||
|
||||
const getIndicatorByParentIdData = async (parentId) => {
|
||||
try {
|
||||
const res = await getIndicatorByParentId(parentId);
|
||||
if (res.code === 200) {
|
||||
metricCategories.value = res.data;
|
||||
emit('activeMetricCategory', res.data[0]?.id || null)
|
||||
activeCategoryId.value = res.data[0]?.id || null;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("获取指标数据失败:", error);
|
||||
}
|
||||
};
|
||||
|
||||
const activeCategory = (data) => {
|
||||
activeCategoryId.value = data;
|
||||
emit('activeMetricCategory', data); // 通知父组件
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
getIndicatorByParentIdData(0); // 获取一级指标数据
|
||||
});
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.container {
|
||||
|
||||
@ -4,9 +4,9 @@
|
||||
<div class="title-container">
|
||||
<div class="title-left">
|
||||
<el-tag>二级指标</el-tag>
|
||||
<div class="title">指标名称:<span class="text">无噪声唤醒</span></div>
|
||||
<div class="title">指标名称:<span class="text">{{ props.title }}</span></div>
|
||||
</div>
|
||||
<div>指标权重:30.00%</div>
|
||||
<div>指标权重:{{ props.weight }}%</div>
|
||||
<div>
|
||||
<el-button size="small" :icon="Edit" />
|
||||
<el-button size="small" type="danger" :icon="Delete" />
|
||||
@ -31,6 +31,18 @@
|
||||
<script setup>
|
||||
import { Delete, Edit } from "@element-plus/icons-vue";
|
||||
import ScoreTable from "./components/ScoreTable.vue";
|
||||
|
||||
const props = defineProps({
|
||||
title: {
|
||||
type: String,
|
||||
default: "无噪声唤醒",
|
||||
},
|
||||
weight: {
|
||||
type: Number,
|
||||
default: 30,
|
||||
},
|
||||
});
|
||||
|
||||
const activeTab = ref('1');
|
||||
|
||||
const tabList = ref([
|
||||
|
||||
@ -12,7 +12,7 @@
|
||||
</el-button>
|
||||
</div>
|
||||
<div class="secondaryIndicator-container">
|
||||
<SecondaryIndicator v-for="value in 3" />
|
||||
<SecondaryIndicator v-for="value in listData" :key="value.id" :title="value.title" :weight="value.weight" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -22,6 +22,13 @@
|
||||
import Indicator from './indicator.vue';
|
||||
import SecondaryIndicator from './secondaryIndicator.vue';
|
||||
|
||||
const listData = ref([
|
||||
{ id: 1, title: '无噪声唤醒', weight: 30 },
|
||||
{ id: 2, title: '有噪声唤醒', weight: 40 },
|
||||
{ id: 3, title: '免唤醒', weight: 50 },
|
||||
{ id: 4, title: '误唤醒', weight: 30 }
|
||||
])
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
@ -62,25 +62,7 @@ const metricCategories = ref([
|
||||
name: "智能交互",
|
||||
weight: 20,
|
||||
subMetrics: [],
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
name: "数据分析",
|
||||
weight: 10,
|
||||
subMetrics: [],
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
name: "能智能力",
|
||||
weight: 50,
|
||||
subMetrics: [
|
||||
{
|
||||
id: 51,
|
||||
name: "情绪分析:免唤醒",
|
||||
weight: 50,
|
||||
},
|
||||
],
|
||||
},
|
||||
}
|
||||
]);
|
||||
|
||||
const handleAddMetric = () => {
|
||||
|
||||
@ -4,9 +4,9 @@
|
||||
<div class="title-container">
|
||||
<div class="title-left">
|
||||
<el-tag>二级指标</el-tag>
|
||||
<div class="title">指标名称:<span class="text">无噪声唤醒</span></div>
|
||||
<div class="title">指标名称:<span class="text">{{ props.title }}</span></div>
|
||||
</div>
|
||||
<div>指标权重:30.00%</div>
|
||||
<div>指标权重:{{ props.weight }}%</div>
|
||||
<div>
|
||||
<el-button size="small" :icon="Edit" />
|
||||
<el-button size="small" type="danger" :icon="Delete" />
|
||||
@ -31,6 +31,18 @@
|
||||
<script setup>
|
||||
import { Delete, Edit } from "@element-plus/icons-vue";
|
||||
import ScoreTable from "./components/ScoreTable.vue";
|
||||
|
||||
const props = defineProps({
|
||||
title: {
|
||||
type: String,
|
||||
default: "无噪声唤醒",
|
||||
},
|
||||
weight: {
|
||||
type: Number,
|
||||
default: 30,
|
||||
},
|
||||
});
|
||||
|
||||
const activeTab = ref('1');
|
||||
|
||||
const tabList = ref([
|
||||
|
||||
@ -285,7 +285,7 @@ export const collapseList = [
|
||||
action: 'MICROPHONE_START',
|
||||
nodeType: 'EDGE',
|
||||
nodeParams: [
|
||||
{ name: "deviceId", type: "input", input: "", componentType: 'select', selectOptions: deviceOptions(), disabled: true }
|
||||
{ name: "deviceId", type: "input", input: "", componentType: 'select', selectOptions: audioOptions(), disabled: true }
|
||||
],
|
||||
outputType: 'json'
|
||||
},
|
||||
@ -297,7 +297,7 @@ export const collapseList = [
|
||||
action: 'MICROPHONE_START',
|
||||
nodeType: 'EDGE',
|
||||
nodeParams: [
|
||||
{ name: "deviceId", type: "input", input: "", componentType: 'select', selectOptions: deviceOptions(), disabled: true }
|
||||
{ name: "deviceId", type: "input", input: "", componentType: 'select', selectOptions: audioOptions(), disabled: true }
|
||||
],
|
||||
outputType: 'json'
|
||||
},
|
||||
|
||||
@ -36,7 +36,7 @@ export default defineConfig(({mode, command}) => {
|
||||
//赵 http://10.148.108.58:13080
|
||||
// dev http://10.148.20.34:13080
|
||||
// target: VITE_API_URL,
|
||||
target: command === 'build' ? VITE_API_URL : 'http://192.168.0.10:13080',
|
||||
target: command === 'build' ? VITE_API_URL : 'http://192.168.0.21:13081',
|
||||
changeOrigin: true,
|
||||
rewrite: (p) => p.replace(/^\/dev-api/, '')
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user