You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

359 lines
8.4 KiB
Go

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
}