This commit is contained in:
hero920103 committed 2026-11-11 08:53:14 +08:00
1 parent d9a50e23dd
commit 4f1acaa451
25 files changed
+1265 -335

No files matched your search

+62 -6
View File
@@ -8,6 +8,7 @@ import (
"time"
"server/models"
authSvc "server/services/auth"
"github.com/beego/beego/v2/client/orm"
)
@@ -778,11 +779,11 @@ func (c *BackendOaSchedulingController) ClearEntries() {
c.scOK(map[string]interface{}{"cleared": len(entries)})
}
// MyBoard 当前登录用户的排班:按登录账号匹配员工档案,返回区间内每天的排班,
// 供日程日历渲染上班/休息背景。
// MyBoard 当前登录用户的排班:按登录身份匹配员工档案,返回区间内每天的排班,
// 供工作台今日卡片与日程日历渲染上班/休息背景。
// GET /backend/oa/scheduling/my?start_date=&end_date=
func (c *BackendOaSchedulingController) MyBoard() {
tid, _, username, ok := c.scOperator()
tid, uid, username, ok := c.scOperator()
if !ok {
return
}
@@ -804,9 +805,11 @@ func (c *BackendOaSchedulingController) MyBoard() {
return
}
// 账号未关联员工档案时返回空列表,前端静默不渲染排班背景
var employee models.BackendEmployee
if err := c.scBaseEmployeeQuery(tid).Filter("account", username).One(&employee); err != nil {
// 解析当前登录者对应的员工档案。OIDC 换码签发的令牌里 username 为空,
// 即使有值也是认证中心昵称而非员工工号,因此以「身份+租户」绑定账号为主,
// 再用令牌 username 按 账号 → 姓名 兜底。都匹配不到时返回空列表。
employee, ok := c.scFindSelfEmployee(tid, uid, username)
if !ok {
c.scOK(map[string]interface{}{"employee": nil, "list": []map[string]interface{}{}})
return
}
@@ -839,6 +842,59 @@ func (c *BackendOaSchedulingController) MyBoard() {
})
}
// scFindSelfEmployee 把登录身份映射到本租户的员工档案。
// 优先取认证中心「身份+租户」绑定记录里的账号(与 /auth/userinfo 同源,最可靠),
// 其次用令牌 username 按「账号 → 姓名」匹配。
func (c *BackendOaSchedulingController) scFindSelfEmployee(tid, identityID uint64, username string) (models.BackendEmployee, bool) {
var employee models.BackendEmployee
if identityID > 0 {
if bind, err := authSvc.GetTenantUser(identityID, tid); err == nil && bind != nil {
if v := authBindValue(bind.Account); v != "" {
if emp, found := c.scEmployeeByField(tid, "account", v); found {
return emp, true
}
}
if v := authBindValue(bind.Name); v != "" {
if emp, found := c.scEmployeeByField(tid, "name", v); found {
return emp, true
}
}
}
}
username = strings.TrimSpace(username)
if username != "" {
for _, field := range []string{"account", "name"} {
if emp, found := c.scEmployeeByField(tid, field, username); found {
return emp, true
}
}
}
return employee, false
}
// scEmployeeByField 在本租户员工档案中按指定字段匹配,取第一条有效记录
func (c *BackendOaSchedulingController) scEmployeeByField(tid uint64, field, value string) (models.BackendEmployee, bool) {
var rows []models.BackendEmployee
if _, err := c.scBaseEmployeeQuery(tid).
Filter(field, value).
OrderBy("id").
Limit(1).
All(&rows); err == nil && len(rows) > 0 {
return rows[0], true
}
return models.BackendEmployee{}, false
}
// authBindValue 取认证绑定记录里的可空字符串
func authBindValue(p *string) string {
if p == nil {
return ""
}
return strings.TrimSpace(*p)
}
// ChangeList 排班变更记录(最近 100 条),用于追溯临时调配。
// GET /backend/oa/scheduling/changes?start_date=&end_date=&employee_id=
func (c *BackendOaSchedulingController) ChangeList() {