优化backend端相关功能
This commit is contained in:
@@ -519,6 +519,12 @@ func (c *BackendAdminUserController) EditUser() {
|
||||
|
||||
// DeleteUser 删除后台租户用户
|
||||
// DELETE /backend/deleteUser/:id
|
||||
//
|
||||
// 用户管理里的账号属于租户层面的登录凭证(yz_system_tenant_user),与员工
|
||||
//(yz_backend_employee)、人事档案(yz_backend_employee_file)、通讯录
|
||||
//(yz_backend_erp_contact)是三份不同用途的数据:账号只用于登录系统,员工与档案属于企业数据。
|
||||
// 因此这里只解除登录绑定,不做任何级联操作——删除账号不会影响员工档案和通讯录记录。
|
||||
// 员工侧的离职/禁用走 deleteEmployee,档案侧的离职走 employeefile/delete。
|
||||
func (c *BackendAdminUserController) DeleteUser() {
|
||||
idStr := c.Ctx.Input.Param(":id")
|
||||
id, _ := strconv.ParseUint(idStr, 10, 64)
|
||||
|
||||
@@ -114,13 +114,14 @@ func (c *BackendAuthController) LoginBackend() {
|
||||
"data": map[string]interface{}{
|
||||
"token": token,
|
||||
"user": map[string]interface{}{
|
||||
"id": loginUser.ID,
|
||||
"account": loginUser.Account,
|
||||
"name": loginUser.Name,
|
||||
"tid": loginUser.Tid,
|
||||
"rid": loginUser.Rid,
|
||||
"avatar": loginUser.Avatar,
|
||||
"role_name": loginUser.RoleName,
|
||||
"id": loginUser.ID,
|
||||
"account": loginUser.Account,
|
||||
"name": loginUser.Name,
|
||||
"tid": loginUser.Tid,
|
||||
"tenant_name": loginUser.TenantName,
|
||||
"rid": loginUser.Rid,
|
||||
"avatar": loginUser.Avatar,
|
||||
"role_name": loginUser.RoleName,
|
||||
},
|
||||
},
|
||||
})
|
||||
@@ -171,17 +172,25 @@ func (c *BackendAuthController) GetCurrentUser() {
|
||||
name = strings.TrimSpace(*tenantUser.Name)
|
||||
}
|
||||
|
||||
// 查询当前租户名称
|
||||
tenantName := ""
|
||||
var tenant models.SystemTenant
|
||||
if err := models.Orm.QueryTable(new(models.SystemTenant)).Filter("id", claims.TenantId).One(&tenant); err == nil {
|
||||
tenantName = strings.TrimSpace(tenant.TenantName)
|
||||
}
|
||||
|
||||
c.serveJSON(map[string]interface{}{
|
||||
"code": 200,
|
||||
"msg": "success",
|
||||
"data": map[string]interface{}{
|
||||
"id": tenantUser.Uid,
|
||||
"account": account,
|
||||
"name": name,
|
||||
"tid": tenantUser.Tid,
|
||||
"rid": 0,
|
||||
"avatar": "",
|
||||
"role_name": "",
|
||||
"id": tenantUser.Uid,
|
||||
"account": account,
|
||||
"name": name,
|
||||
"tid": tenantUser.Tid,
|
||||
"tenant_name": tenantName,
|
||||
"rid": 0,
|
||||
"avatar": "",
|
||||
"role_name": "",
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
@@ -66,6 +66,7 @@ type erpContactDTO struct {
|
||||
WorkPhone string `json:"work_phone"`
|
||||
Email string `json:"email"`
|
||||
Wechat string `json:"wechat"`
|
||||
QQ string `json:"qq"`
|
||||
Avatar string `json:"avatar"`
|
||||
CompanyName string `json:"company_name"`
|
||||
DeptName string `json:"dept_name"`
|
||||
@@ -116,6 +117,7 @@ func (c *BackendErpContactController) List() {
|
||||
cond = cond.Or("phone__contains", keyword)
|
||||
cond = cond.Or("email__contains", keyword)
|
||||
cond = cond.Or("wechat__contains", keyword)
|
||||
cond = cond.Or("qq__contains", keyword)
|
||||
qs = qs.SetCond(cond)
|
||||
}
|
||||
|
||||
@@ -126,7 +128,7 @@ func (c *BackendErpContactController) List() {
|
||||
}
|
||||
|
||||
var rows []models.BackendErpContact
|
||||
_, err = qs.OrderBy("-is_starred", "sort", "-id").
|
||||
_, err = qs.OrderBy("-is_starred", "contact_name", "-id").
|
||||
Limit(pageSize, (page-1)*pageSize).
|
||||
All(&rows)
|
||||
if err != nil {
|
||||
@@ -189,6 +191,7 @@ func (c *BackendErpContactController) Create() {
|
||||
workPhone, _ := c.contactGetStringValue(body, "work_phone")
|
||||
email, _ := c.contactGetStringValue(body, "email")
|
||||
wechat, _ := c.contactGetStringValue(body, "wechat")
|
||||
qq, _ := c.contactGetStringValue(body, "qq")
|
||||
avatar, _ := c.contactGetStringValue(body, "avatar")
|
||||
companyName, _ := c.contactGetStringValue(body, "company_name")
|
||||
deptName, _ := c.contactGetStringValue(body, "dept_name")
|
||||
@@ -211,6 +214,7 @@ func (c *BackendErpContactController) Create() {
|
||||
WorkPhone: contactStrPtr(workPhone),
|
||||
Email: contactStrPtr(email),
|
||||
Wechat: contactStrPtr(wechat),
|
||||
QQ: contactStrPtr(qq),
|
||||
Avatar: contactStrPtr(avatar),
|
||||
CompanyName: contactStrPtr(companyName),
|
||||
DeptName: contactStrPtr(deptName),
|
||||
@@ -281,6 +285,9 @@ func (c *BackendErpContactController) Update() {
|
||||
if v, has := c.contactGetStringValue(body, "wechat"); has {
|
||||
update["wechat"] = contactNullableString(v)
|
||||
}
|
||||
if v, has := c.contactGetStringValue(body, "qq"); has {
|
||||
update["qq"] = contactNullableString(v)
|
||||
}
|
||||
if v, has := c.contactGetStringValue(body, "avatar"); has {
|
||||
update["avatar"] = contactNullableString(v)
|
||||
}
|
||||
@@ -555,6 +562,7 @@ func (c *BackendErpContactController) contactDTO(row models.BackendErpContact) e
|
||||
WorkPhone: contactDerefString(row.WorkPhone),
|
||||
Email: contactDerefString(row.Email),
|
||||
Wechat: contactDerefString(row.Wechat),
|
||||
QQ: contactDerefString(row.QQ),
|
||||
Avatar: contactDerefString(row.Avatar),
|
||||
CompanyName: contactDerefString(row.CompanyName),
|
||||
DeptName: contactDerefString(row.DeptName),
|
||||
@@ -571,11 +579,31 @@ func (c *BackendErpContactController) contactDTO(row models.BackendErpContact) e
|
||||
|
||||
// --- Sync from Employee ---
|
||||
|
||||
// SyncContactOnEmployeeCreate 员工创建后同步到通讯录(由 ERP 控制器调用)
|
||||
// SyncContactOnEmployeeCreate 员工创建后同步到通讯录(由组织架构控制器调用)
|
||||
func SyncContactOnEmployeeCreate(tid uint64, employeeID uint64, emp *models.BackendEmployee) {
|
||||
syncContactFromEmployee(tid, employeeID, emp)
|
||||
}
|
||||
|
||||
// SyncContactOnEmployeeRefresh 员工信息变更后重新全量同步通讯录(由组织架构控制器调用)。
|
||||
// 走的是与建档同步同一套逻辑:先取员工基础字段,再用人事档案字段覆盖(工作邮箱、家庭地址优先)。
|
||||
func SyncContactOnEmployeeRefresh(tid uint64, employeeID uint64) {
|
||||
var emp models.BackendEmployee
|
||||
if err := models.Orm.QueryTable(new(models.BackendEmployee)).
|
||||
Filter("id", employeeID).
|
||||
Filter("delete_time__isnull", true).
|
||||
One(&emp); err != nil {
|
||||
return
|
||||
}
|
||||
syncContactFromEmployee(tid, employeeID, &emp)
|
||||
}
|
||||
|
||||
// SyncContactOnEmployeeFileChange 人事档案建档/变更后同步通讯录(由 OA 档案控制器调用)。
|
||||
// 通讯录以 employee_id 关联员工,档案里的字段(工作邮箱、家庭地址)优先级高于员工自身字段。
|
||||
// 只做字段同步:不会新增/删除员工,也不会清理通讯录记录。
|
||||
func SyncContactOnEmployeeFileChange(tid uint64, employeeID uint64) {
|
||||
SyncContactOnEmployeeRefresh(tid, employeeID)
|
||||
}
|
||||
|
||||
// SyncContactOnEmployeeUpdate 员工更新后同步到通讯录(由 ERP 控制器调用)
|
||||
func SyncContactOnEmployeeUpdate(employeeID uint64, update orm.Params) {
|
||||
var contact models.BackendErpContact
|
||||
@@ -638,11 +666,8 @@ func SyncContactOnEmployeeUpdate(employeeID uint64, update orm.Params) {
|
||||
if v, ok := update["home_address"]; ok {
|
||||
contactUpdate["address"] = v
|
||||
}
|
||||
if v, ok := update["account_status"]; ok {
|
||||
if status, ok := v.(int8); ok && status == 2 {
|
||||
contactUpdate["status"] = int8(0)
|
||||
}
|
||||
}
|
||||
// 员工账号状态(启用/禁用/离职)不同步到通讯录:
|
||||
// 通讯录是企业数据,员工离职或账号被删除都不代表联系人应当停用,是否停用由通讯录模块自行维护。
|
||||
|
||||
if len(contactUpdate) > 0 {
|
||||
models.Orm.QueryTable(new(models.BackendErpContact)).
|
||||
@@ -651,7 +676,9 @@ func SyncContactOnEmployeeUpdate(employeeID uint64, update orm.Params) {
|
||||
}
|
||||
}
|
||||
|
||||
// SyncContactOnEmployeeDelete 员工删除后同步通讯录(由 ERP 控制器调用)
|
||||
// SyncContactOnEmployeeDelete 清理员工关联的通讯录记录。
|
||||
// 注意:员工离职/禁用(deleteEmployee)与后台账号删除(deleteUser)都不得调用本函数——
|
||||
// 通讯录是企业数据,账号或状态变化不等于联系人消失。仅在员工数据被真正物理清理时使用。
|
||||
func SyncContactOnEmployeeDelete(employeeID uint64) {
|
||||
now := time.Now().Format("2006-01-02 15:04:05")
|
||||
models.Orm.QueryTable(new(models.BackendErpContact)).
|
||||
@@ -661,6 +688,7 @@ func SyncContactOnEmployeeDelete(employeeID uint64) {
|
||||
}
|
||||
|
||||
// syncContactFromEmployee 内部同步函数
|
||||
// 从员工信息和人事档案同步数据到通讯录
|
||||
func syncContactFromEmployee(tid uint64, employeeID uint64, emp *models.BackendEmployee) string {
|
||||
var existing models.BackendErpContact
|
||||
err := models.Orm.QueryTable(new(models.BackendErpContact)).
|
||||
@@ -668,6 +696,13 @@ func syncContactFromEmployee(tid uint64, employeeID uint64, emp *models.BackendE
|
||||
Filter("delete_time__isnull", true).
|
||||
One(&existing)
|
||||
|
||||
// 获取人事档案数据
|
||||
fileData := getEmployeeFileForContact(employeeID)
|
||||
|
||||
// 通讯录字段优先级:人事档案 > 员工(档案字段为空时回退员工自身字段)
|
||||
email := contactFirstNonEmptyPtr(&fileData.WorkEmail, emp.Email)
|
||||
address := contactFirstNonEmptyPtr(&fileData.HouseholdAddress, &fileData.CurrentAddress, emp.HomeAddress)
|
||||
|
||||
if err != nil {
|
||||
// Not found - create new contact
|
||||
var orgID *uint64
|
||||
@@ -685,10 +720,10 @@ func syncContactFromEmployee(tid uint64, employeeID uint64, emp *models.BackendE
|
||||
ContactName: emp.Name,
|
||||
Gender: emp.Gender,
|
||||
Phone: emp.Phone,
|
||||
Email: emp.Email,
|
||||
Email: email,
|
||||
Wechat: emp.Wechat,
|
||||
PositionTitle: emp.Position,
|
||||
Address: emp.HomeAddress,
|
||||
Address: address,
|
||||
Status: 1,
|
||||
}
|
||||
models.Orm.Insert(&contact)
|
||||
@@ -700,10 +735,10 @@ func syncContactFromEmployee(tid uint64, employeeID uint64, emp *models.BackendE
|
||||
"contact_name": emp.Name,
|
||||
"gender": emp.Gender,
|
||||
"phone": emp.Phone,
|
||||
"email": emp.Email,
|
||||
"email": email,
|
||||
"wechat": emp.Wechat,
|
||||
"position_title": emp.Position,
|
||||
"address": emp.HomeAddress,
|
||||
"address": address,
|
||||
}
|
||||
if emp.Department != nil {
|
||||
if oid, err := strconv.ParseUint(strings.TrimSpace(*emp.Department), 10, 64); err == nil && oid > 0 {
|
||||
@@ -721,6 +756,55 @@ func syncContactFromEmployee(tid uint64, employeeID uint64, emp *models.BackendE
|
||||
return "updated"
|
||||
}
|
||||
|
||||
// getEmployeeFileForContact 获取员工人事档案数据(用于通讯录同步)
|
||||
// 返回档案中与通讯录相关的字段
|
||||
func getEmployeeFileForContact(employeeID uint64) struct {
|
||||
WorkEmail string
|
||||
HouseholdAddress string
|
||||
CurrentAddress string
|
||||
EmergencyContact string
|
||||
EmergencyPhone string
|
||||
EmergencyRelation string
|
||||
EmploymentStatus int8
|
||||
} {
|
||||
var file models.BackendEmployeeFile
|
||||
err := models.Orm.QueryTable(new(models.BackendEmployeeFile)).
|
||||
Filter("employee_id", employeeID).
|
||||
Filter("is_deleted", 0).
|
||||
One(&file)
|
||||
|
||||
if err != nil {
|
||||
// 档案不存在,返回空值
|
||||
return struct {
|
||||
WorkEmail string
|
||||
HouseholdAddress string
|
||||
CurrentAddress string
|
||||
EmergencyContact string
|
||||
EmergencyPhone string
|
||||
EmergencyRelation string
|
||||
EmploymentStatus int8
|
||||
}{}
|
||||
}
|
||||
|
||||
return struct {
|
||||
WorkEmail string
|
||||
HouseholdAddress string
|
||||
CurrentAddress string
|
||||
EmergencyContact string
|
||||
EmergencyPhone string
|
||||
EmergencyRelation string
|
||||
EmploymentStatus int8
|
||||
}{
|
||||
WorkEmail: file.WorkEmail,
|
||||
HouseholdAddress: file.HouseholdAddress,
|
||||
CurrentAddress: file.CurrentAddress,
|
||||
EmergencyContact: file.EmergencyContact,
|
||||
EmergencyPhone: file.EmergencyPhone,
|
||||
EmergencyRelation: file.EmergencyRelation,
|
||||
EmploymentStatus: file.EmploymentStatus,
|
||||
}
|
||||
}
|
||||
|
||||
// --- Helper functions (package-level, shared with ERP controller) ---
|
||||
|
||||
func contactDerefString(v *string) string {
|
||||
@@ -879,3 +963,17 @@ func (c *BackendErpContactController) contactJsonError(code int, msg string) {
|
||||
c.Data["json"] = map[string]interface{}{"code": code, "msg": msg}
|
||||
_ = c.ServeJSON()
|
||||
}
|
||||
|
||||
// contactFirstNonEmptyPtr 按优先级取第一个非空字符串(去空格后判断),全部为空时返回 nil。
|
||||
// 用于通讯录"档案字段 > 员工字段"的取值优先级,避免用空字符串覆盖已有数据。
|
||||
func contactFirstNonEmptyPtr(values ...*string) *string {
|
||||
for _, v := range values {
|
||||
if v == nil {
|
||||
continue
|
||||
}
|
||||
if s := strings.TrimSpace(*v); s != "" {
|
||||
return &s
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -594,6 +594,9 @@ func (c *BackendEmployeeFileController) Create() {
|
||||
return
|
||||
}
|
||||
|
||||
// 建档后同步通讯录(工作邮箱、家庭地址以档案为准)
|
||||
SyncContactOnEmployeeFileChange(uint64(tid), item.EmployeeID)
|
||||
|
||||
c.efOk(item)
|
||||
}
|
||||
|
||||
@@ -654,6 +657,9 @@ func (c *BackendEmployeeFileController) Update() {
|
||||
return
|
||||
}
|
||||
|
||||
// 档案变更后同步通讯录(工作邮箱、家庭地址以档案为准)
|
||||
SyncContactOnEmployeeFileChange(uint64(tid), item.EmployeeID)
|
||||
|
||||
c.efOk(item)
|
||||
}
|
||||
|
||||
@@ -718,7 +724,12 @@ func (c *BackendEmployeeFileController) UpdateCertificates() {
|
||||
c.efOk(item)
|
||||
}
|
||||
|
||||
// Delete DELETE /backend/oa/employeefile/delete/:id 软删除档案。
|
||||
// Delete DELETE /backend/oa/employeefile/delete/:id 档案离职/禁用(档案不做删除)。
|
||||
//
|
||||
// 与员工同理:人事档案属于企业数据,通讯录(yz_backend_erp_contact)也以 employee_id 关联,
|
||||
// 软删档案会让通讯录里对应的人失去数据来源。因此这里只把在职状态置为"离职"(3),
|
||||
// 不写 is_deleted / delete_time,档案与通讯录记录始终保留可查。
|
||||
// 在职状态调整(试用/正式/离职)走 update 接口即可,这里只是给"删除"动作一个不毁数据的语义。
|
||||
func (c *BackendEmployeeFileController) Delete() {
|
||||
claims, err := c.efClaims()
|
||||
if err != nil {
|
||||
@@ -733,15 +744,24 @@ func (c *BackendEmployeeFileController) Delete() {
|
||||
return
|
||||
}
|
||||
|
||||
var item models.BackendEmployeeFile
|
||||
if err := c.efQuery(tid).Filter("id", id).One(&item); err != nil {
|
||||
c.efErr(404, 404, "档案不存在")
|
||||
return
|
||||
}
|
||||
|
||||
now := time.Now()
|
||||
n, err := c.efQuery(tid).Filter("id", id).
|
||||
Update(map[string]interface{}{
|
||||
"IsDeleted": int8(1),
|
||||
"DeleteTime": now,
|
||||
"UpdateTime": now,
|
||||
})
|
||||
if err != nil || n == 0 {
|
||||
c.efErr(404, 404, "档案不存在或已删除")
|
||||
// 离职日期留空时补当天,保证档案资料(离职需填离职日期)完整
|
||||
if item.LeaveDate == nil {
|
||||
today := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, now.Location())
|
||||
item.LeaveDate = &today
|
||||
}
|
||||
item.EmploymentStatus = 3
|
||||
item.UpdateTime = &now
|
||||
|
||||
if _, err := models.Orm.Update(&item, "EmploymentStatus", "LeaveDate", "UpdateTime"); err != nil {
|
||||
log.Printf("员工档案离职失败: tid=%d file_id=%d err=%v", tid, id, err)
|
||||
c.efErr(500, 500, "离职操作失败")
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -251,16 +251,35 @@ func (c *BackendOaCompensationController) Employees() {
|
||||
c.compensationError(500, "员工查询失败")
|
||||
return
|
||||
}
|
||||
orgNames := compensationOrgNameMap(claims.TenantId)
|
||||
list := make([]map[string]interface{}, 0, len(employees))
|
||||
for _, employee := range employees {
|
||||
department := compensationString(employee.Department)
|
||||
list = append(list, map[string]interface{}{
|
||||
"id": employee.ID, "name": employee.Name, "account": employee.Account,
|
||||
"department": compensationString(employee.Department), "position": compensationString(employee.Position),
|
||||
"department": department, "department_name": efOrgNameByID(orgNames, department),
|
||||
"position": compensationString(employee.Position),
|
||||
})
|
||||
}
|
||||
c.compensationOK(list)
|
||||
}
|
||||
|
||||
// compensationOrgNameMap 组织ID -> 名称映射,用于把员工 department 字段(存的是组织ID)解析为部门名称展示。
|
||||
func compensationOrgNameMap(tid int) map[uint64]string {
|
||||
var rows []models.BackendOrganization
|
||||
if _, err := models.Orm.QueryTable(new(models.BackendOrganization)).
|
||||
Filter("tid", tid).
|
||||
Filter("delete_time__isnull", true).
|
||||
All(&rows, "ID", "OrgName"); err != nil {
|
||||
return map[uint64]string{}
|
||||
}
|
||||
names := make(map[uint64]string, len(rows))
|
||||
for _, row := range rows {
|
||||
names[row.ID] = row.OrgName
|
||||
}
|
||||
return names
|
||||
}
|
||||
|
||||
// SchemeList GET /backend/oa/compensation/schemes
|
||||
func (c *BackendOaCompensationController) SchemeList() {
|
||||
claims, err := c.compensationClaims()
|
||||
|
||||
@@ -73,7 +73,6 @@ type organizationDTO struct {
|
||||
Sort uint `json:"sort"`
|
||||
Status int8 `json:"status"`
|
||||
Remark string `json:"remark"`
|
||||
EmployeeCount int64 `json:"employee_count"`
|
||||
CreateTime string `json:"create_time"`
|
||||
UpdateTime string `json:"update_time"`
|
||||
}
|
||||
@@ -958,6 +957,9 @@ func (c *BackendOrganizationController) CreateEmployee() {
|
||||
return
|
||||
}
|
||||
|
||||
// 同步到通讯录(员工为基础数据,已建档时档案字段优先)
|
||||
SyncContactOnEmployeeCreate(tid, uint64(id), &row)
|
||||
|
||||
c.jsonOK(map[string]interface{}{"id": id, "account": account})
|
||||
}
|
||||
|
||||
@@ -1063,10 +1065,19 @@ func (c *BackendOrganizationController) EditEmployee() {
|
||||
return
|
||||
}
|
||||
|
||||
// 同步到通讯录(字段优先级:人事档案 > 员工)
|
||||
SyncContactOnEmployeeRefresh(tid, uint64(id))
|
||||
|
||||
c.jsonOK(nil)
|
||||
}
|
||||
|
||||
// DeleteEmployee 删除员工(软删除)。
|
||||
// DeleteEmployee 员工离职/禁用:员工不做删除,只改账号状态。
|
||||
//
|
||||
// 说明:员工属于企业数据,人事档案(yz_backend_employee_file)与通讯录
|
||||
//(yz_backend_erp_contact)都以 employee_id 关联员工。一旦把员工软删除(写 delete_time),
|
||||
// 档案页与通讯录就查不到对应的人,等于连带删掉了企业数据。
|
||||
// 因此这里只把账号状态置为"离职"(2),不写 delete_time,也不触碰档案与通讯录记录。
|
||||
// 启用/禁用请走 editEmployee 改 account_status(1 启用 / 0 禁用 / 2 离职)。
|
||||
// DELETE /backend/{erp|oa}/deleteEmployee/:id
|
||||
func (c *BackendOrganizationController) DeleteEmployee() {
|
||||
tid, ok := c.tenantID()
|
||||
@@ -1079,14 +1090,15 @@ func (c *BackendOrganizationController) DeleteEmployee() {
|
||||
return
|
||||
}
|
||||
|
||||
num, err := c.employeeQuery(tid).Filter("id", id).
|
||||
Update(orm.Params{"delete_time": c.nowString(), "account_status": int8(2)})
|
||||
if err != nil {
|
||||
c.jsonError(500, "删除员工失败: "+err.Error())
|
||||
if !c.employeeQuery(tid).Filter("id", id).Exist() {
|
||||
c.jsonError(404, "员工不存在")
|
||||
return
|
||||
}
|
||||
if num == 0 {
|
||||
c.jsonError(404, "员工不存在")
|
||||
|
||||
// 员工不允许删除,仅置为离职状态;档案与通讯录原样保留
|
||||
if _, err := c.employeeQuery(tid).Filter("id", id).
|
||||
Update(orm.Params{"account_status": int8(2)}); err != nil {
|
||||
c.jsonError(500, "离职操作失败: "+err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -29,24 +29,22 @@ func (c *BackendOrganizationController) organizationDTOList(tid uint64, rows []m
|
||||
|
||||
nameByID := c.orgNameMap(tid)
|
||||
leaderNames := c.employeeNameMap(tid)
|
||||
counts := c.employeeCountByDepartment(tid)
|
||||
|
||||
for _, row := range rows {
|
||||
list = append(list, c.assembleOrganizationDTO(row, nameByID, leaderNames, counts))
|
||||
list = append(list, c.assembleOrganizationDTO(row, nameByID, leaderNames))
|
||||
}
|
||||
return list
|
||||
}
|
||||
|
||||
func (c *BackendOrganizationController) organizationDTO(tid uint64, row models.BackendOrganization) organizationDTO {
|
||||
return c.assembleOrganizationDTO(row,
|
||||
c.orgNameMap(tid), c.employeeNameMap(tid), c.employeeCountByDepartment(tid))
|
||||
c.orgNameMap(tid), c.employeeNameMap(tid))
|
||||
}
|
||||
|
||||
func (c *BackendOrganizationController) assembleOrganizationDTO(
|
||||
row models.BackendOrganization,
|
||||
nameByID map[uint64]string,
|
||||
leaderNames map[uint64]string,
|
||||
counts map[string]int64,
|
||||
) organizationDTO {
|
||||
leaderID := uint64(0)
|
||||
if row.LeaderID != nil {
|
||||
@@ -67,7 +65,6 @@ func (c *BackendOrganizationController) assembleOrganizationDTO(
|
||||
Sort: row.Sort,
|
||||
Status: row.Status,
|
||||
Remark: derefString(row.Remark),
|
||||
EmployeeCount: counts[strconv.FormatUint(row.ID, 10)],
|
||||
CreateTime: formatDateTime(&row.CreateTime),
|
||||
UpdateTime: formatDateTime(&row.UpdateTime),
|
||||
}
|
||||
@@ -179,23 +176,6 @@ func (c *BackendOrganizationController) employeeNameMap(tid uint64) map[uint64]s
|
||||
return result
|
||||
}
|
||||
|
||||
// employeeCountByDepartment 统计各部门(department 存的是组织ID字符串)的员工数。
|
||||
func (c *BackendOrganizationController) employeeCountByDepartment(tid uint64) map[string]int64 {
|
||||
result := map[string]int64{}
|
||||
var rows []models.BackendEmployee
|
||||
if _, err := c.employeeQuery(tid).All(&rows, "Department"); err != nil {
|
||||
return result
|
||||
}
|
||||
for _, row := range rows {
|
||||
key := strings.TrimSpace(derefString(row.Department))
|
||||
if key == "" {
|
||||
continue
|
||||
}
|
||||
result[key]++
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func (c *BackendOrganizationController) orgExists(tid, id uint64) bool {
|
||||
if id == 0 {
|
||||
return false
|
||||
|
||||
Reference in New Issue
Block a user