2026-03-04 10:31:15 +08:00
|
|
|
|
<template>
|
2026-03-09 09:21:51 +08:00
|
|
|
|
<div class="param-config-container" v-loading="loading" element-loading-text="加载中...">
|
2026-03-09 09:08:27 +08:00
|
|
|
|
<!-- 模型参数卡片组(垂直堆叠) -->
|
2026-03-09 09:21:51 +08:00
|
|
|
|
<div class="model-cards-container" v-if="!loading && modelGroups.length > 0">
|
2026-03-09 09:08:27 +08:00
|
|
|
|
<div
|
|
|
|
|
|
v-for="model in modelGroups"
|
|
|
|
|
|
:key="model.modelCode"
|
|
|
|
|
|
class="model-card"
|
|
|
|
|
|
>
|
|
|
|
|
|
<!-- 模型标题 -->
|
|
|
|
|
|
<div class="model-header">
|
|
|
|
|
|
<h3>{{ model.modelName }}</h3>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- 参数表格 -->
|
|
|
|
|
|
<el-table :data="model.params" border style="width: 100%">
|
|
|
|
|
|
<el-table-column label="监测项" prop="paramName" width="200" />
|
|
|
|
|
|
<el-table-column label="描述" prop="paramDesc" />
|
|
|
|
|
|
<el-table-column label="阈值设置" width="200">
|
|
|
|
|
|
<template #default="{ row }">
|
|
|
|
|
|
<el-input
|
|
|
|
|
|
v-model="row.paramValue"
|
|
|
|
|
|
placeholder="请输入阈值"
|
|
|
|
|
|
@input="markAsModified(model.modelCode, row)"
|
|
|
|
|
|
/>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
</el-table-column>
|
|
|
|
|
|
<el-table-column label="单位" prop="paramUnit" width="120" />
|
|
|
|
|
|
</el-table>
|
|
|
|
|
|
</div>
|
2026-03-06 15:26:39 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
|
2026-03-09 09:21:51 +08:00
|
|
|
|
<!-- 空状态 -->
|
|
|
|
|
|
<div class="empty-state" v-if="!loading && modelGroups.length === 0">
|
|
|
|
|
|
<el-empty description="暂无参数配置数据"></el-empty>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
2026-03-09 09:08:27 +08:00
|
|
|
|
<!-- 统一保存按钮 -->
|
2026-03-09 09:21:51 +08:00
|
|
|
|
<div class="button-section" v-if="!loading && modelGroups.length > 0">
|
2026-03-09 09:08:27 +08:00
|
|
|
|
<el-button type="primary" @click="handleSaveAll" :loading="saving">
|
|
|
|
|
|
保存所有修改
|
2026-03-06 15:26:39 +08:00
|
|
|
|
</el-button>
|
2026-03-09 09:08:27 +08:00
|
|
|
|
<span v-if="modifiedCount > 0" class="modified-tip">
|
|
|
|
|
|
已修改 {{ modifiedCount }} 个参数
|
|
|
|
|
|
</span>
|
2026-03-04 10:31:15 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
|
|
<script>
|
2026-03-09 09:08:27 +08:00
|
|
|
|
import { listAllParams, saveAllParams } from "@/api/ccdi/modelParam";
|
2026-03-06 15:26:39 +08:00
|
|
|
|
|
2026-03-04 10:31:15 +08:00
|
|
|
|
export default {
|
2026-03-06 15:26:39 +08:00
|
|
|
|
name: 'ParamConfig',
|
2026-03-04 10:31:15 +08:00
|
|
|
|
props: {
|
|
|
|
|
|
projectId: {
|
|
|
|
|
|
type: [String, Number],
|
2026-03-06 15:26:39 +08:00
|
|
|
|
required: true
|
2026-03-04 10:31:15 +08:00
|
|
|
|
},
|
|
|
|
|
|
projectInfo: {
|
|
|
|
|
|
type: Object,
|
2026-03-06 15:26:39 +08:00
|
|
|
|
default: () => ({})
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
data() {
|
|
|
|
|
|
return {
|
2026-03-09 09:08:27 +08:00
|
|
|
|
modelGroups: [],
|
2026-03-09 09:17:26 +08:00
|
|
|
|
modifiedParams: {},
|
2026-03-16 13:42:21 +08:00
|
|
|
|
originalParamValues: {},
|
2026-03-09 09:21:51 +08:00
|
|
|
|
loading: false,
|
2026-03-06 15:26:39 +08:00
|
|
|
|
saving: false
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
2026-03-09 09:08:27 +08:00
|
|
|
|
computed: {
|
|
|
|
|
|
modifiedCount() {
|
2026-03-16 13:42:21 +08:00
|
|
|
|
return Object.keys(this.modifiedParams).length;
|
2026-03-09 09:08:27 +08:00
|
|
|
|
}
|
|
|
|
|
|
},
|
2026-03-06 15:26:39 +08:00
|
|
|
|
watch: {
|
|
|
|
|
|
projectId(newVal) {
|
2026-03-09 09:08:27 +08:00
|
|
|
|
if (newVal) {
|
|
|
|
|
|
this.loadAllParams();
|
2026-03-16 13:42:21 +08:00
|
|
|
|
} else {
|
|
|
|
|
|
this.modelGroups = [];
|
|
|
|
|
|
this.modifiedParams = {};
|
|
|
|
|
|
this.originalParamValues = {};
|
2026-03-09 09:08:27 +08:00
|
|
|
|
}
|
2026-03-06 15:26:39 +08:00
|
|
|
|
}
|
2026-03-04 10:31:15 +08:00
|
|
|
|
},
|
2026-03-06 15:26:39 +08:00
|
|
|
|
created() {
|
2026-03-09 09:08:27 +08:00
|
|
|
|
if (this.projectId) {
|
|
|
|
|
|
this.loadAllParams();
|
|
|
|
|
|
}
|
2026-03-06 15:26:39 +08:00
|
|
|
|
},
|
|
|
|
|
|
methods: {
|
2026-03-16 13:42:21 +08:00
|
|
|
|
buildModifiedKey(modelCode, paramCode) {
|
|
|
|
|
|
return `${modelCode}:${paramCode}`
|
|
|
|
|
|
},
|
|
|
|
|
|
normalizeParamValue(value) {
|
|
|
|
|
|
return value === null || value === undefined ? '' : String(value)
|
|
|
|
|
|
},
|
|
|
|
|
|
normalizeModelGroups(models) {
|
|
|
|
|
|
if (!Array.isArray(models)) {
|
|
|
|
|
|
return []
|
|
|
|
|
|
}
|
|
|
|
|
|
return models.map(model => ({
|
|
|
|
|
|
...model,
|
|
|
|
|
|
params: Array.isArray(model.params) ? model.params : []
|
|
|
|
|
|
}))
|
|
|
|
|
|
},
|
|
|
|
|
|
resetModifiedState() {
|
|
|
|
|
|
this.modifiedParams = {}
|
|
|
|
|
|
this.originalParamValues = {}
|
|
|
|
|
|
this.modelGroups.forEach(model => {
|
|
|
|
|
|
model.params.forEach(row => {
|
|
|
|
|
|
const key = this.buildModifiedKey(model.modelCode, row.paramCode)
|
|
|
|
|
|
this.$set(this.originalParamValues, key, this.normalizeParamValue(row.paramValue))
|
|
|
|
|
|
})
|
|
|
|
|
|
})
|
|
|
|
|
|
},
|
2026-03-09 09:08:27 +08:00
|
|
|
|
async loadAllParams() {
|
2026-03-09 09:21:51 +08:00
|
|
|
|
this.loading = true;
|
2026-03-06 15:26:39 +08:00
|
|
|
|
try {
|
2026-03-09 09:08:27 +08:00
|
|
|
|
const res = await listAllParams({ projectId: this.projectId });
|
2026-03-16 13:42:21 +08:00
|
|
|
|
this.modelGroups = this.normalizeModelGroups(res.data && res.data.models);
|
|
|
|
|
|
this.resetModifiedState();
|
2026-03-06 15:26:39 +08:00
|
|
|
|
} catch (error) {
|
2026-03-09 09:08:27 +08:00
|
|
|
|
this.$message.error('加载参数失败:' + error.message);
|
|
|
|
|
|
console.error('加载参数失败', error);
|
2026-03-09 09:21:51 +08:00
|
|
|
|
} finally {
|
|
|
|
|
|
this.loading = false;
|
2026-03-06 15:26:39 +08:00
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
|
2026-03-09 09:08:27 +08:00
|
|
|
|
markAsModified(modelCode, row) {
|
2026-03-16 13:42:21 +08:00
|
|
|
|
const modifiedKey = this.buildModifiedKey(modelCode, row.paramCode);
|
|
|
|
|
|
const currentValue = this.normalizeParamValue(row.paramValue);
|
|
|
|
|
|
const originalValue = this.originalParamValues[modifiedKey];
|
2026-03-09 09:17:26 +08:00
|
|
|
|
|
2026-03-16 13:42:21 +08:00
|
|
|
|
if (currentValue === originalValue) {
|
|
|
|
|
|
if (this.modifiedParams[modifiedKey]) {
|
|
|
|
|
|
this.$delete(this.modifiedParams, modifiedKey);
|
|
|
|
|
|
}
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
this.$set(this.modifiedParams, modifiedKey, {
|
|
|
|
|
|
modelCode,
|
|
|
|
|
|
paramCode: row.paramCode,
|
|
|
|
|
|
paramValue: row.paramValue
|
|
|
|
|
|
});
|
2026-03-06 15:26:39 +08:00
|
|
|
|
},
|
|
|
|
|
|
|
2026-03-09 09:08:27 +08:00
|
|
|
|
async handleSaveAll() {
|
|
|
|
|
|
if (this.modifiedCount === 0) {
|
|
|
|
|
|
this.$message.info('没有需要保存的修改');
|
|
|
|
|
|
return;
|
2026-03-06 15:26:39 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-03-16 13:42:21 +08:00
|
|
|
|
const modelMap = {};
|
|
|
|
|
|
Object.values(this.modifiedParams).forEach(item => {
|
|
|
|
|
|
if (!modelMap[item.modelCode]) {
|
|
|
|
|
|
modelMap[item.modelCode] = {
|
|
|
|
|
|
modelCode: item.modelCode,
|
|
|
|
|
|
params: []
|
|
|
|
|
|
};
|
|
|
|
|
|
}
|
|
|
|
|
|
modelMap[item.modelCode].params.push({
|
|
|
|
|
|
paramCode: item.paramCode,
|
|
|
|
|
|
paramValue: item.paramValue
|
|
|
|
|
|
});
|
|
|
|
|
|
});
|
2026-03-06 15:26:39 +08:00
|
|
|
|
const saveDTO = {
|
|
|
|
|
|
projectId: this.projectId,
|
2026-03-16 13:42:21 +08:00
|
|
|
|
models: Object.values(modelMap)
|
2026-03-09 09:08:27 +08:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
this.saving = true;
|
2026-03-06 15:26:39 +08:00
|
|
|
|
try {
|
2026-03-09 09:08:27 +08:00
|
|
|
|
await saveAllParams(saveDTO);
|
2026-03-16 13:42:21 +08:00
|
|
|
|
this.$modal.msgSuccess('保存成功');
|
2026-03-09 09:08:27 +08:00
|
|
|
|
await this.loadAllParams();
|
2026-03-06 15:26:39 +08:00
|
|
|
|
} catch (error) {
|
|
|
|
|
|
if (error.response && error.response.data && error.response.data.msg) {
|
2026-03-09 09:08:27 +08:00
|
|
|
|
this.$message.error('保存失败:' + error.response.data.msg);
|
2026-03-06 15:26:39 +08:00
|
|
|
|
} else {
|
2026-03-09 09:08:27 +08:00
|
|
|
|
this.$message.error('保存失败:' + error.message);
|
2026-03-06 15:26:39 +08:00
|
|
|
|
}
|
2026-03-09 09:08:27 +08:00
|
|
|
|
console.error('保存失败', error);
|
2026-03-06 15:26:39 +08:00
|
|
|
|
} finally {
|
2026-03-09 09:08:27 +08:00
|
|
|
|
this.saving = false;
|
2026-03-06 15:26:39 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2026-03-04 10:31:15 +08:00
|
|
|
|
</script>
|
|
|
|
|
|
|
2026-03-06 15:26:39 +08:00
|
|
|
|
<style scoped lang="scss">
|
2026-03-04 10:31:15 +08:00
|
|
|
|
.param-config-container {
|
2026-03-06 15:26:39 +08:00
|
|
|
|
padding: 20px;
|
|
|
|
|
|
background-color: #fff;
|
2026-03-04 10:31:15 +08:00
|
|
|
|
min-height: 400px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-03-09 09:08:27 +08:00
|
|
|
|
.model-cards-container {
|
2026-03-06 15:26:39 +08:00
|
|
|
|
margin-bottom: 20px;
|
2026-03-09 09:21:51 +08:00
|
|
|
|
min-height: 300px;
|
2026-03-06 15:26:39 +08:00
|
|
|
|
}
|
2026-03-04 10:31:15 +08:00
|
|
|
|
|
2026-03-09 09:08:27 +08:00
|
|
|
|
.model-card {
|
2026-03-06 15:26:39 +08:00
|
|
|
|
background: #fff;
|
|
|
|
|
|
border-radius: 4px;
|
2026-03-09 09:08:27 +08:00
|
|
|
|
padding: 20px;
|
2026-03-06 15:26:39 +08:00
|
|
|
|
margin-bottom: 20px;
|
2026-03-09 09:08:27 +08:00
|
|
|
|
border: 1px solid #e4e7ed;
|
|
|
|
|
|
|
|
|
|
|
|
.model-header {
|
|
|
|
|
|
margin-bottom: 15px;
|
2026-03-04 10:31:15 +08:00
|
|
|
|
|
2026-03-09 09:08:27 +08:00
|
|
|
|
h3 {
|
|
|
|
|
|
font-size: 16px;
|
|
|
|
|
|
font-weight: bold;
|
|
|
|
|
|
color: #333;
|
|
|
|
|
|
margin: 0;
|
|
|
|
|
|
}
|
2026-03-04 10:31:15 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2026-03-06 15:26:39 +08:00
|
|
|
|
|
2026-03-09 09:21:51 +08:00
|
|
|
|
.empty-state {
|
|
|
|
|
|
padding: 40px;
|
|
|
|
|
|
text-align: center;
|
|
|
|
|
|
background: #fff;
|
|
|
|
|
|
border-radius: 4px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-03-06 15:26:39 +08:00
|
|
|
|
.button-section {
|
|
|
|
|
|
padding: 15px;
|
|
|
|
|
|
background: #fff;
|
|
|
|
|
|
border-radius: 4px;
|
|
|
|
|
|
text-align: left;
|
2026-03-09 09:08:27 +08:00
|
|
|
|
|
|
|
|
|
|
.modified-tip {
|
|
|
|
|
|
margin-left: 15px;
|
|
|
|
|
|
color: #909399;
|
|
|
|
|
|
font-size: 14px;
|
|
|
|
|
|
}
|
2026-03-06 15:26:39 +08:00
|
|
|
|
}
|
2026-03-04 10:31:15 +08:00
|
|
|
|
</style>
|