修复工作人员作业预检状态与提示

This commit is contained in:
czl231
2026-09-05 20:17:07 +08:00
parent 1670d5880f
commit cec02c8887
8 changed files with 191 additions and 12 deletions

View File

@@ -70,12 +70,10 @@ func Preflight(ctx *gin.Context) {
return
}
var credential models.StaffCredential
credentialFound := impl.DBService.
Where("staff_account_id = ? AND status = ?", account.ID, common.StatusEnable).
Order("expired_at desc").
First(&credential).Error == nil
credentialValid := credentialFound && (credential.ExpiredAt == nil || credential.ExpiredAt.After(time.Now()))
var credentials []models.StaffCredential
_ = impl.DBService.Where("staff_account_id = ? AND status <> ?", account.ID, common.StatusArchived).
Order("created_at desc").Find(&credentials).Error
credential, credentialValid, credentialReason := evaluateCredential(credentials, time.Now())
organizationIdentity, organizationName, organizationType := "", "", ""
if account.DeliveryBasicID != 0 {
@@ -94,7 +92,7 @@ func Preflight(ctx *gin.Context) {
"account": gin.H{"status": "passed"},
"role": gin.H{"status": "passed", "role_code": account.RoleCode},
"organization": gin.H{"status": checkStatus(organizationIdentity != ""), "identity": organizationIdentity, "name": organizationName, "type": organizationType},
"credential": gin.H{"status": checkStatus(credentialValid), "expired_at": credential.ExpiredAt},
"credential": gin.H{"status": checkStatus(credentialValid), "reason": credentialReason, "credential_type": credential.CredentialType, "expired_at": credential.ExpiredAt},
"attendance": gin.H{"status": checkStatus(account.WorkStatus == "on_duty"), "work_status": account.WorkStatus},
"daily_training": gin.H{"status": "not_configured"},
"service_area": gin.H{"status": "not_configured"},
@@ -107,6 +105,29 @@ func Preflight(ctx *gin.Context) {
})
}
// evaluateCredential 返回最适合作为提示依据的资质及稳定原因码。
func evaluateCredential(credentials []models.StaffCredential, now time.Time) (models.StaffCredential, bool, string) {
var expired models.StaffCredential
for _, credential := range credentials {
if credential.Status != common.StatusEnable {
continue
}
if credential.ExpiredAt == nil || credential.ExpiredAt.After(now) {
return credential, true, "valid"
}
if expired.ID == 0 || (credential.ExpiredAt != nil && expired.ExpiredAt != nil && credential.ExpiredAt.After(*expired.ExpiredAt)) {
expired = credential
}
}
if expired.ID != 0 {
return expired, false, "expired"
}
if len(credentials) > 0 {
return credentials[0], false, "disabled"
}
return models.StaffCredential{}, false, "missing"
}
func checkStatus(passed bool) string {
if passed {
return "passed"

View File

@@ -0,0 +1,36 @@
// 功能描述:验证工作人员资质预检原因判定。
// 版本1.0.0
package staff
import (
"testing"
"time"
common "git.apinb.com/heqiapp/platforms/backend/api/internal/logic/common"
"git.apinb.com/heqiapp/platforms/backend/api/internal/models"
)
// TestEvaluateCredential 验证缺失、停用、过期和有效资质均返回稳定原因码。
func TestEvaluateCredential(t *testing.T) {
now := time.Date(2026, 9, 5, 12, 0, 0, 0, time.UTC)
past, future := now.Add(-time.Hour), now.Add(time.Hour)
tests := []struct {
name string
credentials []models.StaffCredential
valid bool
reason string
}{
{name: "缺失", reason: "missing"},
{name: "停用", credentials: []models.StaffCredential{{Entity: models.Entity{ID: 1, Status: common.StatusDisable}}}, reason: "disabled"},
{name: "过期", credentials: []models.StaffCredential{{Entity: models.Entity{ID: 2, Status: common.StatusEnable}, ExpiredAt: &past}}, reason: "expired"},
{name: "有效", credentials: []models.StaffCredential{{Entity: models.Entity{ID: 3, Status: common.StatusEnable}, ExpiredAt: &future}}, valid: true, reason: "valid"},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
_, valid, reason := evaluateCredential(test.credentials, now)
if valid != test.valid || reason != test.reason {
t.Fatalf("valid=%v reason=%q期望 valid=%v reason=%q", valid, reason, test.valid, test.reason)
}
})
}
}

View File

@@ -602,6 +602,15 @@ func seedAdditionalCoreScenarios(database *gorm.DB, passwordHash string, now tim
return err
}
// 为每组模拟工作人员补齐独立有效资质,保证预检数据与在岗状态一致。
credential := models.StaffCredential{
Entity: entity(sequence+21, common.StatusEnable), StaffAccountID: staff.ID,
CredentialType: "delivery", CredentialNo: "MOCK-CERT-" + suffix, ExpiredAt: &nextYear,
}
if err := put(database, &credential); err != nil {
return err
}
user := models.UserAccount{
Entity: entity(sequence+4, common.StatusEnable), Username: "mock_customer_" + suffix,
PasswordHash: passwordHash, Name: fmt.Sprintf("示例客户%d", scenario), Phone: "138" + phoneSuffix,