组织列表接口

This commit is contained in:
guosl 2024-07-30 12:03:23 +08:00
parent 62d5b5f9b3
commit b4956ea2be
8 changed files with 114 additions and 45 deletions

View File

@ -3,15 +3,15 @@ package organization
import "time" import "time"
type Organization struct { type Organization struct {
ID uint `json:"id"` // id ID uint `json:"id"` // id
Name string `json:"name"` // 组织名 Name string `json:"name"` // 组织名
ParentID uint `json:"parent_id"` // 上级组织id ParentID uint `json:"parent_id"` // 上级组织id
Sort uint `json:"sort"` // 层级序号 Sort uint `json:"sort"` // 层级序号
Status int `json:"status"` // 状态:0-无效,1-有效 Status int `json:"status"` // 状态:0-无效,1-有效
Path string `json:"path"` // 全路径 Path string `json:"path"` // 全路径
Leaders []string `json:"leaders"` Leaders []string `json:"leaders"`
CreatedOn time.Time `json:"created_on"` // 记录创建时间 CreatedOn time.Time `json:"created_on"` // 记录创建时间
Children []Organization `json:"children"` Children []*Organization `json:"children"`
} }
type OrgTree []Organization type OrgTree []*Organization

View File

@ -2,8 +2,8 @@ package organization
type CreateOrgReq struct { type CreateOrgReq struct {
Name string `json:"name" binding:"required"` Name string `json:"name" binding:"required"`
ParentId uint `json:"parent_id" binding:"required"` ParentId uint `json:"parent_id"`
Sort int `json:"sort" binding:"required"` Sort int `json:"sort"`
Leaders []string `json:"leaders"` Leaders []string `json:"leaders"`
} }
@ -12,7 +12,7 @@ type DelOrgReq struct {
} }
type GetOrgReq struct { type GetOrgReq struct {
Id uint `from:"id" json:"id" binding:"required"` Id uint `form:"id" json:"id" binding:"required"`
} }
type MoveOrgReq struct { type MoveOrgReq struct {
@ -23,8 +23,8 @@ type MoveOrgReq struct {
type SaveOrgReq struct { type SaveOrgReq struct {
Id uint `json:"id" binding:"required"` Id uint `json:"id" binding:"required"`
Name string `json:"name" binding:"required"` Name string `json:"name" binding:"required"`
ParentId uint `json:"parent_id" binding:"required"` ParentId uint `json:"parent_id" `
Sort int `json:"sort" binding:"required"` Sort int `json:"sort" `
Leaders []string `json:"leaders"` Leaders []string `json:"leaders"`
} }

View File

@ -44,7 +44,7 @@ type OrganizationRepo interface{
Save(ctx context.Context,org Organization)(error) Save(ctx context.Context,org Organization)(error)
GetById(ctx context.Context,id uint)(org Organization,err error) GetById(ctx context.Context,id uint)(org Organization,err error)
DelById(ctx context.Context,id uint)(err error) DelById(ctx context.Context,id uint)(err error)
GetOrgs(ctx context.Context)(org []Organization,err error) GetOrgs(ctx context.Context)(org []*Organization,err error)
ExistOrgId(ctx context.Context,id uint)(bool,error) ExistOrgId(ctx context.Context,id uint)(bool,error)
SetStatus(ctx context.Context,id uint,status OrganizationStatus)error SetStatus(ctx context.Context,id uint,status OrganizationStatus)error
} }
@ -60,7 +60,7 @@ func NewOrganization(i *do.Injector)(OrganizationRepo,error){
} }
func (o *orginizationRepo)Create(ctx context.Context,org Organization)(id uint,err error){ func (o *orginizationRepo)Create(ctx context.Context,org Organization)(id uint,err error){
err = o.db.Create(org).Error err = o.db.Create(&org).Error
id = org.ID id = org.ID
return return
} }
@ -75,24 +75,24 @@ func (o *orginizationRepo)GetById(ctx context.Context,id uint)(org Organization,
} }
func (o *orginizationRepo)DelById(ctx context.Context,id uint)(err error){ func (o *orginizationRepo)DelById(ctx context.Context,id uint)(err error){
return o.db.Where("id = ?",id).Delete(&Organization{}).Error return o.db.Model(Organization{}).Where("id = ?",id).Delete(&Organization{}).Error
} }
func (o *orginizationRepo)GetOrgs(ctx context.Context)(orgs []Organization,err error){ func (o *orginizationRepo)GetOrgs(ctx context.Context)(orgs []*Organization,err error){
err = o.db.Model(&Organization{}).Find(&orgs).Error err = o.db.Model(&Organization{}).Find(&orgs).Error
return return
} }
func (o *orginizationRepo)ExistOrgId(ctx context.Context,id uint)(bool,error){ func (o *orginizationRepo)ExistOrgId(ctx context.Context,id uint)(bool,error){
var count int64 = 0 var count int64 = 0
err := o.db.Where("id = ?",id).Count(&count).Error err := o.db.Model(Organization{}).Where("id = ?",id).Count(&count).Error
if count >0{ if count >0{
return false,err return true,err
} }
return true,err return false,err
} }
func (o *orginizationRepo)SetStatus(ctx context.Context,id uint,status OrganizationStatus)error{ func (o *orginizationRepo)SetStatus(ctx context.Context,id uint,status OrganizationStatus)error{
return o.db.Where("id = ?",id).Update("status",status).Error return o.db.Model(Organization{}).Where("id = ?",id).Update("status",status).Error
} }

