作者 郑周

Merge branch 'dev-zhengzhou' into test

@@ -113,3 +113,31 @@ func (rs *RoleUserService) ListRole(in *command.UserRoleQueryCommand) (interface @@ -113,3 +113,31 @@ func (rs *RoleUserService) ListRole(in *command.UserRoleQueryCommand) (interface
113 } 113 }
114 return tool_funs.SimpleWrapGridMap(total, tempList), nil 114 return tool_funs.SimpleWrapGridMap(total, tempList), nil
115 } 115 }
  116 +
  117 +// GetHRBP 当前操作人是否拥有HRBP权限
  118 +func GetHRBP(transactionContext application.TransactionContext, companyId int, operatorId int) (int, error) {
  119 + roleRepo := factory.CreateRoleRepository(map[string]interface{}{"transactionContext": transactionContext})
  120 + roleUserRepo := factory.CreateRoleUserRepository(map[string]interface{}{"transactionContext": transactionContext})
  121 + _, roleList, err := roleRepo.Find(map[string]interface{}{"type": domain.RoleTypeSystem, "companyId": companyId})
  122 + if err != nil {
  123 + return -1, application.ThrowError(application.INTERNAL_SERVER_ERROR, "获取角色信息列表"+err.Error())
  124 + }
  125 + _, userRoleList, err := roleUserRepo.Find(map[string]interface{}{"companyId": companyId, "userId": operatorId})
  126 + if err != nil {
  127 + return -1, application.ThrowError(application.INTERNAL_SERVER_ERROR, "获取用户的角色信息列表"+err.Error())
  128 + }
  129 + // 拥有HRBP权限
  130 + hrbp := -1
  131 + for _, v := range userRoleList {
  132 + for _, v2 := range roleList {
  133 + if v.RoleId == v2.Id {
  134 + hrbp = 1
  135 + break
  136 + }
  137 + }
  138 + if hrbp == 1 {
  139 + break
  140 + }
  141 + }
  142 + return hrbp, nil
  143 +}
  1 +package adapter
  2 +
  3 +type ImportParentUser struct {
  4 + Phone string `json:"phone"` // 用户手机号码
  5 + Name string `json:"name"` // 用户名称
  6 + ParentPhone string `json:"parentPhone"` // 上级手机号码
  7 + ParentName string `json:"parentName"` // 上级名称
  8 +}
  1 +package adapter
  2 +
  3 +import "gitlab.fjmaimaimai.com/allied-creation/performance/pkg/domain"
  4 +
  5 +type UserResp struct {
  6 + *domain.User
  7 + ParentName string `json:"parentName"` // 上级名称
  8 + PositionNames []string `json:"positionNames"` // 职位名称
  9 +}
  1 +package command
  2 +
  3 +import (
  4 + "github.com/beego/beego/v2/core/validation"
  5 +)
  6 +
  7 +type EditParentCommand struct {
  8 + Id int64 `cname:"用户ID" json:"id,string" valid:"Required"`
  9 + ParentId int64 `cname:"上级ID" json:"parentId,string" valid:"Required"`
  10 + CompanyId int `cname:"公司ID" json:"companyId"`
  11 + OperatorId int `cname:"操作人ID" json:"operatorId"`
  12 +}
  13 +
  14 +func (in *EditParentCommand) Valid(*validation.Validation) {
  15 +
  16 +}
1 package command 1 package command
2 2
  3 +import (
  4 + "github.com/beego/beego/v2/core/validation"
  5 + "gitlab.fjmaimaimai.com/allied-creation/performance/pkg/application/user/adapter"
  6 +)
  7 +
