feat: 表单敏感字段变更追踪标记

master
LCJ-MinYa 2 weeks ago
parent b806d077f5
commit bd879f18ad

@ -20,13 +20,19 @@
第三阶段:自动化路由配置 (Step 5)
* 操作目标:修改 src/router/modules/{module}.ts。
* 执行逻辑:找到文件中的 titleArr 数组变量,并在末尾追加新页面的配置对象**切记只能追加,不能修改原始代码**
* 强制前置动作:**必须**先使用 `read_file` 读取该路由文件全文,人工确认 `titleArr` 数组的最后一个条目及其精准内容。
* 执行逻辑:
1. 禁止凭借记忆或模糊搜索进行替换。
2. 唯一推荐的 `replace` 策略:找到该数组末尾的 `];` 符号。
3. 将其替换为包含新项的完整结构,并保持严格缩进:
```javascript
{
key: '{pageName}',
title: '{用户定义的中文名称}',
}
{
key: '{pageName}',
title: '{用户定义的中文名称}',
},
];
```
4. **验证义务**:修改后必须立即再次 `read_file` 检查,确保原有的最后一条数据依然完整存在,且新数据已正确追加。
第四阶段:验证与总结
* 编译检查:确保新创建的页面没有语法错误。

@ -182,6 +182,10 @@ const titleArr = [
key: 'ModifyClosureObject',
title: '如何修改闭包对象',
},
{
key: 'formChangeTrack',
title: '表单敏感字段变更追踪标记',
},
];
// @/views/demo/**/*.vue

@ -0,0 +1,207 @@
<template>
<div class="p-5 space-y-5 !bg-gray-100">
<el-card header="表单变更追踪示例 (30个字段监控其中6个)">
<template #header>
<div class="flex items-center justify-between">
<span>表单变更追踪示例 (30个字段监控其中6个)</span>
<el-tag :type="isModifiedFlag ? 'danger' : 'success'">
{{ isModifiedFlag ? "敏感字段已修改" : "未检测到敏感修改" }}
</el-tag>
</div>
</template>
<el-alert
title="说明:下方的 [字段1] 到 [字段6] 是被监控的敏感字段。只要它们被修改,右上角的标记就会变红,直到点击保存。"
type="info"
:closable="false"
class="mb-4"
/>
<el-form :model="formData" label-width="100px" label-position="left">
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
<!-- 敏感字段 1-6 -->
<el-form-item
v-for="i in 6"
:key="'field' + i"
:label="`字段${i}(监控)`"
:class="{ 'is-sensitive': true }"
>
<el-input
v-model="formData['field' + i]"
placeholder="修改此项会触发标记"
/>
</el-form-item>
<!-- 其他字段 7-15 (Input) -->
<el-form-item
v-for="i in 9"
:key="'field' + (i + 6)"
:label="`字段${i + 6}`"
>
<el-input
v-model="formData['field' + (i + 6)]"
placeholder="修改此项不触发标记"
/>
</el-form-item>
<!-- 其他字段 16-20 (Select) -->
<el-form-item
v-for="i in 5"
:key="'field' + (i + 15)"
:label="`字段${i + 15}`"
>
<el-select
v-model="formData['field' + (i + 15)]"
class="w-full"
placeholder="请选择"
>
<el-option label="选项A" value="A" />
<el-option label="选项B" value="B" />
</el-select>
</el-form-item>
<!-- 其他字段 21-25 (Radio) -->
<el-form-item
v-for="i in 5"
:key="'field' + (i + 20)"
:label="`字段${i + 20}`"
>
<el-radio-group v-model="formData['field' + (i + 20)]">
<el-radio label="1">状态1</el-radio>
<el-radio label="2">状态2</el-radio>
</el-radio-group>
</el-form-item>
<!-- 其他字段 26-30 (Switch/Date) -->
<el-form-item
v-for="i in 5"
:key="'field' + (i + 25)"
:label="`字段${i + 25}`"
>
<el-switch
v-if="i % 2 === 0"
v-model="formData['field' + (i + 25)]"
/>
<el-date-picker
v-else
v-model="formData['field' + (i + 25)]"
type="date"
class="!w-full"
placeholder="选择日期"
/>
</el-form-item>
</div>
<div class="mt-8 flex justify-center space-x-4">
<el-button @click="resetForm"></el-button>
<el-button type="primary" @click="handleSave"></el-button>
</div>
</el-form>
</el-card>
<el-card header="当前敏感字段快照与对比">
<div class="grid grid-cols-2 gap-4 text-sm">
<div>
<p class="font-bold mb-2 text-blue-600">上次保存的快照</p>
<pre class="bg-gray-50 p-3 rounded border">{{
JSON.stringify(lastSavedSnapshot, null, 2)
}}</pre>
</div>
<div>
<p class="font-bold mb-2 text-green-600">实时计算属性 (isDirty)</p>
<div class="bg-gray-50 p-3 rounded border h-[135px] flex items-center justify-center">
<span class="text-lg font-mono" :class="isDirty ? 'text-red-500' : 'text-gray-500'">
{{ isDirty ? "TRUE (检测到差异)" : "FALSE (与快照一致)" }}
</span>
</div>
</div>
</div>
</el-card>
</div>
</template>
<script setup lang="ts">
import { ref, reactive, computed, watch, onMounted } from "vue";
import { message } from "@/utils/message";
// 1. 30
const formData = reactive<Record<string, any>>({});
for (let i = 1; i <= 30; i++) {
//
if (i <= 20) formData[`field${i}`] = "";
else if (i <= 25) formData[`field${i}`] = "1";
else if (i % 2 === 0) formData[`field${i}`] = false;
else formData[`field${i}`] = null;
}
// 2. (6)
const SENSITIVE_FIELDS = ["field1", "field2", "field3", "field4", "field5", "field6"];
// 3. ()
const lastSavedSnapshot = ref<Record<string, any>>({});
// 4. true
const isModifiedFlag = ref(false);
//
const updateSnapshot = () => {
const snapshot: Record<string, any> = {};
SENSITIVE_FIELDS.forEach(field => {
snapshot[field] = formData[field];
});
lastSavedSnapshot.value = snapshot;
};
onMounted(() => {
updateSnapshot();
});
// 5. Computed
const isDirty = computed(() => {
return SENSITIVE_FIELDS.some(field => {
return formData[field] !== lastSavedSnapshot.value[field];
});
});
// 6. Watch
// isDirty true isModifiedFlag
// 使isModifiedFlag true ()
//
watch(isDirty, newVal => {
if (newVal) {
isModifiedFlag.value = true;
console.log("检测到敏感字段修改,标记已设为 TRUE");
}
});
/**
* 保存操作
*/
const handleSave = () => {
//
updateSnapshot();
//
isModifiedFlag.value = false;
message("保存成功,标记已重置", { type: "success" });
};
/**
* 重置表单
*/
const resetForm = () => {
SENSITIVE_FIELDS.forEach(field => {
formData[field] = "";
});
// isDirty true watch isModifiedFlag true
//
};
</script>
<style lang="scss" scoped>
.is-sensitive {
:deep(.el-form-item__label) {
color: #f56c6c;
font-weight: bold;
}
}
</style>
Loading…
Cancel
Save