142 lines
3.9 KiB
Go
142 lines
3.9 KiB
Go
|
package admin_user
|
||
|
|
||
|
import (
|
||
|
"context"
|
||
|
|
||
|
"qnc-server/app/main/api/internal/svc"
|
||
|
"qnc-server/app/main/api/internal/types"
|
||
|
"qnc-server/app/main/model"
|
||
|
"qnc-server/common/xerr"
|
||
|
|
||
|
"github.com/pkg/errors"
|
||
|
"github.com/samber/lo"
|
||
|
"github.com/zeromicro/go-zero/core/logx"
|
||
|
"github.com/zeromicro/go-zero/core/stores/sqlx"
|
||
|
)
|
||
|
|
||
|
type AdminUpdateUserLogic struct {
|
||
|
logx.Logger
|
||
|
ctx context.Context
|
||
|
svcCtx *svc.ServiceContext
|
||
|
}
|
||
|
|
||
|
func NewAdminUpdateUserLogic(ctx context.Context, svcCtx *svc.ServiceContext) *AdminUpdateUserLogic {
|
||
|
return &AdminUpdateUserLogic{
|
||
|
Logger: logx.WithContext(ctx),
|
||
|
ctx: ctx,
|
||
|
svcCtx: svcCtx,
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func (l *AdminUpdateUserLogic) AdminUpdateUser(req *types.AdminUpdateUserReq) (resp *types.AdminUpdateUserResp, err error) {
|
||
|
// 检查用户是否存在
|
||
|
user, err := l.svcCtx.AdminUserModel.FindOne(l.ctx, req.Id)
|
||
|
if err != nil {
|
||
|
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "用户不存在: %v", err)
|
||
|
}
|
||
|
|
||
|
// 检查用户名是否重复
|
||
|
if req.Username != nil && *req.Username != user.Username {
|
||
|
exists, err := l.svcCtx.AdminUserModel.FindOneByUsername(l.ctx, *req.Username)
|
||
|
if err != nil && err != model.ErrNotFound {
|
||
|
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "更新用户失败: %v", err)
|
||
|
}
|
||
|
if exists != nil {
|
||
|
return nil, errors.Wrapf(xerr.NewErrMsg("用户名已存在"), "更新用户失败")
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// 更新用户信息
|
||
|
if req.Username != nil {
|
||
|
user.Username = *req.Username
|
||
|
}
|
||
|
if req.RealName != nil {
|
||
|
user.RealName = *req.RealName
|
||
|
}
|
||
|
if req.Status != nil {
|
||
|
user.Status = *req.Status
|
||
|
}
|
||
|
|
||
|
// 使用事务更新用户和关联角色
|
||
|
err = l.svcCtx.AdminUserModel.Trans(l.ctx, func(ctx context.Context, session sqlx.Session) error {
|
||
|
// 更新用户
|
||
|
_, err = l.svcCtx.AdminUserModel.Update(ctx, session, user)
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
// 只有当RoleIds不为nil时才更新角色关联
|
||
|
if req.RoleIds != nil {
|
||
|
// 1. 获取当前关联的角色ID
|
||
|
builder := l.svcCtx.AdminUserRoleModel.SelectBuilder().
|
||
|
Where("user_id = ?", req.Id)
|
||
|
currentRoles, err := l.svcCtx.AdminUserRoleModel.FindAll(ctx, builder, "id ASC")
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
// 2. 转换为map便于查找
|
||
|
currentRoleMap := make(map[int64]*model.AdminUserRole)
|
||
|
for _, role := range currentRoles {
|
||
|
currentRoleMap[role.RoleId] = role
|
||
|
}
|
||
|
|
||
|
// 3. 检查新的角色ID是否存在
|
||
|
for _, roleId := range req.RoleIds {
|
||
|
exists, err := l.svcCtx.AdminRoleModel.FindOne(ctx, roleId)
|
||
|
if err != nil || exists == nil {
|
||
|
return errors.Wrapf(xerr.NewErrMsg("角色不存在"), "角色ID: %d", roleId)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// 4. 找出需要删除和新增的关联
|
||
|
var toDelete []*model.AdminUserRole
|
||
|
var toInsert []int64
|
||
|
|
||
|
// 需要删除的:当前存在但新列表中没有的
|
||
|
for roleId, userRole := range currentRoleMap {
|
||
|
if !lo.Contains(req.RoleIds, roleId) {
|
||
|
toDelete = append(toDelete, userRole)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// 需要新增的:新列表中有但当前不存在的
|
||
|
for _, roleId := range req.RoleIds {
|
||
|
if _, exists := currentRoleMap[roleId]; !exists {
|
||
|
toInsert = append(toInsert, roleId)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// 5. 删除需要移除的关联
|
||
|
for _, userRole := range toDelete {
|
||
|
err = l.svcCtx.AdminUserRoleModel.Delete(ctx, session, userRole.Id)
|
||
|
if err != nil {
|
||
|
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "删除用户角色关联失败: %v", err)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// 6. 添加新的关联
|
||
|
for _, roleId := range toInsert {
|
||
|
userRole := &model.AdminUserRole{
|
||
|
UserId: req.Id,
|
||
|
RoleId: roleId,
|
||
|
}
|
||
|
_, err = l.svcCtx.AdminUserRoleModel.Insert(ctx, session, userRole)
|
||
|
if err != nil {
|
||
|
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "添加用户角色关联失败: %v", err)
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return nil
|
||
|
})
|
||
|
|
||
|
if err != nil {
|
||
|
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "更新用户失败: %v", err)
|
||
|
}
|
||
|
|
||
|
return &types.AdminUpdateUserResp{
|
||
|
Success: true,
|
||
|
}, nil
|
||
|
}
|