package data import ( "context" "errors" "time" "gorm.io/gorm" "kra/internal/biz" ) type adminPO struct { ID int64 `gorm:"primaryKey;autoIncrement"` Name string `gorm:"uniqueIndex"` Email string `gorm:"uniqueIndex"` Password string Access string Avatar string CreateTime time.Time UpdateTime time.Time } func (adminPO) TableName() string { return "admins" } func convertAdmin(po *adminPO) *biz.Admin { return &biz.Admin{ID: po.ID, Name: po.Name, Email: po.Email, Password: po.Password, Access: po.Access, Avatar: po.Avatar, CreateTime: po.CreateTime, UpdateTime: po.UpdateTime} } type adminRepo struct{ data *Data } func NewAdminRepo(data *Data) biz.AdminRepo { return &adminRepo{data: data} } func (r *adminRepo) one(ctx context.Context, query *gorm.DB) (*biz.Admin, error) { var po adminPO if err := query.WithContext(ctx).First(&po).Error; err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { return nil, biz.ErrAdminNotFound } return nil, err } return convertAdmin(&po), nil } func (r *adminRepo) FindByID(ctx context.Context, id int64) (*biz.Admin, error) { return r.one(ctx, r.data.gormDB.Where("id = ?", id)) } func (r *adminRepo) FindByName(ctx context.Context, name string) (*biz.Admin, error) { return r.one(ctx, r.data.gormDB.Where("name = ?", name)) } func (r *adminRepo) FindByEmail(ctx context.Context, email string) (*biz.Admin, error) { return r.one(ctx, r.data.gormDB.Where("email = ?", email)) } func (r *adminRepo) ListAdmins(ctx context.Context, opts ...biz.ListOption) ([]*biz.Admin, error) { o := biz.ListOptions{Limit: 20} for _, opt := range opts { opt(&o) } var pos []adminPO if err := r.data.gormDB.WithContext(ctx).Offset(o.Offset).Limit(o.Limit).Order("id asc").Find(&pos).Error; err != nil { return nil, err } out := make([]*biz.Admin, 0, len(pos)) for i := range pos { out = append(out, convertAdmin(&pos[i])) } return out, nil } func (r *adminRepo) CreateAdmin(ctx context.Context, a *biz.Admin) (*biz.Admin, error) { now := time.Now() po := adminPO{Name: a.Name, Email: a.Email, Password: a.Password, Access: a.Access, Avatar: a.Avatar, CreateTime: now, UpdateTime: now} if err := r.data.gormDB.WithContext(ctx).Create(&po).Error; err != nil { return nil, err } return convertAdmin(&po), nil } func (r *adminRepo) UpdateAdmin(ctx context.Context, a *biz.Admin) (*biz.Admin, error) { values := map[string]any{"name": a.Name, "email": a.Email, "access": a.Access, "avatar": a.Avatar, "update_time": time.Now()} if a.Password != "" { values["password"] = a.Password } if err := r.data.gormDB.WithContext(ctx).Model(&adminPO{}).Where("id = ?", a.ID).Updates(values).Error; err != nil { return nil, err } return r.FindByID(ctx, a.ID) } func (r *adminRepo) DeleteAdmin(ctx context.Context, id int64) error { return r.data.gormDB.WithContext(ctx).Delete(&adminPO{}, id).Error }