feat: Dashboard 合同卡片显示有效合同数 + 总合同数
This commit is contained in:
@@ -20,11 +20,20 @@ router.use(authMiddleware, platformAdminMiddleware)
|
|||||||
*/
|
*/
|
||||||
router.get('/dashboard', async (_req: AuthRequest, res, next) => {
|
router.get('/dashboard', async (_req: AuthRequest, res, next) => {
|
||||||
try {
|
try {
|
||||||
const [orgs, users, employees, contracts, payslips] = await Promise.all([
|
const now = new Date()
|
||||||
|
const [orgs, users, employees, contracts, activeContracts, payslips] = await Promise.all([
|
||||||
prisma.organization.count(),
|
prisma.organization.count(),
|
||||||
prisma.user.count({ where: { role: { not: 'SUPER_ADMIN' } } }),
|
prisma.user.count({ where: { role: { not: 'SUPER_ADMIN' } } }),
|
||||||
prisma.employee.count(),
|
prisma.employee.count(),
|
||||||
prisma.laborContract.count(),
|
prisma.laborContract.count(),
|
||||||
|
prisma.laborContract.count({
|
||||||
|
where: {
|
||||||
|
OR: [
|
||||||
|
{ endDate: null },
|
||||||
|
{ endDate: { gte: now } },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
}),
|
||||||
prisma.payslip.count(),
|
prisma.payslip.count(),
|
||||||
])
|
])
|
||||||
|
|
||||||
@@ -52,6 +61,7 @@ router.get('/dashboard', async (_req: AuthRequest, res, next) => {
|
|||||||
totalUsers: users,
|
totalUsers: users,
|
||||||
totalEmployees: employees,
|
totalEmployees: employees,
|
||||||
totalContracts: contracts,
|
totalContracts: contracts,
|
||||||
|
activeContracts,
|
||||||
totalPayslips: payslips,
|
totalPayslips: payslips,
|
||||||
orgsByPlan: orgsByPlan.map((g: any) => ({ plan: g.plan, count: g._count })),
|
orgsByPlan: orgsByPlan.map((g: any) => ({ plan: g.plan, count: g._count })),
|
||||||
recentOrgs: recentOrgs.map((o: any) => ({
|
recentOrgs: recentOrgs.map((o: any) => ({
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ interface DashboardData {
|
|||||||
totalUsers: number
|
totalUsers: number
|
||||||
totalEmployees: number
|
totalEmployees: number
|
||||||
totalContracts: number
|
totalContracts: number
|
||||||
|
activeContracts: number
|
||||||
totalPayslips: number
|
totalPayslips: number
|
||||||
orgsByPlan: { plan: string; count: number }[]
|
orgsByPlan: { plan: string; count: number }[]
|
||||||
recentOrgs: {
|
recentOrgs: {
|
||||||
@@ -38,7 +39,7 @@ export default function PlatformDashboard() {
|
|||||||
{ label: '企业总数', value: data.totalOrgs, icon: Building2, color: 'text-primary' },
|
{ label: '企业总数', value: data.totalOrgs, icon: Building2, color: 'text-primary' },
|
||||||
{ label: '用户总数', value: data.totalUsers, icon: Users, color: 'text-blue-600' },
|
{ label: '用户总数', value: data.totalUsers, icon: Users, color: 'text-blue-600' },
|
||||||
{ label: '员工总数', value: data.totalEmployees, icon: Users, color: 'text-emerald-600' },
|
{ label: '员工总数', value: data.totalEmployees, icon: Users, color: 'text-emerald-600' },
|
||||||
{ label: '合同总数', value: data.totalContracts, icon: FileText, color: 'text-purple-600' },
|
{ label: '有效合同', value: data.activeContracts, sub: `共 ${data.totalContracts} 份`, icon: FileText, color: 'text-purple-600' },
|
||||||
{ label: '工资条总数', value: data.totalPayslips, icon: Calculator, color: 'text-rose-600' },
|
{ label: '工资条总数', value: data.totalPayslips, icon: Calculator, color: 'text-rose-600' },
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -60,6 +61,7 @@ export default function PlatformDashboard() {
|
|||||||
<Icon className={`w-5 h-5 ${s.color}`} />
|
<Icon className={`w-5 h-5 ${s.color}`} />
|
||||||
</div>
|
</div>
|
||||||
<div className="text-2xl font-bold text-gray-900">{s.value.toLocaleString()}</div>
|
<div className="text-2xl font-bold text-gray-900">{s.value.toLocaleString()}</div>
|
||||||
|
{(s as any).sub && <div className="text-xs text-gray-400 mt-0.5">{(s as any).sub}</div>}
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
})}
|
})}
|
||||||
|
|||||||
Reference in New Issue
Block a user