feat: 社保公积金版本管理 + 员工基数调整 + 加班费计算优化 + UI组件改进
- SocialInsuranceConfig 版本化(effectiveFrom/effectiveTo/isCurrent/adjustmentDone) - 社保配置版本管理接口(列表/新建/按月获取/当前版本) - 员工基数调整:预览全部在职员工、上年月均工资计算建议基数、可编辑表格、确认后批量保存 - payroll.service 按批次月份匹配对应版本社保配置 - risk.service / seed.ts 同步更新 - 前端社保tab重构为版本管理+调整+试算 - 加班费计算三步流程、CSV导入、批次导入 - UI组件、Dashboard、合同、薪酬等页面优化
This commit is contained in:
@@ -48,7 +48,7 @@ export default function ContractConfirm() {
|
||||
<div className="min-h-screen flex items-center justify-center bg-gray-50 px-4">
|
||||
<div className="max-w-sm w-full text-center">
|
||||
<Check className="w-16 h-16 text-safe mx-auto mb-4" />
|
||||
<h1 className="text-lg font-semibold mb-2">合同签署确认成功</h1>
|
||||
<h1 className="text-sm font-semibold mb-2">合同签署确认成功</h1>
|
||||
<p className="text-sm text-gray-500">已记录您的签署确认时间和 IP 地址。</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -60,7 +60,7 @@ export default function ContractConfirm() {
|
||||
<div className="max-w-md mx-auto">
|
||||
<div className="flex items-center gap-2 mb-6">
|
||||
<PenTool className="w-6 h-6 text-primary" />
|
||||
<h1 className="text-lg font-semibold">合同签署确认</h1>
|
||||
<h1 className="text-sm font-semibold">合同签署确认</h1>
|
||||
</div>
|
||||
|
||||
{loading ? (
|
||||
@@ -74,7 +74,7 @@ export default function ContractConfirm() {
|
||||
</Card>
|
||||
) : data ? (
|
||||
<Card>
|
||||
<div className="space-y-4">
|
||||
<div className="space-y-3">
|
||||
<div className="text-sm text-gray-600">
|
||||
{data.orgName} 与 {data.employeeName} 的劳动合同
|
||||
</div>
|
||||
|
||||
@@ -37,7 +37,7 @@ export default function MyContract() {
|
||||
<div className="flex items-center justify-between mb-6">
|
||||
<div className="flex items-center gap-2">
|
||||
<FileText className="w-6 h-6 text-primary" />
|
||||
<h1 className="text-lg font-semibold">我的劳动合同</h1>
|
||||
<h1 className="text-sm font-semibold">我的劳动合同</h1>
|
||||
</div>
|
||||
<div className="flex items-center gap-3">
|
||||
<span className="text-sm text-gray-500">{employee.name}</span>
|
||||
@@ -51,7 +51,7 @@ export default function MyContract() {
|
||||
) : !contract ? (
|
||||
<EmptyState title="暂无合同" description="HR 尚未录入您的合同信息" />
|
||||
) : (
|
||||
<div className="space-y-4">
|
||||
<div className="space-y-3">
|
||||
{/* 到期提醒 */}
|
||||
{daysToExpire !== null && daysToExpire <= 30 && daysToExpire >= 0 && (
|
||||
<div className="flex items-center gap-2 px-3 py-2 rounded-md bg-yellow-50 text-yellow-700 text-sm">
|
||||
|
||||
@@ -53,7 +53,7 @@ export default function Onboarding() {
|
||||
<div className="min-h-screen flex items-center justify-center bg-gray-50 px-4">
|
||||
<div className="max-w-sm w-full text-center">
|
||||
<Check className="w-16 h-16 text-safe mx-auto mb-4" />
|
||||
<h1 className="text-lg font-semibold mb-2">信息提交成功</h1>
|
||||
<h1 className="text-sm font-semibold mb-2">信息提交成功</h1>
|
||||
<p className="text-sm text-gray-500">HR 将审核您的信息,请耐心等待。</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -65,7 +65,7 @@ export default function Onboarding() {
|
||||
<div className="max-w-md mx-auto">
|
||||
<div className="flex items-center gap-2 mb-6">
|
||||
<ClipboardList className="w-6 h-6 text-primary" />
|
||||
<h1 className="text-lg font-semibold">入职信息填报</h1>
|
||||
<h1 className="text-sm font-semibold">入职信息填报</h1>
|
||||
</div>
|
||||
|
||||
{orgName && (
|
||||
@@ -79,7 +79,7 @@ export default function Onboarding() {
|
||||
)}
|
||||
|
||||
<Card>
|
||||
<div className="space-y-4">
|
||||
<div className="space-y-3">
|
||||
<div>
|
||||
<Label>姓名 *</Label>
|
||||
<Input value={form.name} onChange={(e) => setForm({ ...form, name: e.target.value })} placeholder="请输入姓名" />
|
||||
|
||||
@@ -42,7 +42,7 @@ export default function Payslip() {
|
||||
<div className="flex items-center justify-between mb-6">
|
||||
<div className="flex items-center gap-2">
|
||||
<DollarSign className="w-6 h-6 text-primary" />
|
||||
<h1 className="text-lg font-semibold">我的工资条</h1>
|
||||
<h1 className="text-sm font-semibold">我的工资条</h1>
|
||||
</div>
|
||||
<div className="flex items-center gap-3">
|
||||
<span className="text-sm text-gray-500">{employee.name}</span>
|
||||
@@ -93,7 +93,7 @@ export default function Payslip() {
|
||||
<div className="border-t pt-3">
|
||||
<div className="flex justify-between">
|
||||
<span className="font-medium">应发合计</span>
|
||||
<span className="text-xl font-bold text-primary">¥{fmt(Number(data.totalPay))}</span>
|
||||
<span className="text-base font-bold text-primary">¥{fmt(Number(data.totalPay))}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -64,7 +64,7 @@ export default function PortalLogin() {
|
||||
<div className="w-full max-w-sm">
|
||||
<div className="flex items-center justify-center gap-2 mb-8">
|
||||
<Building2 className="w-8 h-8 text-primary" />
|
||||
<span className="text-xl font-bold">用工合规助手 — 员工端</span>
|
||||
<span className="text-base font-bold">用工合规助手 — 员工端</span>
|
||||
</div>
|
||||
|
||||
<div className="card">
|
||||
@@ -82,7 +82,7 @@ export default function PortalLogin() {
|
||||
{error && <div className="mb-4 px-3 py-2 rounded-md bg-red-50 text-red-700 text-sm">{error}</div>}
|
||||
|
||||
{mode === 'password' ? (
|
||||
<div className="space-y-4">
|
||||
<div className="space-y-3">
|
||||
<div>
|
||||
<Label>手机号</Label>
|
||||
<Input type="tel" placeholder="请输入手机号" value={phone} onChange={(e) => setPhone(e.target.value)} maxLength={11} />
|
||||
@@ -96,7 +96,7 @@ export default function PortalLogin() {
|
||||
</Button>
|
||||
</div>
|
||||
) : (
|
||||
<div className="space-y-4">
|
||||
<div className="space-y-3">
|
||||
<div>
|
||||
<Label>手机号</Label>
|
||||
<Input type="tel" placeholder="请输入手机号" value={phone} onChange={(e) => setPhone(e.target.value)} maxLength={11} />
|
||||
|
||||
Reference in New Issue
Block a user