505 lines
16 KiB
Go
505 lines
16 KiB
Go
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)
|
||
}
|