diff --git a/src/components/CrudFormPanel.vue b/src/components/CrudFormPanel.vue
index 51d487d..efda886 100644
--- a/src/components/CrudFormPanel.vue
+++ b/src/components/CrudFormPanel.vue
@@ -314,6 +314,8 @@ watch(
readonly
/>
+
+
{{ col.tip }}
@@ -323,3 +325,14 @@ watch(
+
+
diff --git a/src/components/CrudTable.vue b/src/components/CrudTable.vue
index a3a739b..971835f 100644
--- a/src/components/CrudTable.vue
+++ b/src/components/CrudTable.vue
@@ -97,6 +97,12 @@ const props = withDefaults(defineProps<{
* (弹窗内再叠抽屉会错位,如应用市场的"应用-职务绑定"弹窗)。
*/
formMode?: 'dialog' | 'drawer'
+ /**
+ * 表单列运行态覆盖(按字段名 → 覆盖部分列属性):
+ * 父页面可按运行态调整某些字段的表单表现,如未解锁时把敏感字段 IdCard 置为
+ * disabled 并加 tip 提示;仅作用于新增/编辑表单,不影响表格单元格渲染。
+ */
+ columnOverrides?: Record>
}>(), {
// editable 必须显式给默认值 true:Vue 会把「未传的 Boolean prop」强制转成 false,
// 不给默认值时 props.editable 恒为 false,canEdit 判定失败 → 所有未传 editable 的
@@ -208,6 +214,17 @@ const formColumns = computed(() => {
.map((c: ColumnSchema) => (isAutoTimestampField(c.field) ? { ...c, required: false } : c))
})
+// 表单列叠加父页面的运行态覆盖(如未解锁时将身份证列禁用并给出提示文案):
+// 放在表单渲染前合并,表格单元格不受影响(列表仍显示后端返回的值/空)
+const effectiveFormColumns = computed(() => {
+ const overrides = props.columnOverrides
+ if (!overrides) return formColumns.value
+ return formColumns.value.map((c) => {
+ const override = overrides[c.field]
+ return override ? { ...c, ...override } : c
+ })
+})
+
// ===== 新增表单自动草稿(独立 composable:useDraftAutosave) =====
// 防止误关闭/误刷新丢失录入内容;按表维度存 localStorage,
// 再次打开"新增"时提示「恢复草稿 / 删除草稿」(空草稿直接丢弃,不打扰);提交成功后清除。
@@ -871,7 +888,7 @@ defineExpose({
:visible="dialogVisible"
:title="dialogTitle"
:submitting="submitting"
- :columns="formColumns"
+ :columns="effectiveFormColumns"
:form-model="editingRow"
:mode="formMode"
@update:visible="(v: boolean) => (dialogVisible = v)"
diff --git a/src/types/api.ts b/src/types/api.ts
index 6a68730..91edb26 100644
--- a/src/types/api.ts
+++ b/src/types/api.ts
@@ -214,6 +214,8 @@ export interface ColumnSchema {
defaultValue?: unknown
/** 占位符 */
placeholder?: string
+ /** 表单控件下方的说明/提示文案(如敏感字段需解锁后才能查看/修改) */
+ tip?: string
// === 数值约束 ===
/** 最小值 */
diff --git a/src/views/ehrm/Profile.vue b/src/views/ehrm/Profile.vue
index 388b4d9..a96f216 100644
--- a/src/views/ehrm/Profile.vue
+++ b/src/views/ehrm/Profile.vue
@@ -15,6 +15,7 @@ import AdminBadge from '@/components/AdminBadge.vue'
import { useUserStore } from '@/stores/user'
import { setPageTitle } from '@/utils/serverScope'
import { ehrmIdCardApi } from '@/api/form'
+import type { ColumnSchema } from '@/types/api'
const userStore = useUserStore()
setPageTitle('档案管理')
@@ -29,6 +30,22 @@ const unlockDialogVisible = ref(false)
const unlockPassword = ref('')
const unlocking = ref(false)
+/**
+ * 未解锁时对新增/编辑表单里身份证列做运行态覆盖:
+ * 禁用输入 + 明确提示「需验证密码才能查看/修改」,其它字段照常可改。
+ * 解锁后返回空覆盖对象,身份证列恢复为普通可编辑文本。
+ */
+const columnOverrides = computed>>(() => {
+ const overrides: Record> = {}
+ if (idCardUnlocked.value) return overrides
+ overrides.IdCard = {
+ disabled: true,
+ placeholder: '需先验证密码才能查看/修改',
+ tip: '身份证号需先点上方「查看身份证」验证密码后才能查看或修改;不验证不影响修改其它字段。',
+ }
+ return overrides
+})
+
/** 查询当前登录用户是否已处于解锁窗口内(页面刷新后恢复按钮状态) */
async function loadIdCardStatus(): Promise {
try {
@@ -80,6 +97,7 @@ onMounted(loadIdCardStatus)
pageable
stretch
:selectable="isAdmin"
+ :columnOverrides="columnOverrides"
>
身份证已解锁