package repo import ( "admin/apps/user/domain/entity" "admin/apps/user/model" "admin/apps/user/model/dto" "admin/internal/errcode" "admin/lib/passlib" "admin/lib/xlog" "errors" "gorm.io/gorm" "reflect" ) type ICommonResourceRepo interface { List(pageNo, pageLen int, extraQuery string, args ...any) ([]*dto.CommonDtoFieldDesc, []*entity.CommonResource, error) GetById(id int) ([]*dto.CommonDtoFieldDesc, *entity.CommonResource, bool, error) Create(et dto.CommonDtoValues) (*entity.CommonResource, error) Edit(et dto.CommonDtoValues) error Delete(id int) (*entity.CommonResource, bool, error) } func NewCommonResourceRepo(db *gorm.DB, poTemplate model.IModel) ICommonResourceRepo { return newCommonResourceRepoImpl(db, poTemplate) } type commonResourceRepoImpl struct { db *gorm.DB poTemplate model.IModel fieldsDescInfoFun func() []*dto.CommonDtoFieldDesc } func newCommonResourceRepoImpl(db *gorm.DB, poTemplate model.IModel) *commonResourceRepoImpl { fieldsInfo := (&entity.CommonResource{}).FromPo(poTemplate).GetDtoFieldsDescInfo return &commonResourceRepoImpl{db: db, poTemplate: poTemplate, fieldsDescInfoFun: fieldsInfo} } func (repo *commonResourceRepoImpl) List(pageNo, pageLen int, extraQuery string, args ...any) ([]*dto.CommonDtoFieldDesc, []*entity.CommonResource, error) { listType := reflect.New(reflect.SliceOf(reflect.TypeOf(repo.poTemplate))) var err error if extraQuery == "" { err = repo.db.Find(listType.Interface()).Error } else { err = repo.db.Where(extraQuery, args...).Find(listType.Interface()).Error } if err != nil { return nil, nil, errcode.New(errcode.DBError, "list resource %v error:%v", repo.poTemplate.TableName(), err) } listType1 := listType.Elem() listLen := listType1.Len() entityList := make([]*entity.CommonResource, 0, listLen) for i := 0; i < listType1.Len(); i++ { po := listType1.Index(i).Interface().(model.IModel) et := &entity.CommonResource{} et.FromPo(po) entityList = append(entityList, et) } return repo.fieldsDescInfoFun(), entityList, nil } func (repo *commonResourceRepoImpl) GetById(id int) ([]*dto.CommonDtoFieldDesc, *entity.CommonResource, bool, error) { po := repo.newEmptyPo() err := repo.db.Where("id = ?", id).First(po).Error if err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { return repo.fieldsDescInfoFun(), (&entity.CommonResource{}).FromPo(repo.newEmptyPo()), false, nil } return nil, nil, false, errcode.New(errcode.DBError, "get resource:%v by id:%v error:%v", repo.poTemplate.TableName(), id, err) } return repo.fieldsDescInfoFun(), (&entity.CommonResource{}).FromPo(po), true, nil } func (repo *commonResourceRepoImpl) Create(dtoObj dto.CommonDtoValues) (*entity.CommonResource, error) { if pass, find := dtoObj["UserPass"]; find { dtoObj["UserPass"] = passlib.EncryptPassword(pass.(string)) } et := (&entity.CommonResource{}).FromPo(repo.newEmptyPo()).FromDto(dtoObj) err := repo.db.Create(et.Po).Error if err != nil { return et, errcode.New(errcode.DBError, "create resource:%v obj:%+v error:%v", repo.poTemplate.TableName(), et, err) } return et, nil } func (repo *commonResourceRepoImpl) Edit(dtoObj dto.CommonDtoValues) error { xlog.Infof("update obj:%+v", dtoObj) if pass, find := dtoObj["UserPass"]; find { if pass.(string) == "***" { // 没有改密码 delete(dtoObj, "UserPass") } else { dtoObj["UserPass"] = passlib.EncryptPassword(pass.(string)) } } et := (&entity.CommonResource{}).FromPo(repo.newEmptyPo()).FromDto(dtoObj) err := repo.db.Where("id=?", et.Po.GetId()).Updates(et.Po).Error if err != nil { return errcode.New(errcode.DBError, "edit resource:%v obj:%+v error:%v", repo.poTemplate.TableName(), et, err) } return nil } func (repo *commonResourceRepoImpl) Delete(id int) (*entity.CommonResource, bool, error) { _, et, find, err := repo.GetById(id) if err != nil { return nil, false, err } if !find { return et, false, nil } err = repo.db.Where("id=?", id).Unscoped().Delete(repo.poTemplate).Error if err != nil { return nil, false, errcode.New(errcode.DBError, "delete resource:%v obj:%+v error:%v", repo.poTemplate.TableName(), id, err) } return et, true, nil } func (repo *commonResourceRepoImpl) newEmptyPo() model.IModel { return reflect.New(reflect.TypeOf(repo.poTemplate).Elem()).Interface().(model.IModel) }