235 lines
5.8 KiB
Vue
235 lines
5.8 KiB
Vue
<template>
|
||
<div class="param-config-container" v-loading="loading" element-loading-text="加载中...">
|
||
<!-- 模型参数卡片组(垂直堆叠) -->
|
||
<div class="model-cards-container" v-if="!loading && modelGroups.length > 0">
|
||
<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>
|
||
</div>
|
||
|
||
<!-- 空状态 -->
|
||
<div class="empty-state" v-if="!loading && modelGroups.length === 0">
|
||
<el-empty description="暂无参数配置数据"></el-empty>
|
||
</div>
|
||
|
||
<!-- 统一保存按钮 -->
|
||
<div class="button-section" v-if="!loading && modelGroups.length > 0">
|
||
<el-button type="primary" @click="handleSaveAll" :loading="saving">
|
||
保存所有修改
|
||
</el-button>
|
||
<span v-if="modifiedCount > 0" class="modified-tip">
|
||
已修改 {{ modifiedCount }} 个参数
|
||
</span>
|
||
</div>
|
||
</div>
|
||
</template>
|
||
|
||
<script>
|
||
import { listAllParams, saveAllParams } from "@/api/ccdi/modelParam";
|
||
|
||
export default {
|
||
name: 'ParamConfig',
|
||
props: {
|
||
projectId: {
|
||
type: [String, Number],
|
||
required: true
|
||
},
|
||
projectInfo: {
|
||
type: Object,
|
||
default: () => ({})
|
||
}
|
||
},
|
||
data() {
|
||
return {
|
||
// 模型参数数据(按模型分组)
|
||
modelGroups: [],
|
||
// 修改记录(使用对象而非Map,确保Vue能检测变化)
|
||
modifiedParams: {},
|
||
// 加载状态
|
||
loading: false,
|
||
// 保存状态
|
||
saving: false
|
||
}
|
||
},
|
||
computed: {
|
||
/** 计算已修改参数数量 */
|
||
modifiedCount() {
|
||
let count = 0;
|
||
Object.values(this.modifiedParams).forEach(params => {
|
||
count += params.size;
|
||
});
|
||
return count;
|
||
}
|
||
},
|
||
watch: {
|
||
projectId(newVal) {
|
||
if (newVal) {
|
||
this.loadAllParams();
|
||
}
|
||
}
|
||
},
|
||
created() {
|
||
if (this.projectId) {
|
||
this.loadAllParams();
|
||
}
|
||
},
|
||
methods: {
|
||
/** 加载所有模型参数 */
|
||
async loadAllParams() {
|
||
this.loading = true;
|
||
try {
|
||
const res = await listAllParams({ projectId: this.projectId });
|
||
this.modelGroups = res.data.models || [];
|
||
// 清空修改记录
|
||
this.modifiedParams = {};
|
||
} catch (error) {
|
||
this.$message.error('加载参数失败:' + error.message);
|
||
console.error('加载参数失败', error);
|
||
} finally {
|
||
this.loading = false;
|
||
}
|
||
},
|
||
|
||
/** 标记参数为已修改 */
|
||
markAsModified(modelCode, row) {
|
||
// 使用 $set 确保 Vue 能检测到对象属性的新增
|
||
if (!this.modifiedParams[modelCode]) {
|
||
this.$set(this.modifiedParams, modelCode, new Set());
|
||
}
|
||
this.modifiedParams[modelCode].add(row.paramCode);
|
||
|
||
// 强制更新视图
|
||
this.$forceUpdate();
|
||
},
|
||
|
||
/** 保存所有修改 */
|
||
async handleSaveAll() {
|
||
// 验证是否有修改
|
||
if (this.modifiedCount === 0) {
|
||
this.$message.info('没有需要保存的修改');
|
||
return;
|
||
}
|
||
|
||
// 构造保存数据(只包含修改过的参数)
|
||
const saveDTO = {
|
||
projectId: this.projectId,
|
||
models: []
|
||
};
|
||
|
||
Object.entries(this.modifiedParams).forEach(([modelCode, paramCodes]) => {
|
||
const modelGroup = this.modelGroups.find(m => m.modelCode === modelCode);
|
||
if (!modelGroup) return;
|
||
|
||
const modifiedParamList = modelGroup.params
|
||
.filter(p => paramCodes.has(p.paramCode))
|
||
.map(p => ({
|
||
paramCode: p.paramCode,
|
||
paramValue: p.paramValue
|
||
}));
|
||
|
||
if (modifiedParamList.length > 0) {
|
||
saveDTO.models.push({
|
||
modelCode: modelCode,
|
||
params: modifiedParamList
|
||
});
|
||
}
|
||
});
|
||
|
||
// 保存
|
||
this.saving = true;
|
||
try {
|
||
await saveAllParams(saveDTO);
|
||
this.$message.success('保存成功');
|
||
// 清空修改记录并重新加载
|
||
this.modifiedParams = {};
|
||
await this.loadAllParams();
|
||
} catch (error) {
|
||
if (error.response && error.response.data && error.response.data.msg) {
|
||
this.$message.error('保存失败:' + error.response.data.msg);
|
||
} else {
|
||
this.$message.error('保存失败:' + error.message);
|
||
}
|
||
console.error('保存失败', error);
|
||
} finally {
|
||
this.saving = false;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<style scoped lang="scss">
|
||
.param-config-container {
|
||
padding: 20px;
|
||
background-color: #fff;
|
||
min-height: 400px;
|
||
}
|
||
|
||
.model-cards-container {
|
||
margin-bottom: 20px;
|
||
min-height: 300px;
|
||
}
|
||
|
||
.model-card {
|
||
background: #fff;
|
||
border-radius: 4px;
|
||
padding: 20px;
|
||
margin-bottom: 20px;
|
||
border: 1px solid #e4e7ed;
|
||
|
||
.model-header {
|
||
margin-bottom: 15px;
|
||
|
||
h3 {
|
||
font-size: 16px;
|
||
font-weight: bold;
|
||
color: #333;
|
||
margin: 0;
|
||
}
|
||
}
|
||
}
|
||
|
||
.empty-state {
|
||
padding: 40px;
|
||
text-align: center;
|
||
background: #fff;
|
||
border-radius: 4px;
|
||
}
|
||
|
||
.button-section {
|
||
padding: 15px;
|
||
background: #fff;
|
||
border-radius: 4px;
|
||
text-align: left;
|
||
|
||
.modified-tip {
|
||
margin-left: 15px;
|
||
color: #909399;
|
||
font-size: 14px;
|
||
}
|
||
}
|
||
</style>
|