Add aftersales stats to dashboard and service-layer tests
- CompanyStatsOverviewDTO and GetStats() now include aftersales counts (total, pending confirmation, closed, rejected) and a recentAftersales list - aftersales_service_test.go covers YYMMNN sequence, owner-only submit, state machine, phone last-4 check, reject increment, force-close - users_service_test.go covers duplicate username, self-demotion guard, last-admin guard, password reset, assignable filter Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -317,6 +317,11 @@ func (s *CompaniesService) GetStats() (map[string]any, error) {
|
||||
return nil, errors.New("查询员工序列号统计失败")
|
||||
}
|
||||
|
||||
var aftersales []models.AftersalesOrder
|
||||
if err := database.DB.Preload("Technician").Order("created_at DESC").Find(&aftersales).Error; err != nil {
|
||||
return nil, errors.New("查询售后工单统计失败")
|
||||
}
|
||||
|
||||
companyCount := len(companies)
|
||||
serialCount := len(serials)
|
||||
employeeSerialCount := len(employeeSerials)
|
||||
@@ -392,6 +397,41 @@ func (s *CompaniesService) GetStats() (map[string]any, error) {
|
||||
recentSerials = recentSerials[:10]
|
||||
}
|
||||
|
||||
aftersalesTotal := len(aftersales)
|
||||
aftersalesPending := 0
|
||||
aftersalesClosed := 0
|
||||
aftersalesRejected := 0
|
||||
for _, o := range aftersales {
|
||||
switch o.WorkOrderStatus {
|
||||
case "pending_confirmation":
|
||||
aftersalesPending++
|
||||
case "closed":
|
||||
aftersalesClosed++
|
||||
case "rejected":
|
||||
aftersalesRejected++
|
||||
}
|
||||
}
|
||||
|
||||
recentAftersales := make([]map[string]any, 0)
|
||||
for i, order := range aftersales {
|
||||
if i >= 10 {
|
||||
break
|
||||
}
|
||||
technicianName := ""
|
||||
if order.Technician != nil {
|
||||
technicianName = order.Technician.Name
|
||||
}
|
||||
recentAftersales = append(recentAftersales, map[string]any{
|
||||
"serialNumber": order.SerialNumber,
|
||||
"companyName": order.CompanyName,
|
||||
"serviceType": order.ServiceType,
|
||||
"workOrderStatus": order.WorkOrderStatus,
|
||||
"authorizationStatus": order.AuthorizationStatus,
|
||||
"technicianName": technicianName,
|
||||
"createdAt": order.CreatedAt,
|
||||
})
|
||||
}
|
||||
|
||||
return map[string]any{
|
||||
"overview": map[string]any{
|
||||
"totalCompanies": companyCount,
|
||||
@@ -399,10 +439,15 @@ func (s *CompaniesService) GetStats() (map[string]any, error) {
|
||||
"totalEmployeeSerials": employeeSerialCount,
|
||||
"activeSerials": activeCount,
|
||||
"inactiveSerials": inactiveCount,
|
||||
"totalAftersales": aftersalesTotal,
|
||||
"pendingConfirmation": aftersalesPending,
|
||||
"closedAftersales": aftersalesClosed,
|
||||
"rejectedAftersales": aftersalesRejected,
|
||||
},
|
||||
"monthlyStats": monthlyItems,
|
||||
"recentCompanies": recentCompanies,
|
||||
"recentSerials": recentSerials,
|
||||
"monthlyStats": monthlyItems,
|
||||
"recentCompanies": recentCompanies,
|
||||
"recentSerials": recentSerials,
|
||||
"recentAftersales": recentAftersales,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -440,5 +485,18 @@ func (s *CompaniesService) GetStatsOverview() (*models.CompanyStatsOverviewDTO,
|
||||
|
||||
stats.RevokedEmployeeSerials = stats.TotalEmployeeSerials - stats.ActiveEmployeeSerials
|
||||
|
||||
if err := database.DB.Model(&models.AftersalesOrder{}).Count(&stats.TotalAftersales).Error; err != nil {
|
||||
return nil, errors.New("统计售后工单总数失败")
|
||||
}
|
||||
if err := database.DB.Model(&models.AftersalesOrder{}).Where("work_order_status = ?", "pending_confirmation").Count(&stats.PendingConfirmation).Error; err != nil {
|
||||
return nil, errors.New("统计待客户确认工单失败")
|
||||
}
|
||||
if err := database.DB.Model(&models.AftersalesOrder{}).Where("work_order_status = ?", "closed").Count(&stats.ClosedAftersales).Error; err != nil {
|
||||
return nil, errors.New("统计已完成工单失败")
|
||||
}
|
||||
if err := database.DB.Model(&models.AftersalesOrder{}).Where("work_order_status = ?", "rejected").Count(&stats.RejectedAftersales).Error; err != nil {
|
||||
return nil, errors.New("统计已退回工单失败")
|
||||
}
|
||||
|
||||
return stats, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user