189 lines
5.0 KiB
Go
189 lines
5.0 KiB
Go
package controllers
|
||
|
||
import (
|
||
"encoding/json"
|
||
"fmt"
|
||
"io"
|
||
"strconv"
|
||
"strings"
|
||
|
||
"server/models"
|
||
"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) {
|
||
auth := c.Ctx.Request.Header.Get("Authorization")
|
||
if auth == "" {
|
||
return nil, fmt.Errorf("未登录")
|
||
}
|
||
parts := strings.SplitN(auth, " ", 2)
|
||
if len(parts) != 2 || parts[0] != "Bearer" {
|
||
return nil, fmt.Errorf("认证信息格式错误")
|
||
}
|
||
claims, err := jwtutil.ParseToken(parts[1])
|
||
if err != nil {
|
||
return nil, fmt.Errorf("无效的token")
|
||
}
|
||
if claims.UserType != "backend" {
|
||
return nil, fmt.Errorf("无权访问")
|
||
}
|
||
return claims, nil
|
||
}
|
||
|
||
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 {
|
||
c.jsonErr(401, 401, 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 {
|
||
c.jsonErr(401, 401, 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 {
|
||
c.jsonErr(401, 401, 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()
|
||
}
|