feat: 完成全部11项优化需求 + 模板必填项标注 + 归档重算个税

- 高优先级: 花名册导入模板必填项标注、性别自动识别、导入结果反馈、证据链Excel导出、身份证搜索修复、试用期区分与转正提醒、薪税批次流程优化
- 中优先级: 专项附加扣除批量导入、文本模板库完善(Word下载/复制/使用说明)、用工体检评分标准说明、考勤页面导入入口
- 所有导入模板表头标注必填项(*后缀)并含示例行
- 导入逻辑统一改用getField兼容*后缀列名
- 批次归档时强制重算所有条目个税和社保,解决多未归档批次并存时累计计算不准问题
- 更新需求梳理文档
This commit is contained in:
freedakgmail
2026-07-29 19:08:45 +08:00
parent 7c24ebe3d9
commit 0372cbe243
14 changed files with 1275 additions and 171 deletions
+16 -2
View File
@@ -51,7 +51,8 @@ export default function Roster() {
queryFn: async () => {
const params: any = { page, pageSize }
if (debouncedSearch) params.search = debouncedSearch
if (filterStatus) params.status = filterStatus
if (filterStatus && filterStatus !== 'PROBATION') params.status = filterStatus
if (filterStatus === 'PROBATION') params.status = 'ACTIVE'
if (filterContractStatus) params.contractStatus = filterContractStatus
if (filterDepartment) params.department = filterDepartment
const res = await api.get('/roster', { params }) as any
@@ -59,7 +60,10 @@ export default function Roster() {
},
})
const employees = rosterData?.data || []
const employees = (rosterData?.data || []).filter((e: any) => {
if (filterStatus === 'PROBATION') return e.probationInfo?.isProbation
return true
})
const pagination = rosterData?.pagination || { page, pageSize, total: 0, totalPages: 0 }
const addMutation = useMutation({
@@ -255,6 +259,7 @@ export default function Roster() {
>
<option value=""></option>
<option value="ACTIVE"></option>
<option value="PROBATION"></option>
<option value="PRE_HIRE"></option>
<option value="RESIGNED"></option>
</select>
@@ -388,6 +393,15 @@ export default function Roster() {
}`}>
{e.status === 'ACTIVE' ? '在职' : e.status === 'PRE_HIRE' ? '预入职' : '离职'}
</span>
{e.probationInfo?.isProbation && (
<span className={`ml-1 px-2 py-0.5 rounded text-xs ${
e.probationInfo.isExpiring
? 'bg-orange-50 text-orange-700 border border-orange-200'
: 'bg-amber-50 text-amber-700 border border-amber-200'
}`}>
{e.probationInfo.isExpiring ? `即将到期(${e.probationInfo.daysToConfirm}天)` : `${e.probationInfo.daysToConfirm}`}
</span>
)}
</td>
<td className="hidden px-4 py-3 text-gray-500">{e.hireDate?.toString().slice(0, 10)}</td>
<td className="hidden px-4 py-3 text-gray-500">