feat: 20260809 系统优化 - 全部28项问题修复(P0×6+P1×16+P2×6)
P0: 福利批量参保/离职证明下载防乱码/考勤模板合并Sheet/补卡修改/附件在线查看删除 P1: 分页pageSize修复/离职导出筛选/撤回删除草稿/加班费自动计算/考勤加班汇总/证据链异常详情/制度催办/模板导入Word/社保封顶保底/校验字段提示/职务字段/社保费用明细/弹窗防误关/身份证查重/证明员工下拉/培训批量 P2: 离职流程去重/社保基数覆盖输入/薪税入口改名/添加员工引导/绩效模板清理
This commit is contained in:
@@ -2,7 +2,7 @@ import { useState } from 'react'
|
||||
import { usePageSize } from '../hooks/usePageSize'
|
||||
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'
|
||||
import { toast } from 'sonner'
|
||||
import { FileText, Plus, ChevronRight, CheckCircle, Clock, X } from 'lucide-react'
|
||||
import { FileText, Plus, ChevronRight, CheckCircle, Clock, X, Bell } from 'lucide-react'
|
||||
import { policiesApi } from '../lib/api-services'
|
||||
import Card from '../components/ui/Card'
|
||||
import Button from '../components/ui/Button'
|
||||
@@ -247,6 +247,8 @@ function CreatePolicyModal({ onClose, onSuccess }: { onClose: () => void; onSucc
|
||||
* 阅读签收统计组件
|
||||
*/
|
||||
function ReadStats({ policyId }: { policyId: string }) {
|
||||
const queryClient = useQueryClient()
|
||||
const [showUnread, setShowUnread] = useState(false)
|
||||
const { data, isLoading } = useQuery<any>({
|
||||
queryKey: ['policy-read-stats', policyId],
|
||||
queryFn: async () => {
|
||||
@@ -254,6 +256,17 @@ function ReadStats({ policyId }: { policyId: string }) {
|
||||
},
|
||||
})
|
||||
|
||||
const remindMutation = useMutation({
|
||||
mutationFn: async (employeeIds?: string[]) => {
|
||||
return await policiesApi.remind(policyId, employeeIds)
|
||||
},
|
||||
onSuccess: (res: any) => {
|
||||
toast.success(`已催办 ${res?.reminded || 0} 名未签收员工`)
|
||||
queryClient.invalidateQueries({ queryKey: ['policy-read-stats', policyId] })
|
||||
},
|
||||
onError: () => toast.error('催办失败'),
|
||||
})
|
||||
|
||||
if (isLoading) return <div className="text-xs text-gray-400 mt-3">加载阅读统计...</div>
|
||||
if (!data) return null
|
||||
|
||||
@@ -271,8 +284,25 @@ function ReadStats({ policyId }: { policyId: string }) {
|
||||
</span>
|
||||
</div>
|
||||
{data.unreadCount > 0 && (
|
||||
<div className="text-xs text-amber-600 mb-2">
|
||||
{data.unreadCount} 人未签收
|
||||
<div className="flex items-center gap-2 mb-2">
|
||||
<span className="text-xs text-amber-600">{data.unreadCount} 人未签收</span>
|
||||
<button onClick={() => setShowUnread(!showUnread)} className="text-xs text-primary hover:underline">
|
||||
{showUnread ? '收起' : '查看明细'}
|
||||
</button>
|
||||
<Button size="sm" variant="secondary" className="!h-6 !px-2 !text-xs" onClick={() => remindMutation.mutate(undefined)} disabled={remindMutation.isPending}>
|
||||
<Bell className="w-3 h-3 mr-1" />一键催办
|
||||
</Button>
|
||||
</div>
|
||||
)}
|
||||
{showUnread && data.unreadEmployees && data.unreadEmployees.length > 0 && (
|
||||
<div className="max-h-40 overflow-y-auto space-y-1 mb-2">
|
||||
{data.unreadEmployees.map((r: any) => (
|
||||
<div key={r.employeeId} className="flex items-center justify-between px-2 py-1 rounded bg-amber-50 text-xs">
|
||||
<span className="text-gray-700">{r.employeeName}</span>
|
||||
<span className="text-gray-400">{r.department}</span>
|
||||
<span className="text-amber-600">未签收</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
{data.records && data.records.length > 0 && (
|
||||
|
||||
Reference in New Issue
Block a user