作者 yangfu

用户角色修改

... ... @@ -389,6 +389,9 @@ type(
}
SystemUserAccountUpdateRequest struct{
Id int64 `path:"id"`
Name string `json:"name"` // 姓名
Roles []int64 `json:"roles"` // 权限角色
Status int `json:"enable"` // 状态 1:启用 2:禁用
}
SystemUserAccountUpdateResponse struct{}
... ...
... ... @@ -2,7 +2,9 @@ package role
import (
"context"
"github.com/samber/lo"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/domain"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/pkg/contextdata"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/pkg/xerr"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/api/internal/svc"
... ... @@ -27,15 +29,26 @@ func NewSystemGetRoleLogic(ctx context.Context, svcCtx *svc.ServiceContext) *Sys
func (l *SystemGetRoleLogic) SystemGetRole(req *types.RoleGetRequest) (resp *types.RoleGetResponse, err error) {
var (
conn = l.svcCtx.DefaultDBConn()
role *domain.Role
conn = l.svcCtx.DefaultDBConn()
role *domain.Role
users []*domain.User
userToken = contextdata.GetUserTokenFromCtx(l.ctx)
)
if role, err = l.svcCtx.RoleRepository.FindOne(l.ctx, conn, req.Id); err != nil {
return nil, xerr.NewErrMsgErr("角色不存在", err)
}
_, users, _ = l.svcCtx.UserRepository.FindByCompanyRoles(l.ctx, conn, userToken.CompanyId, []int64{role.Id}, domain.NewQueryOptions().WithFindOnly())
typesRole := NewTypesRole(role)
lo.ForEach(users, func(item *domain.User, index int) {
typesRole.Users = append(typesRole.Users, types.RoleUser{
Id: item.Id,
Name: item.Name,
})
})
resp = &types.RoleGetResponse{
Role: NewTypesRole(role),
Role: typesRole,
}
for _, auth := range domain.Auths {
resp.AuthList = append(resp.AuthList, types.Auth{
Id: auth.Id,
... ...
... ... @@ -92,12 +92,6 @@ func NewTypesRole(item *domain.Role) types.RoleItem {
role types.RoleItem
users []types.RoleUser = make([]types.RoleUser, 0)
)
lo.ForEach(item.Users, func(item domain.User, index int) {
users = append(users, types.RoleUser{
Id: item.Id,
Name: item.Name,
})
})
role = types.RoleItem{
Id: item.Id,
CompanyId: item.CompanyId,
... ...
... ... @@ -35,6 +35,7 @@ func (l *SystemSearchRoleLogic) SystemSearchRole(req *types.RoleSearchRequest) (
userToken = contextdata.GetUserTokenFromCtx(l.ctx)
roles []*domain.Role
total int64
users []*domain.User
)
queryOptions := domain.IndexCompanyId(userToken.CompanyId)()
if req.Page != 0 && req.Size != 0 {
... ... @@ -57,17 +58,27 @@ func (l *SystemSearchRoleLogic) SystemSearchRole(req *types.RoleSearchRequest) (
})
return
}
roleIds := domain.Values(roles, func(item *domain.Role) int64 {
return item.Id
})
_, users, _ = l.svcCtx.UserRepository.FindByCompanyRoles(l.ctx, conn, userToken.CompanyId, roleIds, domain.NewQueryOptions().WithFindOnly())
lo.ForEach(roles, func(item *domain.Role, index int) {
role := NewTypesRole(item)
role.UsersDesc = usersDesc(item)
usersAll := make([]domain.User, 0)
for _, u := range users {
if lo.Contains(u.Roles, item.Id) {
usersAll = append(usersAll, *u)
}
}
role.UsersDesc = usersDesc(usersAll)
role.AuthsDesc = authsDesc(item)
resp.List = append(resp.List, role)
})
return
}
func usersDesc(item *domain.Role) string {
users := lo.Slice(item.Users, 0, 3)
func usersDesc(usersAll []domain.User) string {
users := lo.Slice(usersAll, 0, 3)
var (
nameList = make([]string, 0)
desc string = " "
... ... @@ -79,7 +90,7 @@ func usersDesc(item *domain.Role) string {
return desc
}
desc = fmt.Sprintf("%s%s", strings.Join(nameList, "、"),
lo.Ternary(len(item.Users) > 3, fmt.Sprintf("...共%d人", len(item.Users)), ""),
lo.Ternary(len(usersAll) > 3, fmt.Sprintf("...共%d人", len(usersAll)), ""),
)
return desc
}
... ...
... ... @@ -67,10 +67,20 @@ func (l *SystemUserAccountSaveLogic) SystemUserAccountSave(req *types.SystemUser
AuditStatus: domain.UserAuditStatusPassed,
}
user.WithName(name)
if user, err = l.svcCtx.UserRepository.Insert(ctx, conn, user); err != nil {
return err
}
for _, roleId := range req.Roles {
if _, err = l.svcCtx.UserRoleRepository.Insert(l.ctx, conn, &domain.UserRole{
CompanyId: user.CompanyId,
UserId: user.Id,
RoleId: roleId,
}); err != nil {
return err
}
user.AddRole(roleId)
}
if user, err = l.svcCtx.UserRepository.Insert(ctx, conn, user); err != nil {
if user, err = l.svcCtx.UserRepository.UpdateWithVersion(ctx, conn, user); err != nil {
return err
}
return nil
... ...
... ... @@ -2,6 +2,11 @@ package user
import (
"context"
"github.com/samber/lo"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/db/transaction"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/domain"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/pkg/contextdata"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/pkg/xerr"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/api/internal/svc"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/api/internal/types"
... ... @@ -24,7 +29,49 @@ func NewSystemUserAccountUpdateLogic(ctx context.Context, svcCtx *svc.ServiceCon
}
func (l *SystemUserAccountUpdateLogic) SystemUserAccountUpdate(req *types.SystemUserAccountUpdateRequest) (resp *types.SystemUserAccountUpdateResponse, err error) {
// todo: add your logic here and delete this line
var (
userToken = contextdata.GetUserTokenFromCtx(l.ctx)
user *domain.User
conn = l.svcCtx.DefaultDBConn()
)
if user, err = l.svcCtx.UserRepository.FindOne(l.ctx, conn, req.Id); err != nil {
return nil, xerr.NewErrMsgErr("用户不存在", err)
}
if user.CompanyId != userToken.CompanyId {
return nil, xerr.NewErrMsgErr("无权限更改", err)
}
if req.Name != user.Name {
user.WithName(req.Name)
}
removeList, addList := lo.Difference(user.Roles, req.Roles)
if len(removeList) > 0 || len(addList) > 0 {
user.Roles = req.Roles
}
user.Enable = req.Status
if err = transaction.UseTrans(l.ctx, l.svcCtx.DB, func(ctx context.Context, conn transaction.Conn) error {
if user, err = l.svcCtx.UserRepository.UpdateWithVersion(ctx, conn, user); err != nil {
return err
}
if len(removeList) > 0 || len(addList) > 0 {
if err = l.svcCtx.UserRoleRepository.DeleteByUser(ctx, conn, user.Id); err != nil {
return err
}
user.Roles = []int64{}
for _, roleId := range req.Roles {
if _, err = l.svcCtx.UserRoleRepository.Insert(l.ctx, conn, &domain.UserRole{
CompanyId: user.CompanyId,
UserId: user.Id,
RoleId: roleId,
}); err != nil {
return err
}
user.AddRole(roleId)
}
}
return nil
}, true); err != nil {
return nil, xerr.NewErrMsgErr("更新用户信息失败", err)
}
resp = &types.SystemUserAccountUpdateResponse{}
return
}
... ...
... ... @@ -39,6 +39,7 @@ type ServiceContext struct {
UserLoveFlagRepository domain.UserLoveFlagRepository
UserReadArticleRepository domain.UserReadArticleRepository
UserRepository domain.UserRepository
UserRoleRepository domain.UserRoleRepository
ApiAuthService authlib.ApiAuthService
SmsService smslib.SMSService
... ... @@ -80,6 +81,7 @@ func NewServiceContext(c config.Config) *ServiceContext {
UserRepository: repository.NewUserRepository(cache.NewCachedRepository(mlCache)),
UserReadArticleRepository: repository.NewUserReadArticleRepository(cache.NewCachedRepository(mlCache)),
ArticleTagRepository: repository.NewArticleTagRepository(cache.NewCachedRepository(mlCache)),
UserRoleRepository: repository.NewUserRoleRepository(cache.NewCachedRepository(mlCache)),
}
}
... ...
... ... @@ -689,7 +689,10 @@ type SystemUserAccountEnableResponse struct {
}
type SystemUserAccountUpdateRequest struct {
Id int64 `path:"id"`
Id int64 `path:"id"`
Name string `json:"name"` // 姓名
Roles []int64 `json:"roles"` // 权限角色
Status int `json:"enable"` // 状态 1:启用 2:禁用
}
type SystemUserAccountUpdateResponse struct {
... ...
syntax = "v1"
info(
title: "xx实例"
desc: "xx实例"
author: "author"
email: "email"
version: "v1"
)
@server(
prefix: user_role/v1
group: user_role
jwt: JwtAuth
)
service Core {
@handler getUserRole
post /user_role/:id (UserRoleGetRequest) returns (UserRoleGetResponse)
@handler saveUserRole
post /user_role (UserRoleSaveRequest) returns (UserRoleSaveResponse)
@handler deleteUserRole
delete /user_role/:id (UserRoleDeleteRequest) returns (UserRoleDeleteResponse)
@handler updateUserRole
put /user_role/:id (UserRoleUpdateRequest) returns (UserRoleUpdateResponse)
@handler searchUserRole
post /user_role/search (UserRoleSearchRequest) returns (UserRoleSearchResponse)
}
type (
UserRoleGetRequest {
Id int64 `path:"id"`
}
UserRoleGetResponse struct{
UserRole UserRoleItem `json:"user_role"`
}
UserRoleSaveRequest struct{
UserRole UserRoleItem `json:"user_role"`
}
UserRoleSaveResponse struct{}
UserRoleDeleteRequest struct{
Id int64 `path:"id"`
}
UserRoleDeleteResponse struct{}
UserRoleUpdateRequest struct{
Id int64 `path:"id"`
UserRole UserRoleItem `json:"user_role"`
}
UserRoleUpdateResponse struct{}
UserRoleSearchRequest struct{
Page int `json:"page"`
Size int `json:"size"`
}
UserRoleSearchResponse{
List []UserRoleItem `json:"list"`
Total int64 `json:"total"`
}
UserRoleItem struct{
}
)
... ...
syntax = "proto3";
option go_package ="./pb";
package pb;
message UserRoleGetReq {
int64 Id = 1;
}
message UserRoleGetResp{
UserRoleItem User = 1;
}
message UserRoleSaveReq {
}
message UserRoleSaveResp{
}
message UserRoleDeleteReq {
int64 Id = 1;
}
message UserRoleDeleteResp{
}
message UserRoleUpdateReq {
int64 Id = 1;
}
message UserRoleUpdateResp{
}
message UserRoleSearchReq {
int64 PageNumber = 1;
int64 PageSize = 2;
}
message UserRoleSearchResp{
repeated UserRoleItem List =1;
int64 Total =2;
}
message UserRoleItem {
}
service UserRoleService {
rpc UserRoleGet(UserRoleGetReq) returns(UserRoleGetResp);
rpc UserRoleSave(UserRoleSaveReq) returns(UserRoleSaveResp);
rpc UserRoleDelete(UserRoleDeleteReq) returns(UserRoleDeleteResp);
rpc UserRoleUpdate(UserRoleUpdateReq) returns(UserRoleUpdateResp);
rpc UserRoleSearch(UserRoleSearchReq) returns(UserRoleSearchResp);
}
... ...
... ... @@ -16,6 +16,7 @@ func Migrate(db *gorm.DB) {
&models.UserLoveFlag{},
&models.UserReadArticle{},
&models.User{},
&models.UserRole{},
&models.Role{},
&models.Company{},
&models.UserFollow{},
... ...
package models
import (
"gorm.io/gorm"
)
type UserRole struct {
Id int64 // 唯一标识
CompanyId int64 // 公司ID
UserId int64
RoleId int64
CreatedAt int64
UpdatedAt int64
DeletedAt int64
Version int
}
func (m *UserRole) TableName() string {
return "user_role"
}
func (m *UserRole) BeforeCreate(tx *gorm.DB) (err error) {
// m.CreatedAt = time.Now().Unix()
// m.UpdatedAt = time.Now().Unix()
return
}
func (m *UserRole) BeforeUpdate(tx *gorm.DB) (err error) {
// m.UpdatedAt = time.Now().Unix()
return
}
func (m *UserRole) CacheKeyFunc() string {
return ""
}
func (m *UserRole) CacheKeyFuncByObject(obj interface{}) string {
if v, ok := obj.(*UserRole); ok {
return v.CacheKeyFunc()
}
return ""
}
func (m *UserRole) CachePrimaryKeyFunc() string {
return ""
}
... ...
... ... @@ -242,6 +242,39 @@ func (repository *UserRepository) FindDepartmentUsers(ctx context.Context, conn
return total, dms, nil
}
func (repository *UserRepository) FindByCompanyRoles(ctx context.Context, conn transaction.Conn, companyId int64, roles []int64, queryOptions map[string]interface{}) (int64, []*domain.User, error) {
var (
tx = conn.DB()
ms []*models.User
dms = make([]*domain.User, 0)
total int64
)
queryFunc := func() (interface{}, error) {
tx = tx.Model(&ms).Order("id asc")
tx.Select("id", "name", "roles")
tx.Where("company_id = ?", companyId)
tx.Where("flag = ?", domain.UserAdmin)
tx.Where("id in (select user_id from user_role where role_id in(?)) ", roles)
if total, tx = transaction.PaginationAndCount(ctx, tx, queryOptions, &ms); tx.Error != nil {
return dms, tx.Error
}
return dms, nil
}
if _, err := repository.Query(queryFunc); err != nil {
return 0, nil, err
}
for _, item := range ms {
if dm, err := repository.ModelToDomainModel(item); err != nil {
return 0, dms, err
} else {
dms = append(dms, dm)
}
}
return total, dms, nil
}
func (repository *UserRepository) FindCompanyPositions(ctx context.Context, conn transaction.Conn, companyId int64, queryOptions map[string]interface{}) (int64, []*domain.User, error) {
var (
tx = conn.DB()
... ...
package repository
import (
"context"
"github.com/jinzhu/copier"
"github.com/pkg/errors"
"github.com/tiptok/gocomm/pkg/cache"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/db/models"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/db/transaction"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/domain"
"gorm.io/gorm"
)
type UserRoleRepository struct {
*cache.CachedRepository
}
func (repository *UserRoleRepository) Insert(ctx context.Context, conn transaction.Conn, dm *domain.UserRole) (*domain.UserRole, error) {
var (
err error
m = &models.UserRole{}
tx = conn.DB()
)
if m, err = repository.DomainModelToModel(dm); err != nil {
return nil, err
}
if tx = tx.Model(m).Save(m); tx.Error != nil {
return nil, tx.Error
}
dm.Id = m.Id
return repository.ModelToDomainModel(m)
}
func (repository *UserRoleRepository) Update(ctx context.Context, conn transaction.Conn, dm *domain.UserRole) (*domain.UserRole, error) {
var (
err error
m *models.UserRole
tx = conn.DB()
)
if m, err = repository.DomainModelToModel(dm); err != nil {
return nil, err
}
queryFunc := func() (interface{}, error) {
tx = tx.Model(m).Updates(m)
return nil, tx.Error
}
if _, err = repository.Query(queryFunc, m.CacheKeyFunc()); err != nil {
return nil, err
}
return repository.ModelToDomainModel(m)
}
func (repository *UserRoleRepository) UpdateWithVersion(ctx context.Context, transaction transaction.Conn, dm *domain.UserRole) (*domain.UserRole, error) {
var (
err error
m *models.UserRole
tx = transaction.DB()
)
if m, err = repository.DomainModelToModel(dm); err != nil {
return nil, err
}
oldVersion := dm.Version
m.Version += 1
queryFunc := func() (interface{}, error) {
tx = tx.Model(m).Select("*").Where("id = ?", m.Id).Where("version = ?", oldVersion).Updates(m)
if tx.RowsAffected == 0 {
return nil, domain.ErrUpdateFail
}
return nil, tx.Error
}
if _, err = repository.Query(queryFunc, m.CacheKeyFunc()); err != nil {
return nil, err
}
return repository.ModelToDomainModel(m)
}
func (repository *UserRoleRepository) Delete(ctx context.Context, conn transaction.Conn, dm *domain.UserRole) (*domain.UserRole, error) {
var (
tx = conn.DB()
m = &models.UserRole{Id: dm.Identify().(int64)}
)
queryFunc := func() (interface{}, error) {
tx = tx.Where("id = ?", m.Id).Delete(m)
return m, tx.Error
}
if _, err := repository.Query(queryFunc, m.CacheKeyFunc()); err != nil {
return dm, err
}
return repository.ModelToDomainModel(m)
}
func (repository *UserRoleRepository) DeleteByUser(ctx context.Context, conn transaction.Conn, userId int64) error {
var (
tx = conn.DB()
m = &models.UserRole{}
)
queryFunc := func() (interface{}, error) {
tx = tx.Where("user_id = ?", userId).Delete(m)
return m, tx.Error
}
if _, err := repository.Query(queryFunc, m.CacheKeyFunc()); err != nil {
return err
}
return nil
}
func (repository *UserRoleRepository) FindOne(ctx context.Context, conn transaction.Conn, id int64) (*domain.UserRole, error) {
var (
err error
tx = conn.DB()
m = new(models.UserRole)
)
queryFunc := func() (interface{}, error) {
tx = tx.Model(m).Where("id = ?", id).First(m)
if errors.Is(tx.Error, gorm.ErrRecordNotFound) {
return nil, domain.ErrNotFound
}
return m, tx.Error
}
cacheModel := new(models.UserRole)
cacheModel.Id = id
if err = repository.QueryCache(cacheModel.CacheKeyFunc, m, queryFunc); err != nil {
return nil, err
}
return repository.ModelToDomainModel(m)
}
func (repository *UserRoleRepository) Find(ctx context.Context, conn transaction.Conn, queryOptions map[string]interface{}) (int64, []*domain.UserRole, error) {
var (
tx = conn.DB()
ms []*models.UserRole
dms = make([]*domain.UserRole, 0)
total int64
)
queryFunc := func() (interface{}, error) {
tx = tx.Model(&ms).Order("id desc")
if total, tx = transaction.PaginationAndCount(ctx, tx, queryOptions, &ms); tx.Error != nil {
return dms, tx.Error
}
return dms, nil
}
if _, err := repository.Query(queryFunc); err != nil {
return 0, nil, err
}
for _, item := range ms {
if dm, err := repository.ModelToDomainModel(item); err != nil {
return 0, dms, err
} else {
dms = append(dms, dm)
}
}
return total, dms, nil
}
func (repository *UserRoleRepository) ModelToDomainModel(from *models.UserRole) (*domain.UserRole, error) {
to := &domain.UserRole{}
err := copier.Copy(to, from)
return to, err
}
func (repository *UserRoleRepository) DomainModelToModel(from *domain.UserRole) (*models.UserRole, error) {
to := &models.UserRole{}
err := copier.Copy(to, from)
return to, err
}
func NewUserRoleRepository(cache *cache.CachedRepository) domain.UserRoleRepository {
return &UserRoleRepository{CachedRepository: cache}
}
... ...
... ... @@ -39,6 +39,7 @@ type UserRepository interface {
FindOne(ctx context.Context, conn transaction.Conn, id int64) (*User, error)
FindOneByCompanyIdAndPhone(ctx context.Context, conn transaction.Conn, companyId int64, phone string, status []int) (*User, error)
Find(ctx context.Context, conn transaction.Conn, queryOptions map[string]interface{}) (int64, []*User, error)
FindByCompanyRoles(ctx context.Context, conn transaction.Conn, companyId int64, roles []int64, queryOptions map[string]interface{}) (int64, []*User, error)
FindDepartmentUsers(ctx context.Context, conn transaction.Conn, companyId int64, queryOptions map[string]interface{}) (int64, []*User, error)
FindCompanyPositions(ctx context.Context, conn transaction.Conn, companyId int64, queryOptions map[string]interface{}) (int64, []*User, error)
}
... ...
package domain
import (
"context"
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/db/transaction"
)
type UserRole struct {
Id int64 // 唯一标识
CompanyId int64 // 公司ID
UserId int64
RoleId int64
CreatedAt int64
UpdatedAt int64
DeletedAt int64
Version int
}
type UserRoleRepository interface {
Insert(ctx context.Context, conn transaction.Conn, dm *UserRole) (*UserRole, error)
Update(ctx context.Context, conn transaction.Conn, dm *UserRole) (*UserRole, error)
UpdateWithVersion(ctx context.Context, conn transaction.Conn, dm *UserRole) (*UserRole, error)
Delete(ctx context.Context, conn transaction.Conn, dm *UserRole) (*UserRole, error)
DeleteByUser(ctx context.Context, conn transaction.Conn, userId int64) error
FindOne(ctx context.Context, conn transaction.Conn, id int64) (*UserRole, error)
Find(ctx context.Context, conn transaction.Conn, queryOptions map[string]interface{}) (int64, []*UserRole, error)
}
func (m *UserRole) Identify() interface{} {
if m.Id == 0 {
return nil
}
return m.Id
}
... ...
CREATE TABLE `comment` (
`id` int(0) NOT NULL COMMENT '唯一标识',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
CREATE TABLE `department` (
`id` int(0) NOT NULL COMMENT '唯一标识',
PRIMARY KEY (`id`) USING BTREE
... ... @@ -18,6 +13,11 @@ CREATE TABLE `user` (
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
CREATE TABLE `user_role` (
`id` int(0) NOT NULL COMMENT '唯一标识',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
CREATE TABLE `company` (
`id` int(0) NOT NULL COMMENT '唯一标识',
PRIMARY KEY (`id`) USING BTREE
... ...