feat: 电子签署导航调整+员工手机端电子签署功能

- 管理端导航:电子签署移到首页分组(工作日历下)
- 员工端新增电子签署页面(MyEsign.tsx):
  - 查看自己的签署记录列表,支持待签/已签/已取消状态
  - 查看签署详情,含文件内容、关联合同标识
  - 确认签署操作(框架阶段,对接易签宝后跳转签署页面)
- 员工端导航(PortalNav)增加电子签署入口
- 员工首页(EmployeeHome)增加电子签署快捷入口
- 员工首页待办事项增加待签署文件提醒
- 后端portal路由新增3个接口:GET /esign、GET /esign/:id、POST /esign/:id/sign
This commit is contained in:
freedakgmail
2026-08-05 07:39:11 +08:00
parent b9240ffe9b
commit e8cd0f472b
7 changed files with 271 additions and 3 deletions
+64
View File
@@ -705,6 +705,14 @@ router.get('/home/overview', portalAuth, async (req: any, res, next) => {
if (unreadPolicies.length > 0) {
pendingTasks.push({ severity: 'medium', message: `您有 ${unreadPolicies.length} 份制度待阅读确认` })
}
// 待签署文件
const pendingEsign = await prisma.eSignRecord.findMany({
where: { employeeId, orgId, status: 'PENDING' },
select: { id: true, documentTitle: true },
})
if (pendingEsign.length > 0) {
pendingTasks.push({ severity: 'high', message: `您有 ${pendingEsign.length} 份文件待签署(${pendingEsign.map(e => e.documentTitle).join('、')}` })
}
res.json({
success: true,
@@ -903,4 +911,60 @@ router.post('/leaves/:id/cancel', portalAuth, async (req: any, res, next) => {
} catch (err) { next(err) }
})
// ========== 员工端:电子签署 ==========
// 查看自己的签署记录列表
router.get('/esign', portalAuth, async (req: any, res, next) => {
try {
const { id: employeeId, orgId } = req.employee
const records = await prisma.eSignRecord.findMany({
where: { employeeId, orgId },
orderBy: { createdAt: 'desc' },
})
res.json({ success: true, data: records })
} catch (err) { next(err) }
})
// 查看签署详情
router.get('/esign/:id', portalAuth, async (req: any, res, next) => {
try {
const { id: employeeId, orgId } = req.employee
const record = await prisma.eSignRecord.findFirst({
where: { id: req.params.id, employeeId, orgId },
})
if (!record) return res.status(404).json({ success: false, error: { message: '记录不存在' } })
res.json({ success: true, data: record })
} catch (err) { next(err) }
})
// 员工签署操作(预留:对接易签宝后跳转到签署页面或提交签署结果)
router.post('/esign/:id/sign', portalAuth, async (req: any, res, next) => {
try {
const { id: employeeId, orgId } = req.employee
const record = await prisma.eSignRecord.findFirst({
where: { id: req.params.id, employeeId, orgId, status: 'PENDING' },
})
if (!record) return res.status(404).json({ success: false, error: { message: '记录不存在或已处理' } })
// 预留:对接易签宝后,此处应跳转到易签宝签署页面或接收签署结果
// 当前框架阶段:直接标记为已签署
const updated = await prisma.eSignRecord.update({
where: { id: record.id },
data: {
status: 'COMPLETED',
completedAt: new Date(),
},
})
// 如果关联了合同,更新合同签署信息
if (record.contractId) {
await prisma.laborContract.update({
where: { id: record.contractId },
data: { signMethod: 'ELECTRONIC' },
})
}
res.json({ success: true, data: updated, message: '签署成功' })
} catch (err) { next(err) }
})
export default router