双数据源管理 :
- 使用 originalData_month 和 originalData_min 保存原始数据
- 通过 data_map_min_month_data 和 data_map_min_data 管理当前显示数据
- 实现数据修改前后的对比和回滚功能
当修改的时候进行判断,如果最小值大于最大值,或者最大值小于最小值,就会实时进行回滚并弹窗提示
智能表单状态控制,当点击修改按钮会修改状态,修改按钮改为保存按钮
// 通过isEditing控制编辑状态
const isEditing = ref(false)
function startEdit() {
isEditing.value = true
}
<div style="margin-left: auto; " >
<el-button @click="startEdit" v-if="!isEditing" style="position: absolute; right: 0px; bottom: 1px;" v-hasPermi="['/gateway/protoBufferWeb.ParmByStationInfo/UpdateLimitParams']">修改</el-button>
<el-popconfirm
title="确认保存所有修改吗?"
confirm-button-text="确认"
cancel-button-text="取消"
@confirm="saveChanges"
>
<template #reference>
<el-button type="primary" v-if="isEditing" style="position: absolute; right: 0px; bottom: 1px;" v-hasPermi="['/gateway/protoBufferWeb.ParmByStationInfo/UpdateLimitParams']">保存</el-button>
</template>
</el-popconfirm>
</div>
回滚实现:
- v-number="true" :限制只能输入数字
- v-if 条件:仅在编辑模式、数据存在且值不为-99999时显示
- v-model :双向绑定到当前行的maxValue
- @change :值变化时触发handleValueChange处理函数
- v-else :非编辑模式下显示
- 分别显示最大值和最小值,同样会过滤无效值(-99999)
这样就实现当数值为-99999时是不会显示输入框的
<template #default="scope">
<el-input
v-number="true"
v-if="isEditing && scope.row[index + 1] && scope.row[index + 1].maxValue != -99999"
v-model="scope.row[index + 1].maxValue"
size="small"
@change="(val) => handleValueChange(scope.row, 'max', val, index + 1)"
/>
<el-input
v-number="true"
v-if="isEditing && scope.row[index + 1] && scope.row[index + 1].minValue != -99999"
v-model="scope.row[index + 1].minValue"
size="small"
@change="(val) => handleValueChange(scope.row, 'min', val, index + 1)"
/>
<template v-else>
<div v-if="!isEditing &&scope.row[index + 1].maxValue != -99999">
{{ scope.row[index + 1].maxValue }}
</div>
<div v-if="!isEditing &&scope.row[index + 1].minValue != -99999">
{{ scope.row[index + 1].minValue }}
</div>
</template>
该代码在 Vue 模板中绑定 @change 事件,当值变化时调用 handleValueChange 方法,并传入当前行数据、字段名 'max'、新值和索引 index + 1。
修改时,去判断输入值和原始的最大值和最小值的值,进行校验
如果校验不通过就直接回滚,拿着原始值可以进行回滚
校验通过后进行加一个修改字段,便于下面的提交表单的校验
因为表单很大,内容很多,我们只需要提交修改的值
可以在修改的那一行的数据加一个字段,哪个月被修改了就加一个字段
function handleValueChange(row, type, value, monthIndex) {
// 从data_map_min_month_data中查找原始数据
let originalData = originalData_month.value.find(
item => item.observationType === row.observationType
)
if (!originalData) {
originalData = originalData_min.value.find(
item => item.observationType === row.observationType
)
}
// 获取原始最大值和最小值
const originalMax = originalData[monthIndex]?.maxValue
const originalMin = originalData[monthIndex]?.minValue
if(monthIndex > 0){// 如果是修改最小值,检查是否大于最大值
if(originalMax!=-99999&&type === 'min' && value > originalMax) {
proxy.$modal.msgError("最小值不能大于最大值")
// 还原值
row[monthIndex].minValue = originalMin
return
}
// 如果是修改最大值,检查是否小于最小值
if(type === 'max' && value < originalMin) {
proxy.$modal.msgError("最大值不能小于最小值")
// 还原值
row[monthIndex].maxValue = originalMax
return
}}else{
if(originalMax!=-99999&&type ==='min' && value > originalMax) {
proxy.$modal.msgError("最小值不能大于最大值")
// 还原值
row[0].minValue = originalMin
return
}
// 如果是修改最大值,检查是否小于最小值
if(type ==='max' && value < originalMin) {
proxy.$modal.msgError("最大值不能小于最小值")
// 还原值
row[0].maxValue = originalMax
return
}
}
// 添加修改标记
if (!row.modifiedMonths) {
row.modifiedMonths = {}
}
row.modifiedMonths[monthIndex] = true
modifiedRows.value.add(row)
//判断是修改的是最大值还是最小值,然后更新原始数据为当前值
if(type ==='max'){
originalData[monthIndex].maxValue = value
}else if(type ==='min'){
originalData[monthIndex].minValue = value
}
if(monthIndex === 0){
if(type ==='max'){
originalData.maxValue = value
}
else if(type ==='min'){
originalData.minValue = value
}
}
}
在保存时,传递参数,参数是修改的那一行
遍历修改的行,判断月份有没有修改字段标记,如果有就加到参数里
async function saveChanges() {
try {
loading.value = true
// 准备保存的数据
const params = {
data: []
}
Array.from(modifiedRows.value).forEach(row => {
if(row.observationType) {
for(let i = 1; i <= 12; i++) {
if(row[i] && row.modifiedMonths && row.modifiedMonths[i]) {
params.data.push({
observation_type: row.observationType,
station_num: row.stationNum,
extreme_type: row.extremeType,
month: i,
max_value: row[i].maxValue,
min_value: row[i].minValue
})
}
}
}
if(row[0] && row.modifiedMonths && row.modifiedMonths[0]) {
params.data.push({
observation_type: row.observationType,
station_num: row.stationNum,
extreme_type: row.extremeType,
month: 0,
max_value: row[0].maxValue,
min_value: row[0].minValue
})
}
})
if(params.data.length === 0) {
proxy.$modal.msgWarning("没有检测到数据修改")
isEditing.value = false
}
// 调用保存接口
await proxy.grpcRequest(
"protoBufferWeb.ParmByStationInfo/UpdateLimitParams",
"ParamsUpdateLimitParamsRequest",
params,
null
)
proxy.$modal.msgSuccess("保存成功")
//清空params
params.data = []
// 重置修改标记
// 重置每一行的 modifiedMonths 标记
Array.from(modifiedRows.value).forEach(row => {
if (row.modifiedMonths) {
row.modifiedMonths = {}
}
})
isEditing.value = false
} catch (error) {
console.error(error)
} finally {
loading.value = false
}
}