3 type ImportUserCommand struct { 8 type ImportUserCommand struct {
4 AddUsers []SaveUserCommand `json:"add"` 9 AddUsers []SaveUserCommand `json:"add"`
5 EditUsers []SaveUserCommand `json:"edit"` 10 EditUsers []SaveUserCommand `json:"edit"`
6 } 11 }
  12 +
  13 +// ImportParentUserCommand 导入直接上级
  14 +type ImportParentUserCommand struct {
  15 + CompanyId int `cname:"公司ID" json:"companyId"`
  16 + OperatorId int `cname:"操作人ID" json:"operatorId"`
  17 + Data []adapter.ImportParentUser `cname:"数据" json:"-"` // 文件中读取到的数据
  18 +}
  19 +
  20 +func (in *ImportParentUserCommand) Valid(_ *validation.Validation) {
  21 +}
@@ -4,6 +4,9 @@ import ( @@ -4,6 +4,9 @@ import (
4 "github.com/linmadan/egglib-go/core/application" 4 "github.com/linmadan/egglib-go/core/application"
5 "github.com/linmadan/egglib-go/utils/tool_funs" 5 "github.com/linmadan/egglib-go/utils/tool_funs"
6 "gitlab.fjmaimaimai.com/allied-creation/performance/pkg/application/factory" 6 "gitlab.fjmaimaimai.com/allied-creation/performance/pkg/application/factory"
  7 + service "gitlab.fjmaimaimai.com/allied-creation/performance/pkg/application/role"
  8 + "gitlab.fjmaimaimai.com/allied-creation/performance/pkg/application/user/adapter"
  9 + "gitlab.fjmaimaimai.com/allied-creation/performance/pkg/application/user/command"
7 "gitlab.fjmaimaimai.com/allied-creation/performance/pkg/application/user/query" 10 "gitlab.fjmaimaimai.com/allied-creation/performance/pkg/application/user/query"
8 "gitlab.fjmaimaimai.com/allied-creation/performance/pkg/domain" 11 "gitlab.fjmaimaimai.com/allied-creation/performance/pkg/domain"
9 ) 12 )
@@ -46,6 +49,8 @@ func (us *UserService) ListByDepartment(in *query.ListByDepartmentQuery) (interf @@ -46,6 +49,8 @@ func (us *UserService) ListByDepartment(in *query.ListByDepartmentQuery) (interf
46 }() 49 }()
47 50
48 userRepo := factory.CreateUserRepository(map[string]interface{}{"transactionContext": transactionContext}) 51 userRepo := factory.CreateUserRepository(map[string]interface{}{"transactionContext": transactionContext})
  52 + positionRepo := factory.CreatePositionRepository(map[string]interface{}{"transactionContext": transactionContext})
  53 +
