package controllers import ( "encoding/json" "io" "strconv" "strings" "server/models" "server/pkg/passwordutil" "server/services" "github.com/beego/beego/v2/client/orm" beego "github.com/beego/beego/v2/server/web" ) type BackendAdminUserController struct { beego.Controller } type backendUserInfoDTO struct { ID uint64 `json:"id"` Tid uint64 `json:"tid"` Uid uint64 `json:"uid"` Account *string `json:"account"` Name *string `json:"name"` Phone *string `json:"phone"` Email *string `json:"email"` Sex uint8 `json:"sex"` Birth *string `json:"birth"` IsDefault int8 `json:"is_default"` Status int8 `json:"status"` Remark *string `json:"remark"` CreateTime string `json:"create_time"` UpdateTime *string `json:"update_time"` TenantName string `json:"tenant_name"` TenantCode string `json:"tenant_code"` } type backendTenantUserPayload struct { Tid uint64 `json:"tid"` Uid uint64 `json:"uid"` Account *string `json:"account"` Name *string `json:"name"` Phone *string `json:"phone"` Email *string `json:"email"` Sex *uint8 `json:"sex"` Birth *string `json:"birth"` Password *string `json:"password"` IsDefault *int8 `json:"is_default"` Status *int8 `json:"status"` Remark *string `json:"remark"` } type backendChangePasswordPayload struct { ID uint64 `json:"id"` Password string `json:"password"` } func formatBackendBirth(birth *string) *string { if birth == nil { return nil } s := strings.TrimSpace(*birth) if s == "" { return nil } if len(s) >= 10 { date := s[:10] return &date } return &s } func toBackendUserInfoDTO(u models.SystemTenantUser) backendUserInfoDTO { var updateTime *string if u.UpdateTime != nil { s := u.UpdateTime.Format("2006-01-02 15:04:05") updateTime = &s } tenantName := "未知租户" tenantCode := "" tenant, err := services.GetTenantByID(u.Tid) if err == nil && tenant != nil { tenantName = tenant.TenantName tenantCode = tenant.TenantCode } return backendUserInfoDTO{ ID: u.ID, Tid: u.Tid, Uid: u.Uid, Account: u.Account, Name: u.Name, Phone: u.Phone, Email: u.Email, Sex: u.Sex, Birth: formatBackendBirth(u.Birth), IsDefault: u.IsDefault, Status: u.Status, Remark: u.Remark, CreateTime: u.CreateTime.Format("2006-01-02 15:04:05"), UpdateTime: updateTime, TenantName: tenantName, TenantCode: tenantCode, } } func (c *BackendAdminUserController) getJWTUidTid() (uint64, uint64) { var uid uint64 var tid uint64 data := c.Ctx.Input.Data() if jwtUid := data["uid"]; jwtUid != nil { if v, ok := jwtUid.(uint64); ok { uid = v } } if jwtTid := data["tid"]; jwtTid != nil { if v, ok := jwtTid.(uint64); ok { tid = v } } return uid, tid } func (c *BackendAdminUserController) parseTenantUserPayload() (backendTenantUserPayload, bool) { var p backendTenantUserPayload raw, _ := io.ReadAll(c.Ctx.Request.Body) if err := json.Unmarshal(raw, &p); err != nil { c.Data["json"] = map[string]interface{}{"code": 400, "msg": "参数错误"} _ = c.ServeJSON() return backendTenantUserPayload{}, false } return p, true } func findBackendTenantUser(idOrUid uint64, jwtTid uint64) (*models.SystemTenantUser, error) { var row models.SystemTenantUser qs := models.Orm.QueryTable(new(models.SystemTenantUser)). Filter("delete_time__isnull", true) if jwtTid > 0 { qs = qs.Filter("tid", jwtTid) } err := qs.Filter("id", idOrUid).One(&row) if err == nil { return &row, nil } qs = models.Orm.QueryTable(new(models.SystemTenantUser)). Filter("delete_time__isnull", true) if jwtTid > 0 { qs = qs.Filter("tid", jwtTid) } err = qs.Filter("uid", idOrUid).One(&row) if err != nil { return nil, err } return &row, nil } // GetAllUsers 获取当前租户后台用户列表 // GET /backend/getAllUsers func (c *BackendAdminUserController) GetAllUsers() { _, jwtTid := c.getJWTUidTid() keyword := strings.TrimSpace(c.GetString("keyword")) tid, _ := c.GetUint64("tid") if jwtTid > 0 { tid = jwtTid } cond := orm.NewCondition().And("delete_time__isnull", true) if tid > 0 { cond = cond.And("tid", tid) } if keyword != "" { kwCond := orm.NewCondition(). Or("name__icontains", keyword). Or("phone__icontains", keyword). Or("email__icontains", keyword). Or("account__icontains", keyword) cond = cond.AndCond(kwCond) } var rows []models.SystemTenantUser _, err := models.Orm.QueryTable(new(models.SystemTenantUser)). SetCond(cond). OrderBy("-is_default", "-id"). All(&rows) if err != nil { c.Data["json"] = map[string]interface{}{"code": 500, "msg": "查询失败: " + err.Error()} _ = c.ServeJSON() return } list := make([]backendUserInfoDTO, 0, len(rows)) for _, row := range rows { list = append(list, toBackendUserInfoDTO(row)) } c.Data["json"] = map[string]interface{}{ "code": 200, "msg": "success", "data": map[string]interface{}{ "list": list, "total": len(list), }, } _ = c.ServeJSON() } // GetTenantUsers 获取指定租户后台用户 // GET /backend/getTenantUsers/:tid func (c *BackendAdminUserController) GetTenantUsers() { tidStr := c.Ctx.Input.Param(":tid") tid, _ := strconv.ParseUint(tidStr, 10, 64) _, jwtTid := c.getJWTUidTid() if jwtTid > 0 { tid = jwtTid } if tid == 0 { c.Data["json"] = map[string]interface{}{"code": 400, "msg": "tid 不能为空"} _ = c.ServeJSON() return } var rows []models.SystemTenantUser _, err := models.Orm.QueryTable(new(models.SystemTenantUser)). Filter("tid", tid). Filter("delete_time__isnull", true). OrderBy("-is_default", "-id"). All(&rows) if err != nil { c.Data["json"] = map[string]interface{}{"code": 500, "msg": "查询失败: " + err.Error()} _ = c.ServeJSON() return } list := make([]backendUserInfoDTO, 0, len(rows)) for _, row := range rows { list = append(list, toBackendUserInfoDTO(row)) } c.Data["json"] = map[string]interface{}{ "code": 200, "msg": "success", "data": map[string]interface{}{ "list": list, "total": len(list), }, } _ = c.ServeJSON() } // GetUserInfo 获取后台租户用户详情 // GET /backend/getUserInfo/:id func (c *BackendAdminUserController) GetUserInfo() { jwtUid, jwtTid := c.getJWTUidTid() idStr := c.Ctx.Input.Param(":id") id, _ := strconv.ParseUint(idStr, 10, 64) if id == 0 { id = jwtUid } if id == 0 { c.Data["json"] = map[string]interface{}{"code": 401, "msg": "未登录或非法请求"} _ = c.ServeJSON() return } u, err := findBackendTenantUser(id, jwtTid) if err != nil || u == nil { c.Data["json"] = map[string]interface{}{"code": 404, "msg": "后台用户信息不存在"} _ = c.ServeJSON() return } c.Data["json"] = map[string]interface{}{ "code": 200, "msg": "success", "data": toBackendUserInfoDTO(*u), } _ = c.ServeJSON() } // AddUser 添加后台租户用户 // POST /backend/addUser func (c *BackendAdminUserController) AddUser() { p, ok := c.parseTenantUserPayload() if !ok { return } _, jwtTid := c.getJWTUidTid() if jwtTid > 0 { p.Tid = jwtTid } if p.Tid == 0 { c.Data["json"] = map[string]interface{}{"code": 400, "msg": "tid 不能为空"} _ = c.ServeJSON() return } if p.Account == nil || strings.TrimSpace(*p.Account) == "" { c.Data["json"] = map[string]interface{}{"code": 400, "msg": "account 不能为空"} _ = c.ServeJSON() return } if p.Password == nil || strings.TrimSpace(*p.Password) == "" { c.Data["json"] = map[string]interface{}{"code": 400, "msg": "password 不能为空"} _ = c.ServeJSON() return } account := strings.TrimSpace(*p.Account) p.Account = &account hashed, err := passwordutil.Hash(strings.TrimSpace(*p.Password)) if err != nil { c.Data["json"] = map[string]interface{}{"code": 400, "msg": err.Error()} _ = c.ServeJSON() return } p.Password = &hashed if p.Uid == 0 { uid, err := generateTenantUID(p.Tid) if err != nil { c.Data["json"] = map[string]interface{}{"code": 500, "msg": "生成用户ID失败"} _ = c.ServeJSON() return } p.Uid = uid } isDefault := int8(0) if p.IsDefault != nil { isDefault = *p.IsDefault } status := int8(1) if p.Status != nil { status = *p.Status } id, err := services.BindTenantUser( p.Tid, p.Uid, p.Account, p.Name, p.Phone, p.Email, p.Sex, p.Birth, p.Password, isDefault, status, p.Remark, ) if err != nil { c.Data["json"] = map[string]interface{}{"code": 500, "msg": "添加失败: " + err.Error()} _ = c.ServeJSON() return } if isDefault == 1 { _ = services.SetDefaultTenant(p.Uid, p.Tid) } c.Data["json"] = map[string]interface{}{ "code": 200, "msg": "success", "data": map[string]interface{}{"id": id}, } _ = c.ServeJSON() } // EditUser 编辑后台租户用户 // POST /backend/editUser/:id func (c *BackendAdminUserController) EditUser() { idStr := c.Ctx.Input.Param(":id") id, _ := strconv.ParseUint(idStr, 10, 64) if id == 0 { c.Data["json"] = map[string]interface{}{"code": 400, "msg": "id 不能为空"} _ = c.ServeJSON() return } p, ok := c.parseTenantUserPayload() if !ok { return } _, jwtTid := c.getJWTUidTid() row, err := findBackendTenantUser(id, jwtTid) if err != nil || row == nil { c.Data["json"] = map[string]interface{}{"code": 404, "msg": "用户不存在"} _ = c.ServeJSON() return } update := map[string]interface{}{} if p.Tid > 0 && jwtTid == 0 { update["tid"] = p.Tid } if p.Uid > 0 { update["uid"] = p.Uid } if p.Account != nil { account := strings.TrimSpace(*p.Account) if account != "" { update["account"] = account } } if p.Name != nil { update["name"] = *p.Name } if p.Phone != nil { update["phone"] = *p.Phone } if p.Email != nil { update["email"] = *p.Email } if p.Sex != nil { update["sex"] = *p.Sex } if p.Birth != nil { birth := strings.TrimSpace(*p.Birth) if birth == "" { update["birth"] = nil } else { update["birth"] = birth } } if p.Password != nil && strings.TrimSpace(*p.Password) != "" { hashed, err := passwordutil.Hash(strings.TrimSpace(*p.Password)) if err != nil { c.Data["json"] = map[string]interface{}{"code": 400, "msg": err.Error()} _ = c.ServeJSON() return } update["password"] = hashed } if p.IsDefault != nil { update["is_default"] = *p.IsDefault } if p.Status != nil { update["status"] = *p.Status } if p.Remark != nil { update["remark"] = *p.Remark } if len(update) == 0 { c.Data["json"] = map[string]interface{}{"code": 400, "msg": "无更新字段"} _ = c.ServeJSON() return } _, err = models.Orm.QueryTable(new(models.SystemTenantUser)). Filter("id", row.ID). Update(update) if err != nil { c.Data["json"] = map[string]interface{}{"code": 500, "msg": "编辑失败: " + err.Error()} _ = c.ServeJSON() return } if p.IsDefault != nil && *p.IsDefault == 1 { _ = services.SetDefaultTenant(row.Uid, row.Tid) } c.Data["json"] = map[string]interface{}{"code": 200, "msg": "success"} _ = c.ServeJSON() } // DeleteUser 删除后台租户用户 // DELETE /backend/deleteUser/:id func (c *BackendAdminUserController) DeleteUser() { idStr := c.Ctx.Input.Param(":id") id, _ := strconv.ParseUint(idStr, 10, 64) if id == 0 { c.Data["json"] = map[string]interface{}{"code": 400, "msg": "id 不能为空"} _ = c.ServeJSON() return } _, jwtTid := c.getJWTUidTid() row, err := findBackendTenantUser(id, jwtTid) if err != nil || row == nil { c.Data["json"] = map[string]interface{}{"code": 404, "msg": "用户不存在"} _ = c.ServeJSON() return } if err := services.UnbindTenantUser(row.ID); err != nil { c.Data["json"] = map[string]interface{}{"code": 500, "msg": "删除失败: " + err.Error()} _ = c.ServeJSON() return } c.Data["json"] = map[string]interface{}{"code": 200, "msg": "success"} _ = c.ServeJSON() } // ChangePassword 修改后台租户用户密码 // POST /backend/changePassword func (c *BackendAdminUserController) ChangePassword() { var p backendChangePasswordPayload raw, _ := io.ReadAll(c.Ctx.Request.Body) if err := json.Unmarshal(raw, &p); err != nil { c.Data["json"] = map[string]interface{}{"code": 400, "msg": "参数错误"} _ = c.ServeJSON() return } if p.ID == 0 { c.Data["json"] = map[string]interface{}{"code": 400, "msg": "id 不能为空"} _ = c.ServeJSON() return } if strings.TrimSpace(p.Password) == "" { c.Data["json"] = map[string]interface{}{"code": 400, "msg": "password 不能为空"} _ = c.ServeJSON() return } _, jwtTid := c.getJWTUidTid() row, err := findBackendTenantUser(p.ID, jwtTid) if err != nil || row == nil { c.Data["json"] = map[string]interface{}{"code": 404, "msg": "用户不存在"} _ = c.ServeJSON() return } hashed, err := passwordutil.Hash(strings.TrimSpace(p.Password)) if err != nil { c.Data["json"] = map[string]interface{}{"code": 400, "msg": err.Error()} _ = c.ServeJSON() return } _, err = models.Orm.QueryTable(new(models.SystemTenantUser)). Filter("id", row.ID). Update(map[string]interface{}{ "password": hashed, }) if err != nil { c.Data["json"] = map[string]interface{}{"code": 500, "msg": "修改失败: " + err.Error()} _ = c.ServeJSON() return } c.Data["json"] = map[string]interface{}{"code": 200, "msg": "修改成功"} _ = c.ServeJSON() }