作者 郑周

Merge branch 'dev-zhengzhou' into test

... ... @@ -113,3 +113,31 @@ func (rs *RoleUserService) ListRole(in *command.UserRoleQueryCommand) (interface
}
return tool_funs.SimpleWrapGridMap(total, tempList), nil
}
// GetHRBP 当前操作人是否拥有HRBP权限
func GetHRBP(transactionContext application.TransactionContext, companyId int, operatorId int) (int, error) {
roleRepo := factory.CreateRoleRepository(map[string]interface{}{"transactionContext": transactionContext})
roleUserRepo := factory.CreateRoleUserRepository(map[string]interface{}{"transactionContext": transactionContext})
_, roleList, err := roleRepo.Find(map[string]interface{}{"type": domain.RoleTypeSystem, "companyId": companyId})
if err != nil {
return -1, application.ThrowError(application.INTERNAL_SERVER_ERROR, "获取角色信息列表"+err.Error())
}
_, userRoleList, err := roleUserRepo.Find(map[string]interface{}{"companyId": companyId, "userId": operatorId})
if err != nil {
return -1, application.ThrowError(application.INTERNAL_SERVER_ERROR, "获取用户的角色信息列表"+err.Error())
}
// 拥有HRBP权限
hrbp := -1
for _, v := range userRoleList {
for _, v2 := range roleList {
if v.RoleId == v2.Id {
hrbp = 1
break
}
}
if hrbp == 1 {
break
}
}
return hrbp, nil
}
... ...
package adapter
type ImportParentUser struct {
Phone string `json:"phone"` // 用户手机号码
Name string `json:"name"` // 用户名称
ParentPhone string `json:"parentPhone"` // 上级手机号码
ParentName string `json:"parentName"` // 上级名称
}
... ...
package adapter
import "gitlab.fjmaimaimai.com/allied-creation/performance/pkg/domain"
type UserResp struct {
*domain.User
ParentName string `json:"parentName"` // 上级名称
PositionNames []string `json:"positionNames"` // 职位名称
}
... ...
package command
import (
"github.com/beego/beego/v2/core/validation"
)
type EditParentCommand struct {
Id int64 `cname:"用户ID" json:"id,string" valid:"Required"`
ParentId int64 `cname:"上级ID" json:"parentId,string" valid:"Required"`
CompanyId int `cname:"公司ID" json:"companyId"`
OperatorId int `cname:"操作人ID" json:"operatorId"`
}
func (in *EditParentCommand) Valid(*validation.Validation) {
}
... ...
package command
import (
"github.com/beego/beego/v2/core/validation"
"gitlab.fjmaimaimai.com/allied-creation/performance/pkg/application/user/adapter"
)
type ImportUserCommand struct {
AddUsers []SaveUserCommand `json:"add"`
EditUsers []SaveUserCommand `json:"edit"`
}
// ImportParentUserCommand 导入直接上级
type ImportParentUserCommand struct {
CompanyId int `cname:"公司ID" json:"companyId"`
OperatorId int `cname:"操作人ID" json:"operatorId"`
Data []adapter.ImportParentUser `cname:"数据" json:"-"` // 文件中读取到的数据
}
func (in *ImportParentUserCommand) Valid(_ *validation.Validation) {
}
... ...
... ... @@ -4,6 +4,9 @@ import (
"github.com/linmadan/egglib-go/core/application"
"github.com/linmadan/egglib-go/utils/tool_funs"
"gitlab.fjmaimaimai.com/allied-creation/performance/pkg/application/factory"
service "gitlab.fjmaimaimai.com/allied-creation/performance/pkg/application/role"
"gitlab.fjmaimaimai.com/allied-creation/performance/pkg/application/user/adapter"
"gitlab.fjmaimaimai.com/allied-creation/performance/pkg/application/user/command"
"gitlab.fjmaimaimai.com/allied-creation/performance/pkg/application/user/query"
"gitlab.fjmaimaimai.com/allied-creation/performance/pkg/domain"
)
... ... @@ -46,6 +49,8 @@ func (us *UserService) ListByDepartment(in *query.ListByDepartmentQuery) (interf
}()
userRepo := factory.CreateUserRepository(map[string]interface{}{"transactionContext": transactionContext})
positionRepo := factory.CreatePositionRepository(map[string]interface{}{"transactionContext": transactionContext})
inMap := tool_funs.SimpleStructToMap(in)
if in.DepartmentId == 0 {
delete(inMap, "departmentId") // 删除部门ID字段
... ... @@ -54,8 +59,169 @@ func (us *UserService) ListByDepartment(in *query.ListByDepartmentQuery) (interf
if err != nil {
return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
}
parentIds := make([]int64, 0) // 上级ID
positionIds := make([]int, 0) // 职位ID
for i := range list {
if list[i].ParentId > 0 {
parentIds = append(parentIds, list[i].ParentId)
}
pList := list[i].PositionId
for i2 := range pList {
if pList[i2] > 0 {
positionIds = append(positionIds, pList[i2])
}
}
}
// 获取上级
parentMap := map[int64]*domain.User{}
if len(parentIds) > 0 {
_, parentList, err := userRepo.Find(map[string]interface{}{"ids": parentIds})
if err != nil {
return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
}
for i := range parentList {
parentMap[parentList[i].Id] = parentList[i]
}
}
// 获取职位
positionMap := map[int64]*domain.Position{}
if len(positionIds) > 0 {
_, positionList, err := positionRepo.Find(map[string]interface{}{"ids": positionIds})
if err != nil {
return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
}
for i := range positionList {
positionMap[positionList[i].Id] = positionList[i]
}
}
adapters := make([]*adapter.UserResp, 0)
for i := range list {
adp := &adapter.UserResp{
User: list[i],
}
// 上级名称
if v, ok := parentMap[list[i].ParentId]; ok {
adp.ParentName = v.Name
}
// 职位名称数组
adp.PositionNames = make([]string, 0)
pList := list[i].PositionId
for i2 := range pList {
if v2, ok := positionMap[int64(pList[i2])]; ok {
adp.PositionNames = append(adp.PositionNames, v2.Name)
}
}
adapters = append(adapters, adp)
}
if err := transactionContext.CommitTransaction(); err != nil {
return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
}
return tool_funs.SimpleWrapGridMap(int64(count), list), nil
return tool_funs.SimpleWrapGridMap(int64(count), adapters), nil
}
// EditParentUser 保存上级
func (us *UserService) EditParentUser(in *command.EditParentCommand) error {
transactionContext, err := factory.ValidateStartTransaction(in)
if err != nil {
return err
}
defer func() {
transactionContext.RollbackTransaction()
}()
hrbp, err := service.GetHRBP(transactionContext, in.CompanyId, in.OperatorId)
if err != nil {
return application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
}
if hrbp != 1 {
return application.ThrowError(application.BUSINESS_ERROR, "HRBP权限的员工才能操作")
}
userRepo := factory.CreateUserRepository(map[string]interface{}{"transactionContext": transactionContext})
user, err := userRepo.FindOne(map[string]interface{}{"id": in.Id})
if err != nil {
return application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
}
// 上级ID是否存在
_, err = userRepo.FindOne(map[string]interface{}{"id": in.ParentId})
if err != nil {
return application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
}
user.ParentId = in.ParentId
if _, err = userRepo.Update(user); err != nil {
return application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
}
if err := transactionContext.CommitTransaction(); err != nil {
return application.ThrowError(application.TRANSACTION_ERROR, err.Error())
}
return nil
}
func (us *UserService) ImportParentUser(in *command.ImportParentUserCommand) (interface{}, error) {
transactionContext, err := factory.ValidateStartTransaction(in)
if err != nil {
return nil, err
}
defer func() {
transactionContext.RollbackTransaction()
}()
hrbp, err := service.GetHRBP(transactionContext, in.CompanyId, in.OperatorId)
if err != nil {
return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
}
if hrbp != 1 {
return nil, application.ThrowError(application.BUSINESS_ERROR, "HRBP权限的员工才能操作")
}
userRepo := factory.CreateUserRepository(map[string]interface{}{"transactionContext": transactionContext})
userMap := map[string]*domain.User{}
accounts := make([]string, 0) // 全部账号数组(查询一次)
for i := range in.Data {
v := in.Data[i]
if len(v.Phone) == 0 || len(v.ParentPhone) == 0 {
continue
}
accounts = append(accounts, v.Phone)
accounts = append(accounts, v.ParentPhone)
}
if len(accounts) > 0 {
if _, users, err := userRepo.Find(map[string]interface{}{"accounts": accounts, "companyId": in.CompanyId}); err != nil {
return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
} else {
for i := range users {
userMap[users[i].Account] = users[i]
}
}
}
for i := range in.Data {
v := in.Data[i]
if len(v.Phone) == 0 || len(v.ParentPhone) == 0 {
continue
}
if vCurrentUser, ok := userMap[v.Phone]; ok {
if vParentUser, ok := userMap[v.ParentPhone]; ok {
vCurrentUser.ParentId = vParentUser.Id
// 更新上级数据
if _, err := userRepo.Update(vCurrentUser); err != nil {
return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
}
}
}
}
if err := transactionContext.CommitTransaction(); err != nil {
return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
}
return nil, nil
}
... ...
... ... @@ -121,6 +121,9 @@ func (repo *UserRepository) Find(queryOptions map[string]interface{}) (int, []*d
if v, ok := queryOptions["account"]; ok {
query.Where("account like ?", v)
}
if v, ok := queryOptions["accounts"]; ok {
query.Where("account in(?)", pg.In(v))
}
if v, ok := queryOptions["status"]; ok {
query.Where("status=?", v)
}
... ...
... ... @@ -20,6 +20,15 @@ func (controller *TemplateImplController) TemplateQuestion() {
controller.WriteExcel(fileBytes, "评估导入模板.xlsx")
}
func (controller *TemplateImplController) TemplateParentUser() {
fileBytes, err := ioutil.ReadFile("./templates/tpl_template_user.xlsx")
if err != nil {
controller.Response(nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, "未读取到模板文件"))
return
}
controller.WriteExcel(fileBytes, "直接上级导入模板.xlsx")
}
func (controller *TemplateImplController) WriteExcel(fileBytes []byte, fileName string) {
controller.Ctx.Output.Header("Content-Disposition", "attachment;filename="+fileName)
controller.Ctx.Output.Header("Content-Description", "FileTransfer")
... ...
... ... @@ -3,10 +3,14 @@ package controllers
import (
"github.com/linmadan/egglib-go/core/application"
"github.com/linmadan/egglib-go/web/beego"
"github.com/xuri/excelize/v2"
"gitlab.fjmaimaimai.com/allied-creation/performance/pkg/application/user"
"gitlab.fjmaimaimai.com/allied-creation/performance/pkg/application/user/adapter"
"gitlab.fjmaimaimai.com/allied-creation/performance/pkg/application/user/command"
"gitlab.fjmaimaimai.com/allied-creation/performance/pkg/application/user/query"
"gitlab.fjmaimaimai.com/allied-creation/performance/pkg/domain"
"gitlab.fjmaimaimai.com/allied-creation/performance/pkg/port/beego/middlewares"
"strings"
)
type UserController struct {
... ... @@ -33,3 +37,97 @@ func (controller *UserController) ListByDepartment() {
controller.Response((&user.UserService{}).ListByDepartment(in))
}
}
func (controller *UserController) EditParentUser() {
in := &command.EditParentCommand{}
if err := controller.Unmarshal(in); err != nil {
controller.Response(nil, application.ThrowError(application.ARG_ERROR, err.Error()))
} else {
ua := middlewares.GetUser(controller.Ctx)
in.CompanyId = int(ua.CompanyId)
in.OperatorId = int(ua.UserId)
controller.Response(nil, (&user.UserService{}).EditParentUser(in))
}
}
// ImportParentUser 导入用户上级
func (controller *UserController) ImportParentUser() {
in := &command.ImportParentUserCommand{}
if err := controller.Unmarshal(in); err != nil {
controller.Response(nil, application.ThrowError(application.ARG_ERROR, err.Error()))
} else {
if itcArray, err := controller.readExcelFormUserParent(); err != nil {
controller.Response(nil, application.ThrowError(application.ARG_ERROR, err.Error()))
} else {
ua := middlewares.GetUser(controller.Ctx)
in.CompanyId = int(ua.CompanyId)
in.OperatorId = int(ua.UserId)
in.Data = itcArray
if data, err := (&user.UserService{}).ImportParentUser(in); nil != err {
controller.Response(nil, err)
} else {
controller.Response(data, nil)
}
}
}
}
func (controller *UserController) readExcelFormUserParent() ([]adapter.ImportParentUser, error) {
// 读取文件
_, header, err := controller.GetFile("file")
if err != nil {
controller.Response(nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, "上传错误:"+err.Error()))
return nil, err
}
file, err := header.Open()
if err != nil {
controller.Response(nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, "上传错误:"+err.Error()))
return nil, err
}
defer func() {
if err := file.Close(); err != nil {
return
}
}()
reader, err := excelize.OpenReader(file)
if err != nil {
controller.Response(nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, "上传错误:"+err.Error()))
return nil, err
}
index := reader.GetActiveSheetIndex()
rows, err := reader.GetRows(reader.GetSheetName(index))
if err != nil {
controller.Response(nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, "读取excel错误:"+err.Error()))
return nil, err
}
if len(rows) <= 0 {
return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, "文件内数据不能为空:"+err.Error())
}
adapters := make([]adapter.ImportParentUser, 0)
for rowIndex, row := range rows {
if rowIndex < 2 { // 头2行不读取
continue
}
ipu := adapter.ImportParentUser{}
for colIndex, colCell := range row {
switch colIndex {
case 0:
ipu.Name = strings.TrimSpace(colCell) // 员工名称
case 1:
ipu.Phone = strings.TrimSpace(colCell) // 员工手机号码
case 2:
ipu.ParentName = strings.TrimSpace(colCell) // 直接上级名称
case 3:
ipu.ParentPhone = strings.TrimSpace(colCell) // 直接上级手机号码
}
}
adapters = append(adapters, ipu)
}
if len(adapters) <= 0 {
return adapters, application.ThrowError(application.INTERNAL_SERVER_ERROR, "文件内数据不能为空:"+err.Error())
}
return adapters, err
}
... ...
... ... @@ -7,4 +7,6 @@ import (
func init() {
web.Router("/templates/tpl_template_question.xlsx", &controllers.TemplateImplController{}, "Get:TemplateQuestion")
web.Router("/templates/tpl_template_user.xlsx", &controllers.TemplateImplController{}, "Get:TemplateParentUser")
}
... ...
... ... @@ -12,6 +12,9 @@ func init() {
web.NSBefore(filters.AllowCors(), middlewares.CheckAdminToken()),
web.NSRouter("/search", &controllers.UserController{}, "Post:ListUsers"),
web.NSRouter("/list-dep", &controllers.UserController{}, "Post:ListByDepartment"),
web.NSRouter("/edit-parent", &controllers.UserController{}, "Put:EditParentUser"),
web.NSRouter("/edit-parent", &controllers.UserController{}, "Put:EditParentUser"),
web.NSRouter("/import-parent", &controllers.UserController{}, "Post:ImportParentUser"), // 直接上级导入
)
web.AddNamespace(ns)
}
... ...
不能预览此文件类型