49 inMap := tool_funs.SimpleStructToMap(in) 54 inMap := tool_funs.SimpleStructToMap(in)
50 if in.DepartmentId == 0 { 55 if in.DepartmentId == 0 {
51 delete(inMap, "departmentId") // 删除部门ID字段 56 delete(inMap, "departmentId") // 删除部门ID字段
@@ -54,8 +59,169 @@ func (us *UserService) ListByDepartment(in *query.ListByDepartmentQuery) (interf @@ -54,8 +59,169 @@ func (us *UserService) ListByDepartment(in *query.ListByDepartmentQuery) (interf
54 if err != nil { 59 if err != nil {
55 return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) 60 return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
56 } 61 }
  62 +
  63 + parentIds := make([]int64, 0) // 上级ID
  64 + positionIds := make([]int, 0) // 职位ID
  65 + for i := range list {
  66 + if list[i].ParentId > 0 {
  67 + parentIds = append(parentIds, list[i].ParentId)
  68 + }
  69 +
  70 + pList := list[i].PositionId
  71 + for i2 := range pList {
  72 + if pList[i2] > 0 {
  73 + positionIds = append(positionIds, pList[i2])
  74 + }
  75 + }
  76 + }
  77 +
  78 + // 获取上级
  79 + parentMap := map[int64]*domain.User{}
  80 + if len(parentIds) > 0 {
  81 + _, parentList, err := userRepo.Find(map[string]interface{}{"ids": parentIds})
  82 + if err != nil {
  83 + return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
  84 + }
  85 + for i := range parentList {
  86 + parentMap[parentList[i].Id] = parentList[i]
  87 + }
  88 + }
  89 +
  90 + // 获取职位
  91 + positionMap := map[int64]*domain.Position{}
  92 + if len(positionIds) > 0 {
  93 + _, positionList, err := positionRepo.Find(map[string]interface{}{"ids": positionIds})
  94 + if err != nil {
  95 + return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
  96 + }
  97 + for i := range positionList {
  98 + positionMap[positionList[i].Id] = positionList[i]
  99 + }
  100 + }
  101 +
  102 + adapters := make([]*adapter.UserResp, 0)
  103 + for i := range list {
  104 + adp := &adapter.UserResp{
  105 + User: list[i],
  106 + }
  107 + // 上级名称
  108 + if v, ok := parentMap[list[i].ParentId]; ok {
  109 + adp.ParentName = v.Name
  110 + }
  111 + // 职位名称数组
  112 + adp.PositionNames = make([]string, 0)
  113 + pList := list[i].PositionId
  114 + for i2 := range pList {
  115 + if v2, ok := positionMap[int64(pList[i2])]; ok {
  116 + adp.PositionNames = append(adp.PositionNames, v2.Name)
  117 + }
  118 + }
  119 + adapters = append(adapters, adp)
  120 + }
  121 +
57 if err := transactionContext.CommitTransaction(); err != nil { 122 if err := transactionContext.CommitTransaction(); err != nil {
58 return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) 123 return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
59 } 124 }
60 - return tool_funs.SimpleWrapGridMap(int64(count), list), nil 125 + return tool_funs.SimpleWrapGridMap(int64(count), adapters), nil
  126 +}
  127 +
  128 +// EditParentUser 保存上级
  129 +func (us *UserService) EditParentUser(in *command.EditParentCommand) error {
  130 + transactionContext, err := factory.ValidateStartTransaction(in)
  131 + if err != nil {
  132 + return err
  133 + }
  134 + defer func() {
  135 + transactionContext.RollbackTransaction()
  136 + }()
  137 +
  138 + hrbp, err := service.GetHRBP(transactionContext, in.CompanyId, in.OperatorId)
  139 + if err != nil {
  140 + return application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
  141 + }
  142 + if hrbp != 1 {
  143 + return application.ThrowError(application.BUSINESS_ERROR, "HRBP权限的员工才能操作")
  144 + }
  145 +
  146 + userRepo := factory.CreateUserRepository(map[string]interface{}{"transactionContext": transactionContext})
  147 + user, err := userRepo.FindOne(map[string]interface{}{"id": in.Id})
  148 + if err != nil {
  149 + return application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
  150 + }
  151 + // 上级ID是否存在
  152 + _, err = userRepo.FindOne(map[string]interface{}{"id": in.ParentId})
  153 + if err != nil {
  154 + return application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
  155 + }
  156 + user.ParentId = in.ParentId
  157 +
  158 + if _, err = userRepo.Update(user); err != nil {
  159 + return application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
  160 + }
  161 +
  162 + if err := transactionContext.CommitTransaction(); err != nil {
  163 + return application.ThrowError(application.TRANSACTION_ERROR, err.Error())
  164 + }
  165 + return nil
  166 +}
  167 +
  168 +func (us *UserService) ImportParentUser(in *command.ImportParentUserCommand) (interface{}, error) {
  169 + transactionContext, err := factory.ValidateStartTransaction(in)
  170 + if err != nil {
  171 + return nil, err
  172 + }
  173 + defer func() {
  174 + transactionContext.RollbackTransaction()
  175 + }()
  176 +
  177 + hrbp, err := service.GetHRBP(transactionContext, in.CompanyId, in.OperatorId)
  178 + if err != nil {
  179 + return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
  180 + }
  181 + if hrbp != 1 {
  182 + return nil, application.ThrowError(application.BUSINESS_ERROR, "HRBP权限的员工才能操作")
  183 + }
  184 + userRepo := factory.CreateUserRepository(map[string]interface{}{"transactionContext": transactionContext})
  185 +
  186 + userMap := map[string]*domain.User{}
  187 + accounts := make([]string, 0) // 全部账号数组(查询一次)
  188 + for i := range in.Data {
  189 + v := in.Data[i]
  190 + if len(v.Phone) == 0 || len(v.ParentPhone) == 0 {
  191 + continue
  192 + }
  193 + accounts = append(accounts, v.Phone)
  194 + accounts = append(accounts, v.ParentPhone)
  195 + }
  196 + if len(accounts) > 0 {
  197 + if _, users, err := userRepo.Find(map[string]interface{}{"accounts": accounts, "companyId": in.CompanyId}); err != nil {
  198 + return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
  199 + } else {
  200 + for i := range users {
  201 + userMap[users[i].Account] = users[i]
  202 + }
  203 + }
  204 + }
  205 +
  206 + for i := range in.Data {
  207 + v := in.Data[i]
  208 + if len(v.Phone) == 0 || len(v.ParentPhone) == 0 {
  209 + continue
  210 + }
  211 + if vCurrentUser, ok := userMap[v.Phone]; ok {
  212 + if vParentUser, ok := userMap[v.ParentPhone]; ok {
  213 + vCurrentUser.ParentId = vParentUser.Id
  214 +
  215 + // 更新上级数据
  216 + if _, err := userRepo.Update(vCurrentUser); err != nil {
  217 + return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
  218 + }
  219 + }
  220 + }
  221 + }
  222 +
  223 + if err := transactionContext.CommitTransaction(); err != nil {
  224 + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
  225 + }
  226 + return nil, nil
61 } 227 }
@@ -121,6 +121,9 @@ func (repo *UserRepository) Find(queryOptions map[string]interface{}) (int, []*d @@ -121,6 +121,9 @@ func (repo *UserRepository) Find(queryOptions map[string]interface{}) (int, []*d
121 if v, ok := queryOptions["account"]; ok { 121 if v, ok := queryOptions["account"]; ok {
122 query.Where("account like ?", v) 122 query.Where("account like ?", v)
123 } 123 }
  124 + if v, ok := queryOptions["accounts"]; ok {
  125 + query.Where("account in(?)", pg.In(v))
  126 + }
124 if v, ok := queryOptions["status"]; ok { 127 if v, ok := queryOptions["status"]; ok {
125 query.Where("status=?", v) 128 query.Where("status=?", v)
126 } 129 }
@@ -20,6 +20,15 @@ func (controller *TemplateImplController) TemplateQuestion() { @@ -20,6 +20,15 @@ func (controller *TemplateImplController) TemplateQuestion() {
20 controller.WriteExcel(fileBytes, "评估导入模板.xlsx") 20 controller.WriteExcel(fileBytes, "评估导入模板.xlsx")
21 } 21 }
22 22
  23 +func (controller *TemplateImplController) TemplateParentUser() {
  24 + fileBytes, err := ioutil.ReadFile("./templates/tpl_template_user.xlsx")
  25 + if err != nil {
  26 + controller.Response(nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, "未读取到模板文件"))
  27 + return
  28 + }
  29 + controller.WriteExcel(fileBytes, "直接上级导入模板.xlsx")
  30 +}
  31 +
23 func (controller *TemplateImplController) WriteExcel(fileBytes []byte, fileName string) { 32 func (controller *TemplateImplController) WriteExcel(fileBytes []byte, fileName string) {
24 controller.Ctx.Output.Header("Content-Disposition", "attachment;filename="+fileName) 33 controller.Ctx.Output.Header("Content-Disposition", "attachment;filename="+fileName)
25 controller.Ctx.Output.Header("Content-Description", "FileTransfer") 34 controller.Ctx.Output.Header("Content-Description", "FileTransfer")
@@ -3,10 +3,14 @@ package controllers @@ -3,10 +3,14 @@ package controllers
3 import ( 3 import (
4 "github.com/linmadan/egglib-go/core/application" 4 "github.com/linmadan/egglib-go/core/application"
5 "github.com/linmadan/egglib-go/web/beego" 5 "github.com/linmadan/egglib-go/web/beego"
  6 + "github.com/xuri/excelize/v2"
6 "gitlab.fjmaimaimai.com/allied-creation/performance/pkg/application/user" 7 "gitlab.fjmaimaimai.com/allied-creation/performance/pkg/application/user"
  8 + "gitlab.fjmaimaimai.com/allied-creation/performance/pkg/application/user/adapter"
  9 + "gitlab.fjmaimaimai.com/allied-creation/performance/pkg/application/user/command"
7 "gitlab.fjmaimaimai.com/allied-creation/performance/pkg/application/user/query" 10 "gitlab.fjmaimaimai.com/allied-creation/performance/pkg/application/user/query"
8 "gitlab.fjmaimaimai.com/allied-creation/performance/pkg/domain" 11 "gitlab.fjmaimaimai.com/allied-creation/performance/pkg/domain"
9 "gitlab.fjmaimaimai.com/allied-creation/performance/pkg/port/beego/middlewares" 12 "gitlab.fjmaimaimai.com/allied-creation/performance/pkg/port/beego/middlewares"
  13 + "strings"
10 ) 14 )
11 15
12 type UserController struct { 16 type UserController struct {
@@ -33,3 +37,97 @@ func (controller *UserController) ListByDepartment() { @@ -33,3 +37,97 @@ func (controller *UserController) ListByDepartment() {
33 controller.Response((&user.UserService{}).ListByDepartment(in)) 37 controller.Response((&user.UserService{}).ListByDepartment(in))
34 } 38 }
35 } 39 }
  40 +
  41 +func (controller *UserController) EditParentUser() {
  42 + in := &command.EditParentCommand{}
  43 + if err := controller.Unmarshal(in); err != nil {
  44 + controller.Response(nil, application.ThrowError(application.ARG_ERROR, err.Error()))
  45 + } else {
  46 + ua := middlewares.GetUser(controller.Ctx)
  47 + in.CompanyId = int(ua.CompanyId)
  48 + in.OperatorId = int(ua.UserId)
  49 + controller.Response(nil, (&user.UserService{}).EditParentUser(in))
  50 + }
  51 +}
  52 +
  53 +// ImportParentUser 导入用户上级
  54 +func (controller *UserController) ImportParentUser() {
  55 + in := &command.ImportParentUserCommand{}
  56 + if err := controller.Unmarshal(in); err != nil {
  57 + controller.Response(nil, application.ThrowError(application.ARG_ERROR, err.Error()))
  58 + } else {
  59 + if itcArray, err := controller.readExcelFormUserParent(); err != nil {
  60 + controller.Response(nil, application.ThrowError(application.ARG_ERROR, err.Error()))
  61 + } else {
  62 + ua := middlewares.GetUser(controller.Ctx)
  63 + in.CompanyId = int(ua.CompanyId)
  64 + in.OperatorId = int(ua.UserId)
  65 + in.Data = itcArray
  66 + if data, err := (&user.UserService{}).ImportParentUser(in); nil != err {
  67 + controller.Response(nil, err)
  68 + } else {
  69 + controller.Response(data, nil)
  70 + }
  71 + }
  72 + }
  73 +}
  74 +
  75 +func (controller *UserController) readExcelFormUserParent() ([]adapter.ImportParentUser, error) {
  76 + // 读取文件
  77 + _, header, err := controller.GetFile("file")
  78 + if err != nil {
  79 + controller.Response(nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, "上传错误:"+err.Error()))
  80 + return nil, err
  81 + }
  82 + file, err := header.Open()
  83 + if err != nil {
  84 + controller.Response(nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, "上传错误:"+err.Error()))
  85 + return nil, err
  86 + }
  87 + defer func() {
  88 + if err := file.Close(); err != nil {
  89 + return
  90 + }
  91 + }()
  92 +
  93 + reader, err := excelize.OpenReader(file)
  94 + if err != nil {
  95 + controller.Response(nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, "上传错误:"+err.Error()))
  96 + return nil, err
  97 + }
  98 +
  99 + index := reader.GetActiveSheetIndex()
  100 + rows, err := reader.GetRows(reader.GetSheetName(index))
  101 + if err != nil {
  102 + controller.Response(nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, "读取excel错误:"+err.Error()))
  103 + return nil, err
  104 + }
  105 + if len(rows) <= 0 {
  106 + return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, "文件内数据不能为空:"+err.Error())
  107 + }
  108 +
  109 + adapters := make([]adapter.ImportParentUser, 0)
  110 + for rowIndex, row := range rows {
  111 + if rowIndex < 2 { // 头2行不读取
  112 + continue
  113 + }
  114 + ipu := adapter.ImportParentUser{}
  115 + for colIndex, colCell := range row {
  116 + switch colIndex {
  117 + case 0:
  118 + ipu.Name = strings.TrimSpace(colCell) // 员工名称
  119 + case 1:
  120 + ipu.Phone = strings.TrimSpace(colCell) // 员工手机号码
  121 + case 2:
  122 + ipu.ParentName = strings.TrimSpace(colCell) // 直接上级名称
  123 + case 3:
  124 + ipu.ParentPhone = strings.TrimSpace(colCell) // 直接上级手机号码
  125 + }
  126 + }
  127 + adapters = append(adapters, ipu)
  128 + }
  129 + if len(adapters) <= 0 {
  130 + return adapters, application.ThrowError(application.INTERNAL_SERVER_ERROR, "文件内数据不能为空:"+err.Error())
  131 + }
  132 + return adapters, err
  133 +}
