package hr import ( "WiiCITMS/models/hr" "WiiGenerates/WiiCITMS/generates/v1/go/types" "WiiGoLibrary/apply/middle/process/v1" "WiiGoLibrary/framework/db/v1/utils/mssql/unique" "WiiGoLibrary/framework/hub/v1/dblib" "fmt" ) // AssignPositionRequest 为员工分配岗位的请求参数 type AssignPositionRequest struct { StaffGuid string `json:"staffGuid"` // 员工GUID OrganizationGuid string `json:"organizationGuid"` // 组织GUID PositionGuid string `json:"positionGuid"` // 岗位GUID(可选,如果为空则只绑定组织) IsLeader bool `json:"isLeader"` // 是否是组织负责人 RecordType int `json:"recordType"` // 关系类型:0-主部门/岗位,1-兼职部门/岗位 } // UpdateStaffPositionRequest 更新员工岗位的请求参数 type UpdateStaffPositionRequest struct { RecordGuid string `json:"recordGuid"` // 员工组织关系记录GUID PositionGuid string `json:"positionGuid"` // 岗位GUID IsLeader bool `json:"isLeader"` // 是否是组织负责人 RecordType int `json:"recordType"` // 关系类型:0-主部门/岗位,1-兼职部门/岗位 } // RemoveStaffPositionRequest 移除员工岗位的请求参数 type RemoveStaffPositionRequest struct { StaffGuid string `json:"staffGuid"` // 员工GUID OrganizationGuid string `json:"organizationGuid"` // 组织GUID } // StaffPositionRelDetail 员工岗位关系详情 type StaffPositionRelDetail struct { RecordGuid unique.UUID `json:"recordGuid"` // 关系记录GUID StaffGuid unique.UUID `json:"staffGuid"` // 员工GUID StaffName string `json:"staffName"` // 员工姓名 OrganizationGuid unique.UUID `json:"organizationGuid"` // 组织GUID OrganizationName string `json:"organizationName"` // 组织名称 PositionGuid unique.UUID `json:"positionGuid"` // 岗位GUID PositionName string `json:"positionName"` // 岗位名称 IsLeader bool `json:"isLeader"` // 是否是组织负责人 RecordType int `json:"recordType"` // 关系类型:0-主部门/岗位,1-兼职部门/岗位 } // AssignPosition 为员工分配岗位和组织 func AssignPosition(params AssignPositionRequest) (*StaffPositionRelDetail, *process.Process) { // 验证员工ID staffGuid, err := unique.FromString(params.StaffGuid) if err != nil { return nil, process.FailError(types.InvalidParamError, err) } // 验证组织ID orgGuid, err := unique.FromString(params.OrganizationGuid) if err != nil { return nil, process.FailError(types.InvalidParamError, err) } // 开始事务 tx := dblib.DBIns.DB.Begin() // 查询员工是否存在 staff := &hr.StaffModel{} r := tx.Where("RecordGuid = ? AND (RecordStatus & 524288) = 0", staffGuid).First(staff) if r.Error != nil { tx.Rollback() return nil, process.FailError(types.StaffNotFoundError, r.Error) } // 查询组织是否存在 org := &hr.OrganizationModel{} r = tx.Where("RecordGuid = ? AND (RecordStatus & 524288) = 0", orgGuid).First(org) if r.Error != nil { tx.Rollback() return nil, process.FailError(types.OrgNotFoundError, r.Error) } // 如果提供了岗位ID,则验证岗位是否存在且属于该组织 var position *hr.PositionModel if params.PositionGuid != "" { posGuid, err := unique.FromString(params.PositionGuid) if err != nil { tx.Rollback() return nil, process.FailError(types.InvalidParamError, err) } position = &hr.PositionModel{} r = tx.Where("RecordGuid = ? AND (RecordStatus & 524288) = 0", posGuid).First(position) if r.Error != nil { tx.Rollback() return nil, process.FailError(types.PositionNotFoundError, r.Error) } // 检查岗位是否与组织关联 var count int64 r = tx.Model(&hr.OrgPositionRelModel{}).Where( "OrganizationGuid = ? AND PositionGuid = ? AND (RecordStatus & 524288) = 0", orgGuid, posGuid, ).Count(&count) if r.Error != nil || count == 0 { tx.Rollback() return nil, process.FailError(types.InvalidPositionError, fmt.Errorf("岗位不属于指定组织")) } } // 检查是否已经存在员工与组织的关联 var existingRel hr.Staff2OrganizationModel relQuery := tx.Where( "ObjectGuid = ? AND TargetGuid = ? AND (RecordStatus & 524288) = 0", staffGuid, orgGuid, ).First(&existingRel) // 查找当前员工是否已有主部门关系 var currentMain hr.Staff2OrganizationModel hasMain := tx.Where("ObjectGuid = ? AND RecordType = 0 AND (RecordStatus & 524288) = 0", staffGuid).First(¤tMain).Error == nil if params.RecordType == 0 { // 分配主部门/岗位 if relQuery.Error == nil { // 已存在该组织的关联:将其设为主并更新信息 if params.PositionGuid != "" { posGuid, _ := unique.FromString(params.PositionGuid) existingRel.PositionGuid = posGuid } existingRel.IsLeader = params.IsLeader existingRel.RecordType = 0 if err := tx.Save(&existingRel).Error; err != nil { tx.Rollback() return nil, process.FailError(types.UpdateStaffError, err) } // 如果存在其他主部门,则降级 if hasMain && currentMain.RecordGuid != existingRel.RecordGuid { if err := tx.Model(&hr.Staff2OrganizationModel{}). Where("RecordGuid = ?", currentMain.RecordGuid). Update("RecordType", 1).Error; err != nil { tx.Rollback() return nil, process.FailError(types.UpdateStaffError, err) } } } else { if hasMain { // 已有主部门:若同组织,更新;否则切换主部门到新组织(不新增记录) if currentMain.TargetGuid == orgGuid { if params.PositionGuid != "" { posGuid, _ := unique.FromString(params.PositionGuid) currentMain.PositionGuid = posGuid } currentMain.IsLeader = params.IsLeader // 保持为主部门 if err := tx.Save(¤tMain).Error; err != nil { tx.Rollback() return nil, process.FailError(types.UpdateStaffError, err) } } else { // 切换主部门到新的组织 currentMain.TargetGuid = orgGuid if params.PositionGuid != "" { posGuid, _ := unique.FromString(params.PositionGuid) currentMain.PositionGuid = posGuid } else { currentMain.PositionGuid = unique.NilUUID } currentMain.IsLeader = params.IsLeader currentMain.RecordType = 0 if err := tx.Save(¤tMain).Error; err != nil { tx.Rollback() return nil, process.FailError(types.UpdateStaffError, err) } } existingRel = currentMain } else { // 不存在主部门:创建一条主部门关联 newRel := hr.Staff2OrganizationInstance() newRel.ObjectGuid = staffGuid newRel.TargetGuid = orgGuid newRel.RecordType = 0 newRel.IsLeader = params.IsLeader if params.PositionGuid != "" { posGuid, _ := unique.FromString(params.PositionGuid) newRel.PositionGuid = posGuid } if err := tx.Create(newRel).Error; err != nil { tx.Rollback() return nil, process.FailError(types.CreateStaffError, err) } existingRel = *newRel } } } else { // 分配兼职部门/岗位 if relQuery.Error == nil { // 已存在关联,更新为兼职 if params.PositionGuid != "" { posGuid, _ := unique.FromString(params.PositionGuid) existingRel.PositionGuid = posGuid } existingRel.IsLeader = params.IsLeader existingRel.RecordType = int16(params.RecordType) if err := tx.Save(&existingRel).Error; err != nil { tx.Rollback() return nil, process.FailError(types.UpdateStaffError, err) } } else { // 不存在关联,创建兼职记录 newRel := hr.Staff2OrganizationInstance() newRel.ObjectGuid = staffGuid newRel.TargetGuid = orgGuid if params.RecordType == 0 { newRel.RecordType = 1 } else { newRel.RecordType = int16(params.RecordType) } newRel.IsLeader = params.IsLeader if params.PositionGuid != "" { posGuid, _ := unique.FromString(params.PositionGuid) newRel.PositionGuid = posGuid } if err := tx.Create(newRel).Error; err != nil { tx.Rollback() return nil, process.FailError(types.CreateStaffError, err) } existingRel = *newRel } } // 提交事务 tx.Commit() // 构建返回结果 result := &StaffPositionRelDetail{ RecordGuid: existingRel.RecordGuid, StaffGuid: staff.RecordGuid, StaffName: staff.StaffName, OrganizationGuid: org.RecordGuid, OrganizationName: org.OrganizationName, IsLeader: existingRel.IsLeader, RecordType: int(existingRel.RecordType), } if params.PositionGuid != "" && position != nil { result.PositionGuid = position.RecordGuid result.PositionName = position.PositionName } return result, process.Success(200) } // UpdateStaffPosition 更新员工岗位关系 func UpdateStaffPosition(params UpdateStaffPositionRequest) (*StaffPositionRelDetail, *process.Process) { // 验证关系记录ID relGuid, err := unique.FromString(params.RecordGuid) if err != nil { return nil, process.FailError(types.InvalidParamError, err) } // 开始事务 tx := dblib.DBIns.DB.Begin() // 查询关系记录是否存在 rel := &hr.Staff2OrganizationModel{} r := tx.Where("RecordGuid = ? AND (RecordStatus & 524288) = 0", relGuid).First(rel) if r.Error != nil { tx.Rollback() return nil, process.FailError(types.OrgStaffRelNotFoundError, r.Error) } // 如果提供了岗位ID,则验证岗位是否存在 var position *hr.PositionModel if params.PositionGuid != "" { posGuid, err := unique.FromString(params.PositionGuid) if err != nil { tx.Rollback() return nil, process.FailError(types.InvalidParamError, err) } position = &hr.PositionModel{} r = tx.Where("RecordGuid = ? AND (RecordStatus & 524288) = 0", posGuid).First(position) if r.Error != nil { tx.Rollback() return nil, process.FailError(types.PositionNotFoundError, r.Error) } // 检查岗位是否与组织关联 var count int64 r = tx.Model(&hr.OrgPositionRelModel{}).Where( "OrganizationGuid = ? AND PositionGuid = ? AND (RecordStatus & 524288) = 0", rel.TargetGuid, posGuid, ).Count(&count) if r.Error != nil || count == 0 { tx.Rollback() return nil, process.FailError(types.InvalidPositionError, fmt.Errorf("岗位不属于指定组织")) } rel.PositionGuid = posGuid } // 更新其他字段 rel.IsLeader = params.IsLeader rel.RecordType = int16(params.RecordType) // 更新记录 r = tx.Save(rel) if r.Error != nil { tx.Rollback() return nil, process.FailError(types.UpdateStaffError, r.Error) } // 如果这是主部门/岗位,则将其他关系更新为非主部门/岗位 if params.RecordType == 0 { r = tx.Model(&hr.Staff2OrganizationModel{}). Where("ObjectGuid = ? AND RecordGuid != ? AND RecordType = 0 AND (RecordStatus & 524288) = 0", rel.ObjectGuid, rel.RecordGuid). Update("RecordType", 1) if r.Error != nil { tx.Rollback() return nil, process.FailError(types.UpdateStaffError, r.Error) } } // 提交事务 tx.Commit() // 查询员工和组织信息以构建返回结果 staff := &hr.StaffModel{} dblib.DBIns.DB.Where("RecordGuid = ?", rel.ObjectGuid).First(staff) org := &hr.OrganizationModel{} dblib.DBIns.DB.Where("RecordGuid = ?", rel.TargetGuid).First(org) // 构建返回结果 result := &StaffPositionRelDetail{ RecordGuid: rel.RecordGuid, StaffGuid: staff.RecordGuid, StaffName: staff.StaffName, OrganizationGuid: org.RecordGuid, OrganizationName: org.OrganizationName, IsLeader: rel.IsLeader, RecordType: int(rel.RecordType), } if position != nil { result.PositionGuid = position.RecordGuid result.PositionName = position.PositionName } else if rel.PositionGuid != unique.NilUUID { pos := &hr.PositionModel{} dblib.DBIns.DB.Where("RecordGuid = ?", rel.PositionGuid).First(pos) result.PositionGuid = pos.RecordGuid result.PositionName = pos.PositionName } return result, process.Success(200) } // RemoveStaffPosition 移除员工的组织和岗位关联 func RemoveStaffPosition(params RemoveStaffPositionRequest) *process.Process { // 验证员工ID staffGuid, err := unique.FromString(params.StaffGuid) if err != nil { return process.FailError(types.InvalidParamError, err) } // 验证组织ID orgGuid, err := unique.FromString(params.OrganizationGuid) if err != nil { return process.FailError(types.InvalidParamError, err) } // 查询关系记录是否存在 var rel hr.Staff2OrganizationModel r := dblib.DBIns.DB.Where( "ObjectGuid = ? AND TargetGuid = ? AND (RecordStatus & 524288) = 0", staffGuid, orgGuid, ).First(&rel) if r.Error != nil { return process.FailError(types.OrgStaffRelNotFoundError, r.Error) } // 检查是否是员工的最后一个组织关联 var count int64 r = dblib.DBIns.DB.Model(&hr.Staff2OrganizationModel{}). Where("ObjectGuid = ? AND (RecordStatus & 524288) = 0", staffGuid). Count(&count) if r.Error != nil { return process.FailError(types.QueryStaffError, r.Error) } if count <= 1 { return process.FailError(types.LastOrgRelError, fmt.Errorf("无法移除员工的最后一个组织关联")) } // 如果是主部门/岗位,需要将另一个关系设为主部门/岗位 if rel.RecordType == 0 { // 查找一个非主部门/岗位关系 var otherRel hr.Staff2OrganizationModel r = dblib.DBIns.DB.Where( "ObjectGuid = ? AND RecordGuid != ? AND (RecordStatus & 524288) = 0", staffGuid, rel.RecordGuid, ).First(&otherRel) if r.Error == nil { // 将此关系设为主部门/岗位 otherRel.RecordType = 0 dblib.DBIns.DB.Save(&otherRel) } } // 软删除关系记录 - 直接使用SQL操作 r = dblib.DBIns.DB.Exec("UPDATE "+hr.Staff2OrganizationTable+" SET RecordStatus = RecordStatus | 524288 WHERE RecordGuid = ?", rel.RecordGuid) if r.Error != nil { return process.FailError(types.DeleteStaffError, r.Error) } return process.Success(200) } // GetStaffPositions 获取员工的所有组织和岗位关联 func GetStaffPositions(staffGuid string) ([]StaffPositionRelDetail, *process.Process) { // 验证员工ID guid, err := unique.FromString(staffGuid) if err != nil { return nil, process.FailError(types.InvalidParamError, err) } // 查询员工是否存在 staff := &hr.StaffModel{} r := dblib.DBIns.DB.Where("RecordGuid = ? AND (RecordStatus & 524288) = 0", guid).First(staff) if r.Error != nil { return nil, process.FailError(types.StaffNotFoundError, r.Error) } // 查询员工的所有组织和岗位关联 result := make([]StaffPositionRelDetail, 0) rows, err := dblib.DBIns.DB.Raw(` SELECT so.RecordGuid, o.RecordGuid as OrgGuid, o.OrganizationName, p.RecordGuid as PosGuid, p.PositionName, so.IsLeader, so.RecordType FROM `+hr.Staff2OrganizationTable+` so JOIN `+hr.OrganizationTable+` o ON so.TargetGuid = o.RecordGuid LEFT JOIN `+hr.PositionTable+` p ON so.PositionGuid = p.RecordGuid WHERE so.ObjectGuid = ? AND (so.RecordStatus & 524288) = 0 AND (o.RecordStatus & 524288) = 0 ORDER BY so.RecordType ASC `, guid).Rows() if err != nil { return nil, process.FailError(types.QueryStaffError, err) } defer rows.Close() for rows.Next() { var rel StaffPositionRelDetail var relGuid, orgGuid, posGuid unique.UUID var recordType int16 var isLeader bool err := rows.Scan( &relGuid, &orgGuid, &rel.OrganizationName, &posGuid, &rel.PositionName, &isLeader, &recordType, ) if err != nil { continue } rel.RecordGuid = relGuid rel.StaffGuid, _ = unique.FromString(staffGuid) rel.StaffName = staff.StaffName rel.OrganizationGuid = orgGuid rel.IsLeader = isLeader rel.RecordType = int(recordType) if posGuid != unique.NilUUID { rel.PositionGuid = posGuid } result = append(result, rel) } return result, process.Success(200) }