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" >