View File

@ -6,8 +6,11 @@ import (
"busniess-user-center/internal/repo" "busniess-user-center/internal/repo"
"busniess-user-center/pkg/redis" "busniess-user-center/pkg/redis"
"context" "context"
"encoding/json"
"fmt" "fmt"
"busniess-user-center/internal/service/user"
"github.com/jinzhu/copier" "github.com/jinzhu/copier"
"github.com/samber/do" "github.com/samber/do"
"go.uber.org/zap" "go.uber.org/zap"
@ -19,18 +22,20 @@ func init() {
} }
type organizationService struct { type organizationService struct {
logger *zap.SugaredLogger logger *zap.SugaredLogger
orgRepo repo.OrganizationRepo orgRepo repo.OrganizationRepo
redis *redis.Redis redis *redis.Redis
conf *config.AppConfig conf *config.AppConfig
userService user.UserService
} }
func NewOrganizationService(i *do.Injector) (OrganizationService, error) { func NewOrganizationService(i *do.Injector) (OrganizationService, error) {
return &organizationService{ return &organizationService{
logger: do.MustInvoke[*zap.SugaredLogger](i), logger: do.MustInvoke[*zap.SugaredLogger](i),
orgRepo: do.MustInvoke[repo.OrganizationRepo](i), orgRepo: do.MustInvoke[repo.OrganizationRepo](i),
redis: do.MustInvoke[*redis.Redis](i), redis: do.MustInvoke[*redis.Redis](i),
conf: do.MustInvoke[*config.AppConfig](i), conf: do.MustInvoke[*config.AppConfig](i),
userService: do.MustInvoke[user.UserService](i),
}, nil }, nil
} }
@ -43,11 +48,22 @@ func (o *organizationService) CreateOrganization(ctx context.Context, info *orgM
} }
} }
leader := "[]"
if len(info.Leaders) > 0 {
if err := o.verfyUsers(ctx, info.Leaders); err != nil {
return err
}
leaderByte, _ := json.Marshal(info.Leaders)
leader = string(leaderByte)
}
dbOrg := repo.Organization{ dbOrg := repo.Organization{
Name: info.Name, Name: info.Name,
ParentID: info.ParentId, ParentID: info.ParentId,
Sort: uint(info.Sort), Sort: uint(info.Sort),
Status: int(repo.OrganizationEnableStatus), Status: int(repo.OrganizationEnableStatus),
Leaders: leader,
} }
_, err := o.orgRepo.Create(ctx, dbOrg) _, err := o.orgRepo.Create(ctx, dbOrg)
@ -65,8 +81,31 @@ func (o *organizationService) SaveOrganization(ctx context.Context, info *orgMod
return fmt.Errorf("组织不存在") return fmt.Errorf("组织不存在")
} }
dbOrg.Name = info.Name newOrg := repo.Organization{}
err = o.orgRepo.Save(ctx, dbOrg) copier.Copy(&newOrg, dbOrg)
newOrg.Name = info.Name
newOrg.Sort = uint(info.Sort)
if info.ParentId > 0 {
if exist, err := o.orgRepo.ExistOrgId(ctx, info.ParentId); err != nil {
return err
} else if !exist {
return fmt.Errorf("父组织%d不存在", info.ParentId)
}
newOrg.ParentID = info.ParentId
}
if len(info.Leaders) > 0 {
if err := o.verfyUsers(ctx, info.Leaders); err != nil {
return err
}
leaderByte, _ := json.Marshal(info.Leaders)
newOrg.Leaders = string(leaderByte)
}
err = o.orgRepo.Save(ctx, newOrg)
return err return err
} }
@ -83,12 +122,16 @@ func (o *organizationService) Organization(ctx context.Context, info *orgModel.G
return return
} }
if err != gorm.ErrRecordNotFound { if err == gorm.ErrRecordNotFound {
err = fmt.Errorf("组织不存在") err = fmt.Errorf("组织不存在")
return return
} }
copier.Copy(&org, dbOrg) copier.Copy(&org, dbOrg)
if len(dbOrg.Leaders) > 0 {
json.Unmarshal([]byte(dbOrg.Leaders), &org.Leaders)
}
return return
} }

View File

