feat: 实现20260730优化方案全部功能
- AI文件审查:.docx上传提取文本,支持多种文档类型 - 用工办理工作流:WorkProcess页面+后端API,支持入职/续签/终止等流程 - 企业自建文本库:Templates页面Tab切换,企业模板CRUD+渲染+下载Word - 考勤发布:Attendance发布/取消发布按钮,员工端MyAttendance页面 - 工资条发布:Money发布/定时发送按钮+弹窗,portal端publishStatus过滤 - 合同到期弹窗:Dashboard合同到期预警可点击打开弹窗,支持续签/终止操作 - Prisma schema新增WorkProcess/EnterpriseTemplate/AttendancePublish模型 - 前后端编译验证全部通过
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import { useState, useRef } from 'react'
|
||||
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'
|
||||
import { toast } from 'sonner'
|
||||
import { CalendarCheck, CheckCircle, Clock, AlertCircle, Plus, Trash2, Calendar, Users, BarChart3, Plane, Upload, Download, X } from 'lucide-react'
|
||||
import { CalendarCheck, CheckCircle, Clock, AlertCircle, Plus, Trash2, Calendar, Users, BarChart3, Plane, Upload, Download, X, Send, Loader2 } from 'lucide-react'
|
||||
import api from '../lib/api'
|
||||
import { useAuthStore } from '../store/authStore'
|
||||
import Card from '../components/ui/Card'
|
||||
@@ -124,9 +124,53 @@ function ConfirmTab() {
|
||||
},
|
||||
})
|
||||
|
||||
const { data: publishRecords } = useQuery<any[]>({
|
||||
queryKey: ['attendance-publish-records'],
|
||||
queryFn: async () => {
|
||||
const res = await api.get('/attendance/publish-records') as any
|
||||
return res.data
|
||||
},
|
||||
})
|
||||
|
||||
const publishMutation = useMutation({
|
||||
mutationFn: async () => {
|
||||
const res = await api.post('/attendance/publish', { month }) as any
|
||||
return res.data
|
||||
},
|
||||
onSuccess: () => {
|
||||
toast.success(`${month}月考勤表已发布`)
|
||||
queryClient.invalidateQueries({ queryKey: ['attendance-publish-records'] })
|
||||
},
|
||||
onError: (err: any) => toast.error(err?.response?.data?.error?.message || '发布失败'),
|
||||
})
|
||||
|
||||
const cancelPublishMutation = useMutation({
|
||||
mutationFn: async (id: string) => {
|
||||
const res = await api.post(`/attendance/publish/${id}/cancel`) as any
|
||||
return res.data
|
||||
},
|
||||
onSuccess: () => {
|
||||
toast.success('已取消发布')
|
||||
queryClient.invalidateQueries({ queryKey: ['attendance-publish-records'] })
|
||||
},
|
||||
onError: (err: any) => toast.error(err?.response?.data?.error?.message || '取消失败'),
|
||||
})
|
||||
|
||||
const currentPublish = publishRecords?.find((r: any) => r.month === month && r.status === 'PUBLISHED')
|
||||
|
||||
return (
|
||||
<div className="space-y-3">
|
||||
<div className="flex items-center gap-2 justify-end">
|
||||
{currentPublish ? (
|
||||
<Button size="sm" variant="secondary" onClick={() => cancelPublishMutation.mutate(currentPublish.id)}>
|
||||
<X className="w-3.5 h-3.5 mr-1" />取消发布
|
||||
</Button>
|
||||
) : (
|
||||
<Button size="sm" onClick={() => publishMutation.mutate()} disabled={publishMutation.isPending}>
|
||||
{publishMutation.isPending ? <Loader2 className="w-3.5 h-3.5 mr-1 animate-spin" /> : <Send className="w-3.5 h-3.5 mr-1" />}
|
||||
发布考勤表
|
||||
</Button>
|
||||
)}
|
||||
<Button size="sm" variant="secondary" onClick={() => setShowImport(true)}>
|
||||
<Upload className="w-3.5 h-3.5 mr-1" />导入考勤
|
||||
</Button>
|
||||
|
||||
Reference in New Issue
Block a user