package service import ( "joybuywork/internal/app" "joybuywork/internal/consts" "joybuywork/internal/consts/ckey" "joybuywork/internal/plugins/encrypt" "joybuywork/internal/repository/cache" "joybuywork/internal/repository/dbcheck" "joybuywork/internal/repository/finder" "joybuywork/internal/repository/model" "joybuywork/internal/repository/mtype" "joybuywork/internal/repository/withdefault" "joybuywork/internal/service/containers" "joybuywork/internal/utils" pb "joybuywork/proto/go_proto/w_user" "joybuywork/proto/go_proto/workerr" c_userpb "gits.branchcn.com/backend/certified/proto/go_proto/c_user" "gorm.io/gen/field" ) type WUser struct { Service } // Login 登陆 func (s *WUser) Login(req *pb.LoginReq, res *pb.LoginRes) (err error) { defer s.checkErr() *res = pb.LoginRes{} container := new(containers.UserLogin) { container.Init(s.ctx) container.Req = req container.Res = res } err = container.Run() return } // List 用户列表 func (s *WUser) List(req *pb.ListReq, res *pb.ListRes) (err error) { defer s.checkErr() m := s.GetDao().User offset, limit := utils.PpDbLo(req.GetPage(), req.GetPerPage()) list, count, err := m.WithContext(s.ctx).Where(m.CompanyID.Eq(req.GetCompanyId()), m.IsDel.Eq(mtype.No)).Order(m.ID.Desc()).FindByPage(offset, limit) if err != nil { return s.BE().MysqlError(err) } *res = pb.ListRes{ List: make([]*pb.ListRes_One, 0, len(list)), Total: count, } if count == 0 { return } var userIds []int64 for _, v := range list { userIds = append(userIds, v.ID) } //找员工和项目的关联关系 relateM := s.GetDao().UserProjectRelate relateList, err := relateM.WithContext(s.ctx).Where(relateM.UserID.In(userIds...), relateM.IsDel.Eq(mtype.No)).Find() if err != nil { return s.BE().MysqlError(err) } //构建项目的hash表 var projectMap = make(map[int64]*model.Project) var userProjectMap = make(map[int64][]int64) if len(relateList) > 0 { //有关联关系才处理 //得到关联的项目ID var projectIds []int64 for _, v := range relateList { userProjectMap[v.UserID] = append(userProjectMap[v.UserID], v.ProjectID) if _, ok := projectMap[v.ProjectID]; !ok { projectIds = append(projectIds, v.ProjectID) projectMap[v.ProjectID] = nil } } //查询表数据 var projectList []*model.Project projectM := s.GetDao().Project projectList, err = projectM.WithContext(s.ctx).Where(projectM.ID.In(projectIds...), projectM.IsDel.Eq(mtype.No)).Find() if err != nil { return s.BE().MysqlError(err) } for _, v := range projectList { projectMap[v.ID] = v } } for _, v := range list { one := &pb.ListRes_One{ Id: v.ID, HashId: v.HashID, ShowName: v.ShowName, Username: v.Username, Email: v.Email, RoleName: utils.Ternary[string](v.IsAdmin == mtype.No, consts.NormalRoleName, consts.AdminRoleName), } //写入关联项目数据 if ids, ok := userProjectMap[v.ID]; ok { for _, id := range ids { if pro, ok1 := projectMap[id]; ok1 && pro != nil { one.Projects = append(one.Projects, &pb.ListRes_Project{ Id: pro.ID, HashId: pro.HashID, Title: pro.Title, }) } } } res.List = append(res.List, one) } return } // Store 创建员工 func (s *WUser) Store(req *pb.StoreReq, res *pb.StoreRes) (err error) { defer s.checkErr() //保证只有一个账号被创建 onceKey := ckey.UserStoreOnce(req.GetUsername()) lc := app.NewRedisLock(s.ctx, onceKey) defer lc.Release() if !lc.SoftLock() { return workerr.OnceLockError } //验证用户名是否被使用 m := s.GetDao().User exist, err := m.WithContext(s.ctx).Where(m.Username.Eq(req.Username)).Take() if err = dbcheck.DbError(err); err != nil { return s.BE().MysqlError(err) } if exist != nil && exist.IsDel == mtype.No { return workerr.UserExistError } user := withdefault.User(&model.User{ CompanyID: req.GetCompanyId(), Username: req.GetUsername(), ShowName: req.GetShowName(), Passwd: encrypt.UserPasswd(req.GetPasswd()), Email: req.GetEmail(), }) err = m.WithContext(s.ctx).Create(user) if err != nil { return s.BE().MysqlError(err) } //创建项目 pjm := s.GetDao().Project var adds []*model.UserProjectRelate var addMap = make(map[int64]struct{}) //提交上来的项目id if len(req.GetProjectHashIds()) > 0 { var pjs []*model.Project pjs, err = pjm.WithContext(s.ctx).Where(pjm.HashID.In(req.GetProjectHashIds()...), pjm.IsDel.Eq(mtype.No)).Find() if err != nil { return s.BE().MysqlError(err) } for _, v := range pjs { adds = append(adds, withdefault.UserProjectRelate(&model.UserProjectRelate{ UserID: user.ID, ProjectID: v.ID, })) addMap[v.ID] = struct{}{} } } //标识为所有员工都可以看的项目 var pjs []*model.Project pjs, err = pjm.WithContext(s.ctx).Where(pjm.CompanyID.Eq(req.GetCompanyId()), pjm.IsAll.Eq(mtype.Yes), pjm.IsDel.Eq(mtype.No)).Find() if err != nil { return s.BE().MysqlError(err) } for _, v := range pjs { //没有选中的才添加,避免重复添加 if _, ok := addMap[v.ID]; !ok { adds = append(adds, withdefault.UserProjectRelate(&model.UserProjectRelate{ UserID: user.ID, ProjectID: v.ID, })) } } if len(adds) > 0 { err = s.GetDao().UserProjectRelate.WithContext(s.ctx).Create(adds...) if err != nil { return s.BE().MysqlError(err) } } *res = pb.StoreRes{} //清空缓存 err = cache.NewUser(s.ctx).Clear(user) if err != nil { return s.BE().RedisError(err) } return } // Update 更新员工 func (s *WUser) Update(req *pb.UpdateReq, res *pb.UpdateRes) (err error) { defer s.checkErr() m := s.GetDao().User user, err := finder.User(s.ctx, req.GetHashId(), req.GetId()) if err != nil { return s.BE().CacheError(err) } if user == nil || user.IsDel == mtype.Yes { return workerr.NotFound("not found user") } //找到和用户关联的项目id var oldIds []int64 uprM := s.GetDao().UserProjectRelate err = uprM.WithContext(s.ctx).Where(uprM.UserID.Eq(user.ID), uprM.IsDel.Eq(mtype.No)).Pluck(uprM.ProjectID, &oldIds) if err != nil { return s.BE().MysqlError(err) } *res = pb.UpdateRes{} var updateField []field.AssignExpr if user.ShowName != req.GetShowName() { updateField = append(updateField, m.ShowName.Value(req.ShowName)) } if req.GetPasswd() != "" { valid, _ := encrypt.CheckUserPasswd(req.GetPasswd(), user.Passwd) if !valid { updateField = append(updateField, m.Passwd.Value(encrypt.UserPasswd(req.GetPasswd()))) } } if len(updateField) > 0 { _, err = m.WithContext(s.ctx).Where(m.ID.Eq(user.ID)).UpdateSimple(updateField...) if err != nil { return s.BE().MysqlError(err) } } //清空缓存 err = cache.NewUser(s.ctx).Clear(user) if err != nil { return s.BE().RedisError(err) } return } // Destroy 删除员工 func (s *WUser) Destroy(req *pb.DestroyReq, res *pb.DestroyRes) (err error) { defer s.checkErr() *res = pb.DestroyRes{} m := s.GetDao().User user, err := finder.User(s.ctx, req.GetHashId(), req.GetId()) if err != nil { return s.BE().CacheError(err) } if user == nil || user.IsDel == mtype.Yes { return } if user.IsAdmin == mtype.Yes { return workerr.UserDelError } _, err = m.WithContext(s.ctx).Where(m.ID.Eq(user.ID)).UpdateSimple(m.IsDel.Value(mtype.Yes)) if err != nil { return s.BE().MysqlError(err) } //清空缓存 err = cache.NewUser(s.ctx).Clear(user) if err != nil { return s.BE().RedisError(err) } _, _ = app.NewCertifiedUser().Destroy(s.ctx, &c_userpb.DestroyReq{Id: user.ID}) return } // Show 员工详情 func (s *WUser) Show(req *pb.ShowReq, res *pb.ShowRes) (err error) { defer s.checkErr() user, err := finder.User(s.ctx, req.GetHashId(), req.GetId()) if err != nil { return s.BE().CacheError(err) } if user == nil || user.IsDel == mtype.Yes { return workerr.NotFound("not found user") } *res = pb.ShowRes{ Id: user.ID, HashId: user.HashID, ShowName: user.ShowName, Username: user.Username, Email: user.Email, IsAdmin: user.IsAdmin == mtype.Yes, } return } // Select 用户选择列表 func (s *WUser) Select(req *pb.SelectReq, res *pb.SelectRes) (err error) { defer s.checkErr() *res = pb.SelectRes{} m := s.GetDao().User list, err := m.WithContext(s.ctx).Where(m.CompanyID.Eq(req.GetCompanyId()), m.IsDel.Eq(mtype.No)).Find() if err != nil { return s.BE().MysqlError(err) } for _, v := range list { res.List = append(res.List, &pb.SelectRes_One{ Id: v.ID, HashId: v.HashID, ShowName: v.ShowName, }) } return }