@ -3,6 +3,8 @@ package organization
import ( import (
orgModel "busniess-user-center/internal/models/organization" orgModel "busniess-user-center/internal/models/organization"
"busniess-user-center/internal/repo" "busniess-user-center/internal/repo"
"context"
"fmt"
"sort" "sort"
) )
@ -114,20 +116,20 @@ func getChildren(orgId uint, orgChildrenMap map[uint][]repo.Organization) (orgs
return return
} }
func getOrgTree(orgs []repo.Organization) orgModel.OrgTree { func getOrgTree(orgs []*repo.Organization) orgModel.OrgTree {
// top // top
topOrgs := []orgModel.Organization{} topOrgs := []*orgModel.Organization{}
parentMap := make(map[uint][]orgModel.Organization) parentMap := make(map[uint][]*orgModel.Organization)
for _, org := range orgs { for _, org := range orgs {
mOrg := convertOrgDTM(org) mOrg := convertOrgDTM(org)
if org.ParentID == 0 { if org.ParentID == 0 {
topOrgs = append(topOrgs, mOrg) topOrgs = append(topOrgs, mOrg)
}
if _, ok := parentMap[org.ID]; !ok {
parentMap[org.ID] = []orgModel.Organization{mOrg}
} else { } else {
parentMap[org.ID] = append(parentMap[org.ID], mOrg) if _, ok := parentMap[org.ParentID]; !ok {
parentMap[org.ParentID] = []*orgModel.Organization{mOrg}
} else {
parentMap[org.ParentID] = append(parentMap[org.ParentID], mOrg)
}
} }
} }
@ -158,8 +160,8 @@ func getOrgTree(orgs []repo.Organization) orgModel.OrgTree {
return topOrgs return topOrgs
} }
func convertOrgDTM(org repo.Organization) orgModel.Organization { func convertOrgDTM(org *repo.Organization) *orgModel.Organization {
return orgModel.Organization{ return &orgModel.Organization{
ID: org.ID, // id ID: org.ID, // id
Name: org.Name, // 组织名 Name: org.Name, // 组织名
ParentID: org.ParentID, // 上级组织id ParentID: org.ParentID, // 上级组织id
@ -169,3 +171,13 @@ func convertOrgDTM(org repo.Organization) orgModel.Organization {
CreatedOn: org.CreatedOn, // 记录创建时间 CreatedOn: org.CreatedOn, // 记录创建时间
} }
} }
func (o *organizationService) verfyUsers(ctx context.Context, accounts []string) error {
for _, account := range accounts {
if _, err := o.userService.ExistUserByAccount(ctx, account); err != nil {
return fmt.Errorf("用户%s不存在", account)
}
}
return nil
}

View File

@ -16,4 +16,5 @@ type UserService interface {
Search(ctx context.Context, query *userModel.Query) (*userModel.SearchRsp, error) Search(ctx context.Context, query *userModel.Query) (*userModel.SearchRsp, error)
ResetPwd(ctx context.Context, req *userModel.ResetPwdReq) error ResetPwd(ctx context.Context, req *userModel.ResetPwdReq) error
GetUser(ctx context.Context, req *userModel.GetUserReq) (user userModel.User, err error) GetUser(ctx context.Context, req *userModel.GetUserReq) (user userModel.User, err error)
ExistUserByAccount(ctx context.Context, account string) (uint, error)
} }

View File

@ -263,3 +263,16 @@ func (u *userService) GetUser(ctx context.Context, req *userModel.GetUserReq) (u
user = convertUser(rUser) user = convertUser(rUser)
return return
} }
func (u *userService) ExistUserByAccount(ctx context.Context, account string) (uint, error) {
user, err := u.repo.GetUserByAccount(ctx, account)
if err != nil && err != gorm.ErrRecordNotFound {
return 0, err
}
if err == gorm.ErrRecordNotFound {
return 0, nil
}
return user.ID, nil
}

View File

@ -32,7 +32,7 @@ func RegisterRoute(api *gin.RouterGroup) {
server := do.MustInvoke[*OrganizationServer](nil) server := do.MustInvoke[*OrganizationServer](nil)
api.POST("/create", ginUtil.WrapNoRsp(server.Create)) api.POST("/create", ginUtil.WrapNoRsp(server.Create))
api.POST("/save", ginUtil.WrapNoRsp(server.SaveOrganization)) api.POST("/save", ginUtil.WrapNoRsp(server.SaveOrganization))
api.POST("/delete", ginUtil.WrapNoRsp(server.DelOrganization)) api.DELETE("/delete", ginUtil.WrapNoRsp(server.DelOrganization))
api.GET("/get", ginUtil.Wrap(server.Organization)) api.GET("/get", ginUtil.Wrap(server.Organization))
api.POST("/move", ginUtil.WrapNoRsp(server.MoveOrganization)) api.POST("/move", ginUtil.WrapNoRsp(server.MoveOrganization))
api.GET("/orgs", ginUtil.WrapNoReq(server.OrganizationTree)) api.GET("/orgs", ginUtil.WrapNoReq(server.OrganizationTree))