更新接口

This commit is contained in:
扫地僧 2026-06-01 22:35:56 +08:00
parent 6d9977cb76
commit 31fc86e878
6 changed files with 583 additions and 48 deletions

View File

@ -1,11 +1,16 @@
package controllers package controllers
import ( import (
"encoding/json"
"io"
"strconv" "strconv"
"strings"
"server/models" "server/models"
"server/pkg/passwordutil"
"server/services" "server/services"
"github.com/beego/beego/v2/client/orm"
beego "github.com/beego/beego/v2/server/web" beego "github.com/beego/beego/v2/server/web"
) )
@ -21,64 +26,72 @@ type backendUserInfoDTO struct {
Name *string `json:"name"` Name *string `json:"name"`
Phone *string `json:"phone"` Phone *string `json:"phone"`
Email *string `json:"email"` Email *string `json:"email"`
Sex uint8 `json:"sex"`
Birth *string `json:"birth"`
IsDefault int8 `json:"is_default"`
Status int8 `json:"status"` Status int8 `json:"status"`
Remark *string `json:"remark"`
CreateTime string `json:"create_time"` CreateTime string `json:"create_time"`
UpdateTime *string `json:"update_time"`
TenantName string `json:"tenant_name"` TenantName string `json:"tenant_name"`
TenantCode string `json:"tenant_code"` TenantCode string `json:"tenant_code"`
} }
// GetUserInfo 获取当前登录租户用户的详情 type backendTenantUserPayload struct {
// GET /backend/getUserInfo Tid uint64 `json:"tid"`
func (c *BackendAdminUserController) GetUserInfo() { Uid uint64 `json:"uid"`
var uid uint64 Account *string `json:"account"`
var tid uint64 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"`
}
data := c.Ctx.Input.Data() type backendChangePasswordPayload struct {
if jwtUid := data["uid"]; jwtUid != nil { ID uint64 `json:"id"`
uid = jwtUid.(uint64) Password string `json:"password"`
} }
if jwtTid := data["tid"]; jwtTid != nil {
tid = jwtTid.(uint64) func formatBackendBirth(birth *string) *string {
if birth == nil {
return nil
} }
if uid == 0 { s := strings.TrimSpace(*birth)
idStr := c.Ctx.Input.Param(":id") if s == "" {
uid, _ = strconv.ParseUint(idStr, 10, 64) return nil
} }
if uid == 0 { if len(s) >= 10 {
c.Data["json"] = map[string]interface{}{"code": 401, "msg": "未登录或非法请求"} date := s[:10]
_ = c.ServeJSON() return &date
return
} }
var u *models.SystemTenantUser return &s
var err error }
if tid > 0 { func toBackendUserInfoDTO(u models.SystemTenantUser) backendUserInfoDTO {
u, err = services.GetTenantUserByUidAndTid(uid, tid) var updateTime *string
} else { if u.UpdateTime != nil {
u, err = services.GetTenantUserByUid(uid) s := u.UpdateTime.Format("2006-01-02 15:04:05")
updateTime = &s
} }
if err != nil || u == nil {
c.Data["json"] = map[string]interface{}{"code": 404, "msg": "后台用户信息不存在"}
_ = c.ServeJSON()
return
}
tenant, err := services.GetTenantByID(u.Tid)
tenantName := "未知租户" tenantName := "未知租户"
tenantCode := "" tenantCode := ""
tenant, err := services.GetTenantByID(u.Tid)
if err == nil && tenant != nil { if err == nil && tenant != nil {
tenantName = tenant.TenantName tenantName = tenant.TenantName
tenantCode = tenant.TenantCode tenantCode = tenant.TenantCode
} }
c.Data["json"] = map[string]interface{}{ return backendUserInfoDTO{
"code": 200,
"msg": "success",
"data": backendUserInfoDTO{
ID: u.ID, ID: u.ID,
Tid: u.Tid, Tid: u.Tid,
Uid: u.Uid, Uid: u.Uid,
@ -86,11 +99,507 @@ func (c *BackendAdminUserController) GetUserInfo() {
Name: u.Name, Name: u.Name,
Phone: u.Phone, Phone: u.Phone,
Email: u.Email, Email: u.Email,
Sex: u.Sex,
Birth: formatBackendBirth(u.Birth),
IsDefault: u.IsDefault,
Status: u.Status, Status: u.Status,
Remark: u.Remark,
CreateTime: u.CreateTime.Format("2006-01-02 15:04:05"), CreateTime: u.CreateTime.Format("2006-01-02 15:04:05"),
UpdateTime: updateTime,
TenantName: tenantName, TenantName: tenantName,
TenantCode: tenantCode, 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() _ = 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()
}

View File

@ -194,7 +194,7 @@ func (c *PlatformTenantUserController) CreateTenantUser() {
status = *p.Status status = *p.Status
} }
id, err := services.BindTenantUser(p.Tid, p.Uid, p.Account, p.Name, p.Phone, p.Email, p.Password, isDefault, status, p.Remark) id, err := services.BindTenantUser(p.Tid, p.Uid, p.Account, p.Name, p.Phone, p.Email, nil, nil, p.Password, isDefault, status, p.Remark)
if err != nil { if err != nil {
c.Data["json"] = map[string]interface{}{"code": 500, "msg": "创建失败: " + err.Error()} c.Data["json"] = map[string]interface{}{"code": 500, "msg": "创建失败: " + err.Error()}
_ = c.ServeJSON() _ = c.ServeJSON()

View File

@ -88,7 +88,7 @@ func (c *PlatformUserController) AddUser() {
hashedPwd := hashed hashedPwd := hashed
password := &hashedPwd password := &hashedPwd
_, err := services.BindTenantUser(p.Tid, uid, account, name, phone, email, password, 0, status, p.Remark) _, err := services.BindTenantUser(p.Tid, uid, account, name, phone, email, nil, nil, password, 0, status, p.Remark)
if err == nil { if err == nil {
c.Data["json"] = map[string]interface{}{ c.Data["json"] = map[string]interface{}{
"code": 200, "code": 200,

View File

@ -10,6 +10,8 @@ type SystemTenantUser struct {
Name *string `orm:"column(name);size(64);null" json:"name"` Name *string `orm:"column(name);size(64);null" json:"name"`
Phone *string `orm:"column(phone);size(20);null" json:"phone"` Phone *string `orm:"column(phone);size(20);null" json:"phone"`
Email *string `orm:"column(email);size(128);null" json:"email"` Email *string `orm:"column(email);size(128);null" json:"email"`
Sex uint8 `orm:"column(sex);default(0)" json:"sex"`
Birth *string `orm:"column(birth);size(20);null" json:"birth"`
Password *string `orm:"column(password);size(255);null" json:"password"` Password *string `orm:"column(password);size(255);null" json:"password"`
IsDefault int8 `orm:"column(is_default);default(0)" json:"is_default"` IsDefault int8 `orm:"column(is_default);default(0)" json:"is_default"`
Status int8 `orm:"column(status);default(1)" json:"status"` Status int8 `orm:"column(status);default(1)" json:"status"`

View File

@ -47,14 +47,14 @@ func RegisterAuthRoutes() {
// 模块接口 // 模块接口
beego.Router("/backend/modules/getTenantList", &controllers.PlatformModulesController{}, "get:GetTenantList") beego.Router("/backend/modules/getTenantList", &controllers.PlatformModulesController{}, "get:GetTenantList")
//用户接口 // 用户接口
beego.Router("/backend/getTenantUsers/:tid", &controllers.PlatformTenantUserController{}, "get:GetTenantUsersByTid") beego.Router("/backend/getTenantUsers/:tid", &controllers.BackendAdminUserController{}, "get:GetTenantUsers")
beego.Router("/backend/getAllUsers", &controllers.PlatformAdminUserController{}, "get:GetAllUsers") beego.Router("/backend/getAllUsers", &controllers.BackendAdminUserController{}, "get:GetAllUsers")
beego.Router("/backend/getUserInfo/:id", &controllers.BackendAdminUserController{}, "get:GetUserInfo") beego.Router("/backend/getUserInfo/:id", &controllers.BackendAdminUserController{}, "get:GetUserInfo")
beego.Router("/backend/addUser", &controllers.PlatformAdminUserController{}, "post:AddUser") beego.Router("/backend/addUser", &controllers.BackendAdminUserController{}, "post:AddUser")
beego.Router("/backend/editUser/:id", &controllers.PlatformAdminUserController{}, "post:EditUser") beego.Router("/backend/editUser/:id", &controllers.BackendAdminUserController{}, "post:EditUser")
beego.Router("/backend/deleteUser/:id", &controllers.PlatformAdminUserController{}, "delete:DeleteUser") beego.Router("/backend/deleteUser/:id", &controllers.BackendAdminUserController{}, "delete:DeleteUser")
beego.Router("/backend/changePassword", &controllers.PlatformAdminUserController{}, "post:ChangePassword") beego.Router("/backend/changePassword", &controllers.BackendAdminUserController{}, "post:ChangePassword")
// ERP 接口 // ERP 接口
beego.Router("/backend/erp/getOrganization", &controllers.BackendErpController{}, "get:GetOrganization") beego.Router("/backend/erp/getOrganization", &controllers.BackendErpController{}, "get:GetOrganization")

View File

@ -1,9 +1,13 @@
package services package services
import "server/models" import (
"strings"
"server/models"
)
// BindTenantUser 绑定用户到租户(若已存在则更新状态/默认值) // BindTenantUser 绑定用户到租户(若已存在则更新状态/默认值)
func BindTenantUser(tid, uid uint64, account, name, phone, email, password *string, isDefault, status int8, remark *string) (uint64, error) { func BindTenantUser(tid, uid uint64, account, name, phone, email *string, sex *uint8, birth *string, password *string, isDefault, status int8, remark *string) (uint64, error) {
var existed models.SystemTenantUser var existed models.SystemTenantUser
err := models.Orm.QueryTable(new(models.SystemTenantUser)). err := models.Orm.QueryTable(new(models.SystemTenantUser)).
Filter("tid", tid). Filter("tid", tid).
@ -20,6 +24,17 @@ func BindTenantUser(tid, uid uint64, account, name, phone, email, password *stri
"is_default": isDefault, "is_default": isDefault,
"remark": remark, "remark": remark,
} }
if sex != nil {
update["sex"] = *sex
}
if birth != nil {
trimmedBirth := strings.TrimSpace(*birth)
if trimmedBirth == "" {
update["birth"] = nil
} else {
update["birth"] = trimmedBirth
}
}
_, uErr := models.Orm.QueryTable(new(models.SystemTenantUser)).Filter("id", existed.ID).Update(update) _, uErr := models.Orm.QueryTable(new(models.SystemTenantUser)).Filter("id", existed.ID).Update(update)
return existed.ID, uErr return existed.ID, uErr
} }
@ -36,6 +51,15 @@ func BindTenantUser(tid, uid uint64, account, name, phone, email, password *stri
Status: status, Status: status,
Remark: remark, Remark: remark,
} }
if sex != nil {
m.Sex = *sex
}
if birth != nil {
trimmedBirth := strings.TrimSpace(*birth)
if trimmedBirth != "" {
m.Birth = &trimmedBirth
}
}
id, iErr := models.Orm.Insert(m) id, iErr := models.Orm.Insert(m)
return uint64(id), iErr return uint64(id), iErr
} }