后台用户管理新增“人工实名

This commit is contained in:
yml2213
2026-06-28 01:06:35 +08:00
parent 21aabd77f1
commit 18eba36ef9
12 changed files with 453 additions and 16 deletions
@@ -1,9 +1,12 @@
package adminuser
import (
"errors"
"strings"
"testing"
"hfb_sys/backend/internal/model"
"gorm.io/driver/sqlite"
"gorm.io/gorm"
)
@@ -76,3 +79,106 @@ func TestApplyUserFilterHasDepositFreeQuota(t *testing.T) {
t.Fatalf("筛选变量不正确:%v", stmt.Vars)
}
}
func TestManualRealnameUpdatesUserRecordAndAudit(t *testing.T) {
db := setupAdminUserTestDB(t)
user := model.User{
Phone: "13900000001",
Nickname: "待实名用户",
RealnameStatus: "rejected",
Status: "active",
}
if err := db.Create(&user).Error; err != nil {
t.Fatalf("创建用户失败:%v", err)
}
repo := NewRepository(db)
got, err := repo.ManualRealname(t.Context(), 99, user.ID, ManualRealnameRequest{
Name: "周奕男",
IDNo: "130682200604080615",
Reason: "第三方服务异常,客服人工核验通过",
}, AuditMeta{IP: "127.0.0.1", UserAgent: "test", RequestID: "req-1"})
if err != nil {
t.Fatalf("ManualRealname() error = %v", err)
}
if got.RealnameStatus != "verified" {
t.Fatalf("用户实名状态 = %s, want verified", got.RealnameStatus)
}
var savedUser model.User
if err := db.First(&savedUser, user.ID).Error; err != nil {
t.Fatalf("查询用户失败:%v", err)
}
if savedUser.RealnameStatus != "verified" {
t.Fatalf("数据库用户实名状态 = %s, want verified", savedUser.RealnameStatus)
}
var record model.UserRealname
if err := db.Where("user_id = ?", user.ID).First(&record).Error; err != nil {
t.Fatalf("查询实名记录失败:%v", err)
}
if record.Provider != "admin_manual" || record.Status != "verified" {
t.Fatalf("实名记录不正确:provider=%s status=%s", record.Provider, record.Status)
}
if record.MaskedName != "周**" || record.MaskedIDNo != "1306**********0615" {
t.Fatalf("脱敏信息不正确:name=%s id=%s", record.MaskedName, record.MaskedIDNo)
}
if record.EncryptedName != "周奕男" || record.EncryptedIDNo != "130682200604080615" {
t.Fatalf("加密字段未写入:name=%s id=%s", record.EncryptedName, record.EncryptedIDNo)
}
if record.VerifiedAt == nil {
t.Fatal("VerifiedAt 不能为空")
}
var audit model.AuditLog
if err := db.Where("action = ?", "admin_user.manual_realname").First(&audit).Error; err != nil {
t.Fatalf("查询审计日志失败:%v", err)
}
if audit.ActorID != 99 || audit.BizID == nil || *audit.BizID != user.ID {
t.Fatalf("审计日志主体不正确:actor=%d biz=%v", audit.ActorID, audit.BizID)
}
if strings.Contains(string(audit.Detail), "130682200604080615") {
t.Fatalf("审计日志不应包含完整身份证号:%s", string(audit.Detail))
}
}
func TestManualRealnameRejectsVerifiedUser(t *testing.T) {
db := setupAdminUserTestDB(t)
user := model.User{
Phone: "13900000002",
Nickname: "已实名用户",
RealnameStatus: "verified",
Status: "active",
}
if err := db.Create(&user).Error; err != nil {
t.Fatalf("创建用户失败:%v", err)
}
repo := NewRepository(db)
_, err := repo.ManualRealname(t.Context(), 99, user.ID, ManualRealnameRequest{
Name: "周奕男",
IDNo: "130682200604080615",
}, AuditMeta{})
if !errors.Is(err, ErrRealnameAlreadyVerified) {
t.Fatalf("ManualRealname() error = %v, want ErrRealnameAlreadyVerified", err)
}
}
func setupAdminUserTestDB(t *testing.T) *gorm.DB {
t.Helper()
db, err := gorm.Open(sqlite.Open(":memory:"), &gorm.Config{})
if err != nil {
t.Fatalf("打开测试数据库失败:%v", err)
}
if err := db.AutoMigrate(
&model.User{},
&model.UserRealname{},
&model.AuditLog{},
&model.RentalOrder{},
&model.RentalListing{},
&model.Dispute{},
); err != nil {
t.Fatalf("数据库迁移失败:%v", err)
}
return db
}