feat: 完成23项系统优化 - 花名册社保状态列/身份证复制/附件类型扩展, 用工办理姓名检索/直接提交/文书查看/批量证明, 风险中心跳转筛选+批量处理, 日历7/15/35天分组+逾期统计, 考勤单条编辑+按人导出, 工资条查看状态+工资流水导出, 辞职申请附件上传, 交接清单PDF下载, 操作完成下一步引导, 休假审批入口, 人效成本分部门
This commit is contained in:
@@ -1,9 +1,10 @@
|
||||
import { useState, useEffect } from 'react'
|
||||
import { toast } from 'sonner'
|
||||
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'
|
||||
import { Building2, Users, CreditCard, Plus, Bell, Download, Upload, FileSpreadsheet, Clock, CheckCircle, AlertCircle, ClipboardList } from 'lucide-react'
|
||||
import { Building2, Users, CreditCard, Plus, Bell, Download, Upload, FileSpreadsheet, Clock, CheckCircle, AlertCircle, ClipboardList, LayoutGrid } from 'lucide-react'
|
||||
import { settingsApi, notificationsApi } from '../lib/api-services'
|
||||
import { useAuthStore } from '../store/authStore'
|
||||
import { getPageSize, setPageSize as setGlobalPageSize } from '../lib/pageSize'
|
||||
import Card from '../components/ui/Card'
|
||||
import Button from '../components/ui/Button'
|
||||
import { Input, Label, Select } from '../components/ui/Input'
|
||||
@@ -13,7 +14,7 @@ import { useConfirm } from '../hooks/useConfirm'
|
||||
|
||||
export default function Settings() {
|
||||
const queryClient = useQueryClient()
|
||||
const [activeSection, setActiveSection] = useState<'org' | 'users' | 'plan' | 'notifications' | 'import' | 'export'>('org')
|
||||
const [activeSection, setActiveSection] = useState<'org' | 'users' | 'plan' | 'notifications' | 'import' | 'export' | 'display'>('org')
|
||||
|
||||
const { data: orgData } = useQuery<any>({
|
||||
queryKey: ['org-settings'],
|
||||
@@ -41,6 +42,7 @@ export default function Settings() {
|
||||
{ key: 'notifications' as const, label: '通知设置', icon: Bell },
|
||||
{ key: 'import' as const, label: '数据导入', icon: FileSpreadsheet },
|
||||
{ key: 'export' as const, label: '数据导出', icon: Download },
|
||||
{ key: 'display' as const, label: '显示设置', icon: LayoutGrid },
|
||||
]
|
||||
|
||||
return (
|
||||
@@ -78,12 +80,8 @@ export default function Settings() {
|
||||
{activeSection === 'plan' && <PlanSettings orgData={orgData} />}
|
||||
{activeSection === 'notifications' && <NotificationSettings />}
|
||||
{activeSection === 'import' && <ImportSettings />}
|
||||
{activeSection === 'export' && (
|
||||
<Card>
|
||||
<h2 className="text-sm font-medium mb-4">数据导出</h2>
|
||||
<ExportSettings />
|
||||
</Card>
|
||||
)}
|
||||
{activeSection === 'export' && <ExportSettings />}
|
||||
{activeSection === 'display' && <DisplaySettings />}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -705,7 +703,6 @@ function PlanSettings({ orgData }: { orgData: any }) {
|
||||
function NotificationSettings() {
|
||||
const queryClient = useQueryClient()
|
||||
const [form, setForm] = useState<any>({})
|
||||
const [checkResult, setCheckResult] = useState<string>('')
|
||||
|
||||
const { data: setting } = useQuery<any>({
|
||||
queryKey: ['notification-settings'],
|
||||
@@ -714,13 +711,6 @@ function NotificationSettings() {
|
||||
},
|
||||
})
|
||||
|
||||
const { data: logsData } = useQuery<any>({
|
||||
queryKey: ['notification-logs'],
|
||||
queryFn: async () => {
|
||||
return await notificationsApi.logs({ pageSize: 10 })
|
||||
},
|
||||
})
|
||||
|
||||
useEffect(() => {
|
||||
if (setting) setForm(setting)
|
||||
}, [setting])
|
||||
@@ -730,14 +720,6 @@ function NotificationSettings() {
|
||||
onSuccess: () => queryClient.invalidateQueries({ queryKey: ['notification-settings'] }),
|
||||
})
|
||||
|
||||
const checkMutation = useMutation({
|
||||
mutationFn: () => notificationsApi.checkContracts() as any,
|
||||
onSuccess: (res: any) => {
|
||||
setCheckResult(`检查完成:发现 ${res.data.checked} 个即将到期的合同,已发送 ${res.data.notified} 条通知`)
|
||||
queryClient.invalidateQueries({ queryKey: ['notification-logs'] })
|
||||
},
|
||||
})
|
||||
|
||||
const testWechatMutation = useMutation({
|
||||
mutationFn: () => notificationsApi.test('wechat') as any,
|
||||
onSuccess: (res: any) => {
|
||||
@@ -752,8 +734,6 @@ function NotificationSettings() {
|
||||
},
|
||||
})
|
||||
|
||||
const logs = logsData?.items || []
|
||||
|
||||
return (
|
||||
<div className="space-y-3">
|
||||
<Card>
|
||||
@@ -830,31 +810,6 @@ function NotificationSettings() {
|
||||
</Button>
|
||||
</div>
|
||||
</Card>
|
||||
|
||||
<Card>
|
||||
<div className="flex items-center justify-between mb-4">
|
||||
<h2 className="text-sm font-medium">合同到期检查</h2>
|
||||
<Button size="sm" onClick={() => checkMutation.mutate()} disabled={checkMutation.isPending}>
|
||||
{checkMutation.isPending ? '检查中...' : '立即检查'}
|
||||
</Button>
|
||||
</div>
|
||||
{checkResult && (
|
||||
<div className="px-3 py-2 rounded-md bg-blue-50 text-blue-700 text-xs mb-3">{checkResult}</div>
|
||||
)}
|
||||
{logs.length > 0 ? (
|
||||
<div className="space-y-2">
|
||||
{logs.map((log: any) => (
|
||||
<div key={log.id} className="text-xs border-b last:border-0 py-2">
|
||||
<div className="font-medium">{log.title}</div>
|
||||
<div className="text-gray-500 text-xs mt-0.5">{log.content}</div>
|
||||
<div className="text-gray-500 text-xs mt-0.5">{new Date(log.createdAt).toLocaleString('zh-CN')}</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
) : (
|
||||
<div className="text-gray-500 text-xs text-center py-4">暂无通知记录</div>
|
||||
)}
|
||||
</Card>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -1335,3 +1290,33 @@ function MonthlyImport() {
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
function DisplaySettings() {
|
||||
const [size, setSize] = useState(getPageSize())
|
||||
|
||||
const handleSave = () => {
|
||||
setGlobalPageSize(size)
|
||||
toast.success(`分页大小已设置为 ${size} 条/页`)
|
||||
}
|
||||
|
||||
return (
|
||||
<Card>
|
||||
<h2 className="text-sm font-medium mb-4">显示设置</h2>
|
||||
<div className="space-y-4">
|
||||
<div>
|
||||
<Label>列表分页大小</Label>
|
||||
<p className="text-xs text-gray-500 mt-1 mb-2">设置所有列表页面每页显示的记录条数,保存后立即生效</p>
|
||||
<div className="flex items-center gap-3">
|
||||
<Select value={String(size)} onChange={(e) => setSize(parseInt(e.target.value, 10))} className="!w-32">
|
||||
<option value="10">10 条/页</option>
|
||||
<option value="20">20 条/页</option>
|
||||
<option value="50">50 条/页</option>
|
||||
<option value="100">100 条/页</option>
|
||||
</Select>
|
||||
<Button size="sm" onClick={handleSave}>保存</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user