优化: 添加员工弹窗-身份证号必填+性别自动识别
1. 身份证号必填(18位),后端加密存储 2. 性别由身份证号第17位自动计算(奇数=男,偶数=女),无需手动选择 3. 移除添加员工时的孕期/医疗期/工伤复选框(这些状态后续在员工档案中维护)
This commit is contained in:
@@ -164,6 +164,7 @@ export async function createEmployee(orgId: string, userId: string, data: any) {
|
||||
monthlySalary: encrypt(data.monthlySalary),
|
||||
gender: data.gender,
|
||||
phone: data.phone,
|
||||
idCardNumber: data.idCardNumber ? encrypt(data.idCardNumber) : null,
|
||||
isPregnant: data.isPregnant || false,
|
||||
isInMedicalPeriod: data.isInMedicalPeriod || false,
|
||||
isWorkInjured: data.isWorkInjured || false,
|
||||
|
||||
@@ -931,13 +931,22 @@ function AddEmployeeModal({ onClose, onSubmit, loading, error }: {
|
||||
})()
|
||||
const [form, setForm] = useState({
|
||||
name: '', department: '', hireDate: todayStr, monthlySalary: '',
|
||||
gender: '男' as '男' | '女', phone: '',
|
||||
isPregnant: false, isInMedicalPeriod: false, isWorkInjured: false,
|
||||
idCardNumber: '', gender: '男' as '男' | '女', phone: '',
|
||||
contractType: 'FIXED' as 'FIXED' | 'UNFIXED' | 'UNSIGNED',
|
||||
signDate: '', startDate: todayStr, endDate: defaultEndDate,
|
||||
contractYears: 3, probationMonths: 0, probationSalary: 0,
|
||||
})
|
||||
|
||||
// 根据身份证号自动计算性别(第17位:奇数=男,偶数=女)
|
||||
const handleIdCardChange = (idCard: string) => {
|
||||
let gender = form.gender
|
||||
if (idCard.length >= 17) {
|
||||
const digit = parseInt(idCard[16])
|
||||
if (!isNaN(digit)) gender = digit % 2 === 1 ? '男' : '女'
|
||||
}
|
||||
setForm({ ...form, idCardNumber: idCard, gender })
|
||||
}
|
||||
|
||||
// 计算合同月数
|
||||
const contractMonths = (() => {
|
||||
if (form.contractType !== 'FIXED' || !form.startDate) return 0
|
||||
@@ -1017,8 +1026,8 @@ function AddEmployeeModal({ onClose, onSubmit, loading, error }: {
|
||||
name: form.name, department: form.department,
|
||||
hireDate: new Date(form.hireDate).toISOString(),
|
||||
monthlySalary: form.monthlySalary, gender: form.gender,
|
||||
idCardNumber: form.idCardNumber || undefined,
|
||||
phone: form.phone || undefined,
|
||||
isPregnant: form.isPregnant, isInMedicalPeriod: form.isInMedicalPeriod, isWorkInjured: form.isWorkInjured,
|
||||
}
|
||||
if (form.contractType !== 'UNSIGNED' && form.startDate) {
|
||||
data.contract = {
|
||||
@@ -1033,6 +1042,7 @@ function AddEmployeeModal({ onClose, onSubmit, loading, error }: {
|
||||
}
|
||||
|
||||
const canSubmit = form.name && form.department && form.hireDate && form.monthlySalary
|
||||
&& form.idCardNumber.length >= 18
|
||||
&& (form.contractType === 'UNSIGNED' || form.startDate)
|
||||
&& !probationError && !probationSalaryError
|
||||
|
||||
@@ -1048,19 +1058,17 @@ function AddEmployeeModal({ onClose, onSubmit, loading, error }: {
|
||||
<div><Label>姓名 *</Label><Input value={form.name} onChange={(e) => setForm({ ...form, name: e.target.value })} placeholder="员工姓名" /></div>
|
||||
<div><Label>部门 *</Label><Input value={form.department} onChange={(e) => setForm({ ...form, department: e.target.value })} placeholder="如:技术部" /></div>
|
||||
</div>
|
||||
<div className="grid grid-cols-2 gap-3">
|
||||
<div><Label>身份证号 *</Label><Input value={form.idCardNumber} onChange={(e) => handleIdCardChange(e.target.value)} placeholder="18位身份证号" maxLength={18} /></div>
|
||||
<div><Label>性别</Label><div className="text-xs text-gray-600 py-1.5">{form.idCardNumber.length >= 17 ? form.gender : '由身份证号自动识别'}</div></div>
|
||||
</div>
|
||||
<div className="grid grid-cols-2 gap-3">
|
||||
<div><Label>入职日期 *</Label><Input type="date" value={form.hireDate} onChange={(e) => setForm({ ...form, hireDate: e.target.value })} /></div>
|
||||
<div><Label>月工资 *</Label><Input type="number" value={form.monthlySalary} onChange={(e) => setForm({ ...form, monthlySalary: e.target.value })} placeholder="元" /></div>
|
||||
</div>
|
||||
<div className="grid grid-cols-2 gap-3">
|
||||
<div><Label>性别</Label><Select value={form.gender} onChange={(e) => setForm({ ...form, gender: e.target.value as '男' | '女' })}><option value="男">男</option><option value="女">女</option></Select></div>
|
||||
<div><Label>手机号</Label><Input value={form.phone} onChange={(e) => setForm({ ...form, phone: e.target.value })} placeholder="选填" maxLength={11} /></div>
|
||||
</div>
|
||||
<div className="flex gap-4">
|
||||
<label className="flex items-center gap-1.5 text-xs"><input type="checkbox" checked={form.isPregnant} onChange={(e) => setForm({ ...form, isPregnant: e.target.checked })} />孕期/哺乳期</label>
|
||||
<label className="flex items-center gap-1.5 text-xs"><input type="checkbox" checked={form.isInMedicalPeriod} onChange={(e) => setForm({ ...form, isInMedicalPeriod: e.target.checked })} />医疗期</label>
|
||||
<label className="flex items-center gap-1.5 text-xs"><input type="checkbox" checked={form.isWorkInjured} onChange={(e) => setForm({ ...form, isWorkInjured: e.target.checked })} />工伤</label>
|
||||
</div>
|
||||
<div className="border-t pt-3">
|
||||
<Label>合同类型</Label>
|
||||
<Select value={form.contractType} onChange={(e) => setForm({ ...form, contractType: e.target.value as any, endDate: e.target.value === 'UNFIXED' ? '' : form.endDate })}>
|
||||
|
||||
Reference in New Issue
Block a user