作者 郑周

1. 编辑通讯录的上级

2. 增到通讯录上级数据导入
  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 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 +}
@@ -140,7 +140,7 @@ func (us *UserService) EditParentUser(in *command.EditParentCommand) error { @@ -140,7 +140,7 @@ func (us *UserService) EditParentUser(in *command.EditParentCommand) error {
140 return application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) 140 return application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
141 } 141 }
142 if hrbp != 1 { 142 if hrbp != 1 {
143 - return application.ThrowError(application.BUSINESS_ERROR, "拥有HRBP权限才能编辑") 143 + return application.ThrowError(application.BUSINESS_ERROR, "HRBP权限的员工才能操作")
144 } 144 }
145 145
146 userRepo := factory.CreateUserRepository(map[string]interface{}{"transactionContext": transactionContext}) 146 userRepo := factory.CreateUserRepository(map[string]interface{}{"transactionContext": transactionContext})
@@ -164,3 +164,64 @@ func (us *UserService) EditParentUser(in *command.EditParentCommand) error { @@ -164,3 +164,64 @@ func (us *UserService) EditParentUser(in *command.EditParentCommand) error {
164 } 164 }
165 return nil 165 return nil
166 } 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
  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,11 +3,14 @@ package controllers @@ -3,11 +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"
7 "gitlab.fjmaimaimai.com/allied-creation/performance/pkg/application/user/command" 9 "gitlab.fjmaimaimai.com/allied-creation/performance/pkg/application/user/command"
8 "gitlab.fjmaimaimai.com/allied-creation/performance/pkg/application/user/query" 10 "gitlab.fjmaimaimai.com/allied-creation/performance/pkg/application/user/query"
9 "gitlab.fjmaimaimai.com/allied-creation/performance/pkg/domain" 11 "gitlab.fjmaimaimai.com/allied-creation/performance/pkg/domain"
10 "gitlab.fjmaimaimai.com/allied-creation/performance/pkg/port/beego/middlewares" 12 "gitlab.fjmaimaimai.com/allied-creation/performance/pkg/port/beego/middlewares"
  13 + "strings"
11 ) 14 )
12 15
13 type UserController struct { 16 type UserController struct {
@@ -46,3 +49,85 @@ func (controller *UserController) EditParentUser() { @@ -46,3 +49,85 @@ func (controller *UserController) EditParentUser() {
46 controller.Response(nil, (&user.UserService{}).EditParentUser(in)) 49 controller.Response(nil, (&user.UserService{}).EditParentUser(in))
47 } 50 }
48 } 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 }
@@ -13,6 +13,8 @@ func init() { @@ -13,6 +13,8 @@ func init() {
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"), 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"), // 直接上级导入
16 ) 18 )
17 web.AddNamespace(ns) 19 web.AddNamespace(ns)
18 } 20 }
不能预览此文件类型