Sprint 3: 员工目录优化 + Profile Shell + 离职工作流重构 + 合同类型扩充 + 月度社保重构 + 商险管理Tab

S3-1: Roster.tsx 添加 InlineAlert 合同风险提示 + 快捷筛选标签
S3-2: 新建 EmployeeProfileShell.tsx 统一员工详情布局,重构 EmployeeProfile.tsx
S3-3: Termination.tsx 集成 Stepper 步骤条 + InlineAlert 风险提示
S3-4: schema.prisma ContractType 枚举扩充 DISPATCH/OUTSOURCING/PARTTIME + 后端接口 + 前端选择器
S3-5: SocialInsurance.tsx 月度办理 Tab 使用 InlineAlert 替换原始提示
S3-6: SocialInsurance.tsx 新增商险管理 Tab(方案CRUD + 参保人员列表)
This commit is contained in:
selfrelease
2026-07-31 18:07:49 +08:00
parent 55b6867c9c
commit 9946197d20
7 changed files with 636 additions and 81 deletions
+17 -16
View File
@@ -2,6 +2,8 @@ import { useState, useMemo, useEffect } from 'react'
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'
import { toast } from 'sonner'
import { AlertTriangle, Check, ChevronRight, ChevronLeft, Shield, Info, Calculator, FileText, Printer, Trash2, List, Download, Plus, Edit, Send, CheckCircle, XCircle, Play, Ban, CheckCheck } from 'lucide-react'
import { Stepper } from '../components/ui/Stepper'
import { InlineAlert } from '../components/ui/InlineAlert'
import jsPDF from 'jspdf'
import api from '../lib/api'
import { useAuthStore } from '../store/authStore'
@@ -976,15 +978,16 @@ export default function Termination() {
{/* 左侧:向导 */}
<div className="flex-1 min-w-0">
{/* 进度条 */}
<div className="flex items-center gap-1">
{STEPS.map((_s, i) => (
<div key={i} className="flex items-center">
<div className={`w-2.5 h-2.5 rounded-full ${i <= step ? 'bg-primary' : 'bg-gray-300'}`} />
{i < STEPS.length - 1 && <div className={`w-6 h-0.5 ${i < step ? 'bg-primary' : 'bg-gray-300'}`} />}
</div>
))}
</div>
{/* 步骤条 */}
<Stepper
steps={STEPS.map((title: string, i: number) => ({
key: String(i),
title,
status: i < step ? 'complete' : i === step ? 'current' : 'pending',
}))}
onStepClick={(key) => { const i = parseInt(key); if (i <= step) setStep(i) }}
className="mb-4"
/>
<Card>
<div className="mb-2 text-xs text-gray-500">Step {step + 1}/6{STEPS[step]}</div>
@@ -1161,10 +1164,9 @@ export default function Termination() {
{riskAssessment && riskAssessment.warnings.length > 0 && (
<div className="space-y-2">
{riskAssessment.warnings.map((w, i) => (
<div key={i} className="flex items-center gap-2 px-3 py-2 rounded-md bg-red-50 text-red-700 text-xs">
<AlertTriangle className="w-4 h-4 shrink-0" />
<InlineAlert key={i} type="error">
{w}
</div>
</InlineAlert>
))}
<label className="flex items-center gap-2 text-xs px-3 py-2 rounded-md bg-yellow-50 text-yellow-800">
<input type="checkbox" checked={acknowledgeRisk} onChange={(e) => setAcknowledgeRisk(e.target.checked)} />
@@ -1178,10 +1180,9 @@ export default function Termination() {
{/* Step 3: 合规检查 */}
{step === 2 && (
<div className="space-y-3">
<div className="bg-blue-50 text-blue-700 text-xs px-3 py-2 rounded-md flex items-start gap-2">
<Info className="w-4 h-4 mt-0.5 shrink-0" />
<div></div>
</div>
<InlineAlert type="info">
</InlineAlert>
{checklistItems?.map((item) => {
const checked = checklist[item.key] || false
const isAutoChecked = item.autoChecked !== null && item.autoChecked !== undefined