@@ -7,4 +7,6 @@ import ( @@ -7,4 +7,6 @@ import (
7 7
8 func init() { 8 func init() {
9 web.Router("/templates/tpl_template_question.xlsx", &controllers.TemplateImplController{}, "Get:TemplateQuestion") 9 web.Router("/templates/tpl_template_question.xlsx", &controllers.TemplateImplController{}, "Get:TemplateQuestion")
  10 + web.Router("/templates/tpl_template_user.xlsx", &controllers.TemplateImplController{}, "Get:TemplateParentUser")
  11 +
10 } 12 }
@@ -12,6 +12,9 @@ func init() { @@ -12,6 +12,9 @@ func init() {
12 web.NSBefore(filters.AllowCors(), middlewares.CheckAdminToken()), 12 web.NSBefore(filters.AllowCors(), middlewares.CheckAdminToken()),
13 web.NSRouter("/search", &controllers.UserController{}, "Post:ListUsers"), 13 web.NSRouter("/search", &controllers.UserController{}, "Post:ListUsers"),
14 web.NSRouter("/list-dep", &controllers.UserController{}, "Post:ListByDepartment"), 14 web.NSRouter("/list-dep", &controllers.UserController{}, "Post:ListByDepartment"),
  15 + web.NSRouter("/edit-parent", &controllers.UserController{}, "Put:EditParentUser"),
  16 + web.NSRouter("/edit-parent", &controllers.UserController{}, "Put:EditParentUser"),
  17 + web.NSRouter("/import-parent", &controllers.UserController{}, "Post:ImportParentUser"), // 直接上级导入
15 ) 18 )
16 web.AddNamespace(ns) 19 web.AddNamespace(ns)
17 } 20 }
不能预览此文件类型