- 员工主动离职,不涉及经济补偿金。离职日期可在未来(提前办理),到日期后状态自动变为离职。
+ 员工试用期结束,确认转正。转正后薪资将更新到花名册。
{employee.name} - {employee.department}
-
- setForm({ ...form, terminationDate: e.target.value })}
- />
+
+ setForm({ ...form, confirmDate: e.target.value })} />
-
-
-
-
-
-
默认与离职日期同月,可手动修改
-
- {((form.socialInsEndMonth && form.socialInsEndMonth !== terminationMonth) || (form.housingFundEndMonth && form.housingFundEndMonth !== terminationMonth)) && (
-
-
- 截止缴费年月与离职日期不在同月,请确认是否为多缴/少缴月份。
-
- )}
-
-
-
-
setForm({ ...form, remark: e.target.value })} placeholder="补充说明" />
+
+
setForm({ ...form, regularSalary: e.target.value })} placeholder="不填则保持原薪资" />
+
填写后将更新员工月工资并记录薪资变更
{error && (
@@ -224,7 +315,7 @@ export function ResignModal({ employee, onClose, onSubmit, loading, error }: {
@@ -554,8 +645,10 @@ export function AddEmployeeModal({ onClose, onSubmit, loading, error }: {
}
}
- // 根据身份证号自动计算性别(第17位:奇数=男,偶数=女)+ 查重
+ // 根据证件号码自动计算性别(第17位:奇数=男,偶数=女)+ 查重 + 年龄合规筛查
const [idCardDuplicate, setIdCardDuplicate] = useState<{ exists: boolean; employee?: any } | null>(null)
+ const [ageWarning, setAgeWarning] = useState<{ type: 'BLOCK' | 'WARN'; message: string } | null>(null)
+ const [phoneDuplicate, setPhoneDuplicate] = useState<{ exists: boolean; employee?: any } | null>(null)
const handleIdCardChange = (idCard: string) => {
let gender = form.gender
if (idCard.length >= 17) {
@@ -564,10 +657,32 @@ export function AddEmployeeModal({ onClose, onSubmit, loading, error }: {
}
setForm({ ...form, idCardNumber: idCard, gender })
setIdCardDuplicate(null)
+ setAgeWarning(null)
if (idCard.length === 18) {
employeeApi.checkIdCard(idCard).then((data: { exists: boolean; employee?: any }) => {
setIdCardDuplicate(data)
}).catch(() => {})
+ // 年龄合规筛查:从证件号码提取出生日期计算年龄
+ const birthYear = parseInt(idCard.substring(6, 10))
+ const birthMonth = parseInt(idCard.substring(10, 12))
+ const birthDay = parseInt(idCard.substring(12, 14))
+ if (!isNaN(birthYear) && !isNaN(birthMonth) && !isNaN(birthDay)) {
+ const today = new Date()
+ let age = today.getFullYear() - birthYear
+ const monthDiff = today.getMonth() - (birthMonth - 1)
+ if (monthDiff < 0 || (monthDiff === 0 && today.getDate() < birthDay)) {
+ age--
+ }
+ if (age < 16) {
+ setAgeWarning({ type: 'BLOCK', message: `该员工年龄 ${age} 岁,未满16周岁,禁止招用童工(《劳动法》第15条)` })
+ } else if (age < 18) {
+ setAgeWarning({ type: 'WARN', message: `该员工年龄 ${age} 岁,未满18周岁,属于未成年工,需遵守特殊保护规定(《劳动法》第58条)` })
+ } else if (gender === '男' && age >= 60) {
+ setAgeWarning({ type: 'WARN', message: `该员工年龄 ${age} 岁,已达法定退休年龄(男60岁),建议确认是否按退休处理` })
+ } else if (gender === '女' && age >= 50) {
+ setAgeWarning({ type: 'WARN', message: `该员工年龄 ${age} 岁,已达或接近法定退休年龄(女工人50岁/干部55岁),建议确认是否按退休处理` })
+ }
+ }
}
}
@@ -633,6 +748,11 @@ export function AddEmployeeModal({ onClose, onSubmit, loading, error }: {
}
const handleSubmit = () => {
+ // 童工阻断:未满16周岁禁止录入
+ if (ageWarning?.type === 'BLOCK') {
+ toast.error(ageWarning.message)
+ return
+ }
const data: any = {
name: form.name, department: form.department,
position: form.position || undefined,
@@ -684,11 +804,17 @@ export function AddEmployeeModal({ onClose, onSubmit, loading, error }: {
setForm({ ...form, name: e.target.value })} placeholder="员工姓名" />
setForm({ ...form, department: e.target.value })} placeholder="如:技术部" />
setForm({ ...form, position: e.target.value })} placeholder="如:前端工程师" />
-
handleIdCardChange(e.target.value)} placeholder="18位" maxLength={18} />
+
handleIdCardChange(e.target.value)} placeholder="18位" maxLength={18} />
{idCardDuplicate?.exists && (
-
该身份证号已存在:{idCardDuplicate.employee?.name}({idCardDuplicate.employee?.department}),请确认是否重复录入
+
该证件号码已存在:{idCardDuplicate.employee?.name}({idCardDuplicate.employee?.department}),请确认是否重复录入
+
+ )}
+ {ageWarning && (
+
)}
{form.idCardNumber.length >= 17 ? form.gender : '自动识别'}
@@ -699,8 +825,23 @@ export function AddEmployeeModal({ onClose, onSubmit, loading, error }: {
+ {phoneDuplicate?.exists && (
+
+
+
该手机号已存在:{phoneDuplicate.employee?.name}({phoneDuplicate.employee?.department}),请确认是否重复录入
+
+ )}