feat(gerp): 档案页身份证号二次密码解锁查看
- 档案管理页新增「查看身份证」按钮:输入当前登录账号密码解锁 - 解锁成功后刷新列表,10 分钟内切换他人档案同样可查看(解锁态后端按登录用户维护) - api/form.ts 新增 ehrmIdCardApi(unlock/status)
This commit is contained in:
1 parent
1c5b239f2f
commit
25ee6ab0bd
2 files changed
+109
-2
No files matched your search
@@ -91,3 +91,20 @@ export const formApi = {
|
||||
return post<T>('/API/FormAPI/BatchPositions', data)
|
||||
},
|
||||
}
|
||||
|
||||
/**
|
||||
* eHRM 员工档案身份证:二次密码验证
|
||||
*
|
||||
* 身份证号为敏感字段,未解锁时后端返回空值(完全隐藏)。
|
||||
* 输入当前登录用户密码后开启 10 分钟查看窗口,解锁态按登录用户维度共享,
|
||||
* 因此窗口内切换到其他员工档案也能查看。
|
||||
*/
|
||||
export const ehrmIdCardApi = {
|
||||
/** 校验当前登录用户密码,开启 10 分钟身份证查看窗口 */
|
||||
unlock: (password: string): Promise<{ unlocked: boolean; expiresIn: number }> =>
|
||||
post<{ unlocked: boolean; expiresIn: number }>('/API/Ehrm/UnlockIdCard', { Password: password }),
|
||||
|
||||
/** 查询当前登录用户是否处于解锁窗口内 */
|
||||
status: (): Promise<{ unlocked: boolean }> =>
|
||||
get<{ unlocked: boolean }>('/API/Ehrm/IdCardStatus'),
|
||||
}
|
||||
@@ -3,23 +3,76 @@
|
||||
* 档案管理(eHRM 人力资源管理扩展)
|
||||
*
|
||||
* 员工档案表:工号 / 部门 / 入职日期 / 职务 / 学历 / 紧急联系人 / 地址等。
|
||||
*
|
||||
* 身份证号(IdCard)为敏感列:未二次验证时后端返回空值(完全隐藏),
|
||||
* 需在此页点「查看身份证」输入**当前登录账号**密码解锁;解锁后 10 分钟内在
|
||||
* 任意员工档案(含切换到别人)都能查看——解锁态由后端按登录用户维度维护。
|
||||
*/
|
||||
import { computed } from 'vue'
|
||||
import { computed, onMounted, ref } from 'vue'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import CrudTable from '@/components/CrudTable.vue'
|
||||
import AdminBadge from '@/components/AdminBadge.vue'
|
||||
import { useUserStore } from '@/stores/user'
|
||||
import { setPageTitle } from '@/utils/serverScope'
|
||||
import { ehrmIdCardApi } from '@/api/form'
|
||||
|
||||
const userStore = useUserStore()
|
||||
setPageTitle('档案管理')
|
||||
|
||||
const isAdmin = computed(() => userStore.isAdmin)
|
||||
|
||||
// ===== 身份证二次密码验证 =====
|
||||
// 解锁窗口(10 分钟)由后端记录,前端只负责触发解锁并在成功后刷新列表取明文
|
||||
const tableRef = ref()
|
||||
const idCardUnlocked = ref(false)
|
||||
const unlockDialogVisible = ref(false)
|
||||
const unlockPassword = ref('')
|
||||
const unlocking = ref(false)
|
||||
|
||||
/** 查询当前登录用户是否已处于解锁窗口内(页面刷新后恢复按钮状态) */
|
||||
async function loadIdCardStatus(): Promise<void> {
|
||||
try {
|
||||
const res = await ehrmIdCardApi.status()
|
||||
idCardUnlocked.value = !!res?.unlocked
|
||||
} catch {
|
||||
idCardUnlocked.value = false
|
||||
}
|
||||
}
|
||||
|
||||
function openUnlockDialog(): void {
|
||||
unlockPassword.value = ''
|
||||
unlockDialogVisible.value = true
|
||||
}
|
||||
|
||||
/** 提交密码:成功后刷新列表(此时后端才会在 EmployeeProfile 记录里返回身份证明文) */
|
||||
async function submitUnlock(): Promise<void> {
|
||||
if (!unlockPassword.value) {
|
||||
ElMessage.warning('请输入密码')
|
||||
return
|
||||
}
|
||||
unlocking.value = true
|
||||
try {
|
||||
await ehrmIdCardApi.unlock(unlockPassword.value)
|
||||
idCardUnlocked.value = true
|
||||
unlockDialogVisible.value = false
|
||||
unlockPassword.value = ''
|
||||
ElMessage.success('验证成功,10 分钟内可查看身份证号')
|
||||
await tableRef.value?.refresh?.()
|
||||
} catch {
|
||||
// 失败提示由响应拦截器统一弹出(如「密码错误」),弹窗保留供重试
|
||||
} finally {
|
||||
unlocking.value = false
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(loadIdCardStatus)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="ehrm-page">
|
||||
<AdminBadge />
|
||||
<CrudTable
|
||||
ref="tableRef"
|
||||
table="EmployeeProfile"
|
||||
title="员工档案"
|
||||
pk-field="EmployeeProfileUUID"
|
||||
@@ -27,7 +80,37 @@ const isAdmin = computed(() => userStore.isAdmin)
|
||||
pageable
|
||||
stretch
|
||||
:selectable="isAdmin"
|
||||
/>
|
||||
>
|
||||
<template #toolbar>
|
||||
<el-tag v-if="idCardUnlocked" type="success" effect="plain">身份证已解锁</el-tag>
|
||||
<el-button v-else type="warning" plain @click="openUnlockDialog">
|
||||
<el-icon><Lock /></el-icon>查看身份证
|
||||
</el-button>
|
||||
</template>
|
||||
</CrudTable>
|
||||
|
||||
<el-dialog
|
||||
v-model="unlockDialogVisible"
|
||||
title="查看身份证号"
|
||||
width="440px"
|
||||
append-to-body
|
||||
>
|
||||
<p class="idcard-tip">
|
||||
身份证号为敏感信息,请输入当前登录账号的密码完成二次验证。
|
||||
验证通过后 10 分钟内,切换到其他员工档案也可查看。
|
||||
</p>
|
||||
<el-input
|
||||
v-model="unlockPassword"
|
||||
type="password"
|
||||
placeholder="请输入当前登录账号密码"
|
||||
show-password
|
||||
@keyup.enter="submitUnlock"
|
||||
/>
|
||||
<template #footer>
|
||||
<el-button @click="unlockDialogVisible = false">取消</el-button>
|
||||
<el-button type="primary" :loading="unlocking" @click="submitUnlock">验证</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -39,4 +122,11 @@ const isAdmin = computed(() => userStore.isAdmin)
|
||||
flex-direction: column;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.idcard-tip {
|
||||
margin: 0 0 12px;
|
||||
font-size: 13px;
|
||||
line-height: 1.6;
|
||||
color: var(--el-text-color-secondary);
|
||||
}
|
||||
</style>
|
||||
Reference in new issue
Block a user