package controllers import ( "encoding/json" "io" "strconv" "strings" "server/models" "server/pkg/identity" "server/pkg/jwtutil" "server/services" authsvc "server/services/auth" beego "github.com/beego/beego/v2/server/web" ) // BackendTenantApplyController 租户端「加入申请」审批 // 数据按 JWT tid 隔离:只处理目标企业为本租户的 join 申请。 type BackendTenantApplyController struct { beego.Controller } func (c *BackendTenantApplyController) backendClaims() (*jwtutil.Claims, error) { return identity.Claims(c.Ctx.Request.Header.Get("Authorization"), identity.EndBackend) } func (c *BackendTenantApplyController) jsonErr(httpStatus, bizCode int, msg string) { c.Ctx.Output.SetStatus(httpStatus) c.Data["json"] = map[string]interface{}{"code": bizCode, "msg": msg} _ = c.ServeJSON() } func (c *BackendTenantApplyController) readJSON(v interface{}) bool { body := c.Ctx.Input.RequestBody if len(body) == 0 { var err error body, err = io.ReadAll(c.Ctx.Request.Body) if err != nil || len(body) == 0 { c.jsonErr(400, 400, "参数错误") return false } } if err := json.Unmarshal(body, v); err != nil { c.jsonErr(400, 400, "参数错误") return false } return true } // reviewerName 当前审核人姓名(租户用户表 name,兜底 JWT username) func (c *BackendTenantApplyController) reviewerName(claims *jwtutil.Claims) string { var row models.SystemTenantUser if err := models.Orm.QueryTable(new(models.SystemTenantUser)). Filter("tid", claims.TenantId). Filter("uid", claims.UserID). Filter("delete_time__isnull", true). One(&row); err == nil && row.Name != nil && strings.TrimSpace(*row.Name) != "" { return strings.TrimSpace(*row.Name) } return claims.Username } // List GET /backend/tenantApplies?page=1&pageSize=20&status= func (c *BackendTenantApplyController) List() { claims, err := c.backendClaims() if err != nil { code := identity.Status(err) c.jsonErr(code, code, err.Error()) return } tid := uint64(claims.TenantId) if tid == 0 { c.jsonErr(403, 403, "无租户信息") return } page, _ := c.GetInt("page", 1) pageSize, _ := c.GetInt("pageSize", 20) if page < 1 { page = 1 } if pageSize < 1 { pageSize = 20 } var status *int8 if s := strings.TrimSpace(c.GetString("status")); s != "" { if v, e := strconv.ParseInt(s, 10, 8); e == nil { tmp := int8(v) status = &tmp } } rows, total, err := services.ListTenantAppliesForTenant(tid, status, page, pageSize) if err != nil { c.jsonErr(500, 500, "获取申请列表失败") return } // 补充申请人展示信息(昵称 / 手机号) type applyDTO struct { models.AuthTenantApply IdentityNickname string `json:"identity_nickname"` IdentityMobile string `json:"identity_mobile"` } list := make([]applyDTO, 0, len(rows)) for _, r := range rows { dto := applyDTO{AuthTenantApply: r} if identity, ierr := authsvc.GetIdentityByID(r.IdentityID); ierr == nil && identity != nil { if identity.Nickname != nil { dto.IdentityNickname = *identity.Nickname } if identity.Mobile != nil { dto.IdentityMobile = *identity.Mobile } } list = append(list, dto) } c.Data["json"] = map[string]interface{}{ "code": 200, "msg": "success", "data": map[string]interface{}{"list": list, "total": total}, } _ = c.ServeJSON() } // Approve POST /backend/tenantApplies/approve/:id func (c *BackendTenantApplyController) Approve() { claims, err := c.backendClaims() if err != nil { code := identity.Status(err) c.jsonErr(code, code, err.Error()) return } tid := uint64(claims.TenantId) applyID, err := strconv.ParseUint(c.Ctx.Input.Param(":id"), 10, 64) if err != nil || applyID == 0 { c.jsonErr(400, 400, "无效ID") return } if err := services.ApproveJoinApply(applyID, tid, uint64(claims.UserID), c.reviewerName(claims)); err != nil { c.jsonErr(400, 400, err.Error()) return } c.Data["json"] = map[string]interface{}{"code": 200, "msg": "已通过,申请人已加入本企业"} _ = c.ServeJSON() } // Reject POST /backend/tenantApplies/reject/:id { reason } func (c *BackendTenantApplyController) Reject() { claims, err := c.backendClaims() if err != nil { code := identity.Status(err) c.jsonErr(code, code, err.Error()) return } tid := uint64(claims.TenantId) applyID, err := strconv.ParseUint(c.Ctx.Input.Param(":id"), 10, 64) if err != nil || applyID == 0 { c.jsonErr(400, 400, "无效ID") return } var req struct { Reason string `json:"reason"` } if !c.readJSON(&req) { return } if err := services.RejectJoinApply(applyID, tid, uint64(claims.UserID), c.reviewerName(claims), strings.TrimSpace(req.Reason)); err != nil { c.jsonErr(400, 400, err.Error()) return } c.Data["json"] = map[string]interface{}{"code": 200, "msg": "已驳回"} _ = c.ServeJSON() }