|
|
|
@@ -40,7 +40,7 @@ router.post('/login', async (req, res, next) => {
|
|
|
|
|
// 查找所有匹配手机号的在职员工(可能跨组织)
|
|
|
|
|
const employees = await prisma.employee.findMany({
|
|
|
|
|
where: { phone: data.phone, status: 'ACTIVE' },
|
|
|
|
|
select: { id: true, name: true, department: true, orgId: true, passwordHash: true, org: { select: { name: true } } },
|
|
|
|
|
select: { id: true, name: true, department: true, orgId: true, passwordHash: true, idCardNumber: true, org: { select: { name: true } } },
|
|
|
|
|
})
|
|
|
|
|
if (employees.length === 0) {
|
|
|
|
|
return res.status(400).json({ success: false, error: { code: 'AUTH_FAILED', message: '手机号或密码错误' } })
|
|
|
|
@@ -60,7 +60,7 @@ router.post('/login', async (req, res, next) => {
|
|
|
|
|
return res.status(400).json({ success: false, error: { code: 'AUTH_FAILED', message: '手机号或密码错误' } })
|
|
|
|
|
}
|
|
|
|
|
const token = signAccessToken({ id: matchedEmployee.id, orgId: matchedEmployee.orgId, role: 'EMPLOYEE' })
|
|
|
|
|
res.json({ success: true, data: { token, employee: { id: matchedEmployee.id, name: matchedEmployee.name, department: matchedEmployee.department, orgName: (matchedEmployee as any).org?.name || '' } } })
|
|
|
|
|
res.json({ success: true, data: { token, employee: { id: matchedEmployee.id, name: matchedEmployee.name, department: matchedEmployee.department, orgName: (matchedEmployee as any).org?.name || '', idCardNumber: (() => { try { return matchedEmployee.idCardNumber ? (matchedEmployee.idCardNumber.includes(':') ? decrypt(matchedEmployee.idCardNumber) : matchedEmployee.idCardNumber) : null } catch { return null } })() } } })
|
|
|
|
|
} catch (err) {
|
|
|
|
|
next(err)
|
|
|
|
|
}
|
|
|
|
@@ -110,7 +110,7 @@ router.post('/verify-code', async (req, res, next) => {
|
|
|
|
|
// 查找所有匹配手机号的在职员工(可能跨组织)
|
|
|
|
|
const employees = await prisma.employee.findMany({
|
|
|
|
|
where: { phone: data.phone, status: 'ACTIVE' },
|
|
|
|
|
select: { id: true, name: true, department: true, orgId: true, org: { select: { name: true } } },
|
|
|
|
|
select: { id: true, name: true, department: true, orgId: true, idCardNumber: true, org: { select: { name: true } } },
|
|
|
|
|
})
|
|
|
|
|
if (employees.length === 0) {
|
|
|
|
|
return res.status(400).json({ success: false, error: { code: 'NOT_FOUND', message: '员工不存在' } })
|
|
|
|
@@ -118,7 +118,7 @@ router.post('/verify-code', async (req, res, next) => {
|
|
|
|
|
// 如果只有一个匹配,直接登录
|
|
|
|
|
const employee = employees[0]
|
|
|
|
|
const token = signAccessToken({ id: employee.id, orgId: employee.orgId, role: 'EMPLOYEE' })
|
|
|
|
|
res.json({ success: true, data: { token, employee: { id: employee.id, name: employee.name, department: employee.department, orgName: (employee as any).org?.name || '' } } })
|
|
|
|
|
res.json({ success: true, data: { token, employee: { id: employee.id, name: employee.name, department: employee.department, orgName: (employee as any).org?.name || '', idCardNumber: (() => { try { return employee.idCardNumber ? (employee.idCardNumber.includes(':') ? decrypt(employee.idCardNumber) : employee.idCardNumber) : null } catch { return null } })() } } })
|
|
|
|
|
} catch (err) {
|
|
|
|
|
next(err)
|
|
|
|
|
}
|
|
|
|
@@ -421,7 +421,7 @@ router.get('/contract-confirm/:token', async (req, res, next) => {
|
|
|
|
|
include: {
|
|
|
|
|
contract: {
|
|
|
|
|
include: {
|
|
|
|
|
employee: { select: { name: true, org: { select: { name: true } } } },
|
|
|
|
|
employee: { select: { name: true, idCardNumber: true, org: { select: { name: true } } } },
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
@@ -434,6 +434,7 @@ router.get('/contract-confirm/:token', async (req, res, next) => {
|
|
|
|
|
data: {
|
|
|
|
|
orgName: link.contract.employee.org.name,
|
|
|
|
|
employeeName: link.contract.employee.name,
|
|
|
|
|
employeeIdCardNumber: (() => { try { const v = link.contract.employee.idCardNumber; return v ? (v.includes(':') ? decrypt(v) : v) : null } catch { return null } })(),
|
|
|
|
|
contract: link.contract,
|
|
|
|
|
},
|
|
|
|
|
})
|
|
|
|
@@ -694,13 +695,13 @@ router.get('/auto-login', async (req, res, next) => {
|
|
|
|
|
}
|
|
|
|
|
const employee = await prisma.employee.findFirst({
|
|
|
|
|
where: { id: payload.id, orgId: payload.orgId, status: 'ACTIVE' },
|
|
|
|
|
select: { id: true, name: true, department: true, orgId: true, org: { select: { name: true } } },
|
|
|
|
|
select: { id: true, name: true, department: true, orgId: true, idCardNumber: true, org: { select: { name: true } } },
|
|
|
|
|
})
|
|
|
|
|
if (!employee) {
|
|
|
|
|
return res.status(404).json({ success: false, error: { code: 'NOT_FOUND', message: '员工不存在或已离职' } })
|
|
|
|
|
}
|
|
|
|
|
const accessToken = signAccessToken({ id: employee.id, orgId: employee.orgId, role: 'EMPLOYEE' })
|
|
|
|
|
res.json({ success: true, data: { token: accessToken, employee: { id: employee.id, name: employee.name, department: employee.department, orgName: (employee as any).org?.name || '' } } })
|
|
|
|
|
res.json({ success: true, data: { token: accessToken, employee: { id: employee.id, name: employee.name, department: employee.department, orgName: (employee as any).org?.name || '', idCardNumber: (() => { try { return employee.idCardNumber ? (employee.idCardNumber.includes(':') ? decrypt(employee.idCardNumber) : employee.idCardNumber) : null } catch { return null } })() } } })
|
|
|
|
|
} catch (err) {
|
|
|
|
|
next(err)
|
|
|
|
|
}
|
|
|
|
@@ -742,6 +743,9 @@ router.get('/home/overview', portalAuth, async (req: any, res, next) => {
|
|
|
|
|
const employee = await prisma.employee.findFirst({ where: { id: employeeId, orgId } })
|
|
|
|
|
if (!employee) return res.status(404).json({ success: false, error: { code: 'NOT_FOUND', message: '员工不存在' } })
|
|
|
|
|
|
|
|
|
|
let employeeIdCardNumber: string | null = null
|
|
|
|
|
try { if (employee.idCardNumber) employeeIdCardNumber = employee.idCardNumber.includes(':') ? decrypt(employee.idCardNumber) : employee.idCardNumber } catch {}
|
|
|
|
|
|
|
|
|
|
// 最新工资条
|
|
|
|
|
const latestPayslip = await prisma.payslip.findFirst({
|
|
|
|
|
where: { employeeId, orgId, publishStatus: 'PUBLISHED' },
|
|
|
|
@@ -808,6 +812,8 @@ router.get('/home/overview', portalAuth, async (req: any, res, next) => {
|
|
|
|
|
res.json({
|
|
|
|
|
success: true,
|
|
|
|
|
data: {
|
|
|
|
|
employeeName: employee.name,
|
|
|
|
|
employeeIdCardNumber,
|
|
|
|
|
latestPayslip,
|
|
|
|
|
contract: contract ? {
|
|
|
|
|
typeLabel: typeLabels[contract.contractType] || contract.contractType,
|
|
|
|
|