逐步替换代码
This commit is contained in:
parent
ae786d5157
commit
1314e18142
335
controllers/admin_menu.go
Normal file
335
controllers/admin_menu.go
Normal file
@ -0,0 +1,335 @@
|
|||||||
|
package controllers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"io"
|
||||||
|
"server/models"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
beego "github.com/beego/beego/v2/server/web"
|
||||||
|
)
|
||||||
|
|
||||||
|
// AdminMenuController 后台菜单控制器
|
||||||
|
type AdminMenuController struct {
|
||||||
|
beego.Controller
|
||||||
|
}
|
||||||
|
|
||||||
|
type menuPayload struct {
|
||||||
|
Pid *int64 `json:"pid"`
|
||||||
|
Title *string `json:"title"`
|
||||||
|
Path *string `json:"path"`
|
||||||
|
ComponentPath *string `json:"component_path"`
|
||||||
|
Icon *string `json:"icon"`
|
||||||
|
Sort *int64 `json:"sort"`
|
||||||
|
Status *int8 `json:"status"`
|
||||||
|
IsVisible *int8 `json:"is_visible"`
|
||||||
|
IsPlatform *int8 `json:"is_platform"`
|
||||||
|
Type *int8 `json:"type"`
|
||||||
|
Permission *string `json:"permission"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetMenu 获取指定用户可见的菜单列表(简化版:当前先忽略用户权限,返回全部启用且平台端菜单)
|
||||||
|
// 路由示例:GET /platform/menu/1
|
||||||
|
func (c *AdminMenuController) GetMenu() {
|
||||||
|
// 从路由参数中解析用户 ID,占位保留,方便后续按用户权限过滤
|
||||||
|
_ = c.Ctx.Input.Param(":id")
|
||||||
|
|
||||||
|
// 查询所有启用且标记为平台端的菜单
|
||||||
|
var menus []models.SystemMenu
|
||||||
|
qs := models.Orm.
|
||||||
|
QueryTable(new(models.SystemMenu)).
|
||||||
|
Filter("status", 1).
|
||||||
|
Filter("is_platform", 1)
|
||||||
|
_, err := qs.All(&menus)
|
||||||
|
if err != nil {
|
||||||
|
c.Data["json"] = map[string]interface{}{
|
||||||
|
"code": 500,
|
||||||
|
"msg": "获取菜单失败: " + err.Error(),
|
||||||
|
"data": nil,
|
||||||
|
}
|
||||||
|
_ = c.ServeJSON()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 将平铺的菜单列表构建为树形结构
|
||||||
|
menuTree := buildMenuTree(menus, 0)
|
||||||
|
|
||||||
|
c.Data["json"] = map[string]interface{}{
|
||||||
|
"code": 200,
|
||||||
|
"msg": "success",
|
||||||
|
"data": menuTree,
|
||||||
|
}
|
||||||
|
_ = c.ServeJSON()
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetAllMenus 获取平台端全部菜单(用于菜单管理界面)
|
||||||
|
// 路由:GET /platform/allmenu
|
||||||
|
func (c *AdminMenuController) GetAllMenus() {
|
||||||
|
var menus []models.SystemMenu
|
||||||
|
cid, _ := c.GetInt("cid")
|
||||||
|
|
||||||
|
qs := models.Orm.QueryTable(new(models.SystemMenu))
|
||||||
|
// 菜单管理默认返回全量菜单;仅在明确传 cid 时按分类筛选
|
||||||
|
// cid: 1平台角色 -> 平台菜单;2租户角色 -> 租户菜单
|
||||||
|
if cid == 1 {
|
||||||
|
qs = qs.Filter("is_platform", 1)
|
||||||
|
} else if cid == 2 {
|
||||||
|
qs = qs.Filter("is_platform", 0)
|
||||||
|
}
|
||||||
|
_, err := qs.All(&menus)
|
||||||
|
if err != nil {
|
||||||
|
c.Data["json"] = map[string]interface{}{
|
||||||
|
"code": 500,
|
||||||
|
"msg": "获取菜单失败: " + err.Error(),
|
||||||
|
"data": nil,
|
||||||
|
}
|
||||||
|
_ = c.ServeJSON()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
tree := buildMenuTree(menus, 0)
|
||||||
|
|
||||||
|
c.Data["json"] = map[string]interface{}{
|
||||||
|
"code": 200,
|
||||||
|
"msg": "success",
|
||||||
|
"data": tree,
|
||||||
|
}
|
||||||
|
_ = c.ServeJSON()
|
||||||
|
}
|
||||||
|
|
||||||
|
// menuNode 用于 JSON 返回的菜单结构
|
||||||
|
type menuNode struct {
|
||||||
|
ID uint64 `json:"id"`
|
||||||
|
Pid int64 `json:"pid"`
|
||||||
|
Title string `json:"title"`
|
||||||
|
Path string `json:"path,omitempty"`
|
||||||
|
ComponentPath string `json:"component_path,omitempty"`
|
||||||
|
Icon string `json:"icon,omitempty"`
|
||||||
|
Sort int64 `json:"sort"`
|
||||||
|
Status int8 `json:"status"`
|
||||||
|
IsVisible *int8 `json:"is_visible,omitempty"`
|
||||||
|
IsPlatform *int8 `json:"is_platform,omitempty"`
|
||||||
|
Type int8 `json:"type"`
|
||||||
|
Permission string `json:"permission,omitempty"`
|
||||||
|
Children []*menuNode `json:"children,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// buildMenuTree 将菜单列表构建成树结构
|
||||||
|
func buildMenuTree(menus []models.SystemMenu, pid int64) []*menuNode {
|
||||||
|
var tree []*menuNode
|
||||||
|
for _, m := range menus {
|
||||||
|
if m.Pid == pid {
|
||||||
|
node := &menuNode{
|
||||||
|
ID: m.ID,
|
||||||
|
Pid: m.Pid,
|
||||||
|
Title: m.Title,
|
||||||
|
Sort: m.Sort,
|
||||||
|
Status: m.Status,
|
||||||
|
IsVisible: m.IsVisible,
|
||||||
|
IsPlatform: m.IsPlatform,
|
||||||
|
Type: m.Type,
|
||||||
|
}
|
||||||
|
if m.Path != nil {
|
||||||
|
node.Path = *m.Path
|
||||||
|
}
|
||||||
|
if m.ComponentPath != nil {
|
||||||
|
node.ComponentPath = *m.ComponentPath
|
||||||
|
}
|
||||||
|
if m.Icon != nil {
|
||||||
|
node.Icon = *m.Icon
|
||||||
|
}
|
||||||
|
if m.Permission != nil {
|
||||||
|
node.Permission = *m.Permission
|
||||||
|
}
|
||||||
|
|
||||||
|
// 递归查找子菜单
|
||||||
|
children := buildMenuTree(menus, int64(m.ID))
|
||||||
|
if len(children) > 0 {
|
||||||
|
node.Children = children
|
||||||
|
}
|
||||||
|
tree = append(tree, node)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return tree
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateMenuStatus 更新菜单状态
|
||||||
|
// 路由:PATCH /platform/menu/status/:id
|
||||||
|
func (c *AdminMenuController) UpdateMenuStatus() {
|
||||||
|
id, err := strconv.ParseUint(c.Ctx.Input.Param(":id"), 10, 64)
|
||||||
|
if err != nil || id == 0 {
|
||||||
|
c.Data["json"] = map[string]interface{}{"code": 400, "msg": "无效菜单ID"}
|
||||||
|
_ = c.ServeJSON()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var body struct {
|
||||||
|
Status *int8 `json:"status"`
|
||||||
|
}
|
||||||
|
rawBody, _ := io.ReadAll(c.Ctx.Request.Body)
|
||||||
|
if err := json.Unmarshal(rawBody, &body); err != nil || body.Status == nil {
|
||||||
|
c.Data["json"] = map[string]interface{}{"code": 400, "msg": "参数错误"}
|
||||||
|
_ = c.ServeJSON()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = models.Orm.QueryTable(new(models.SystemMenu)).
|
||||||
|
Filter("id", id).
|
||||||
|
Update(map[string]interface{}{"status": *body.Status})
|
||||||
|
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": "success", "success": true}
|
||||||
|
_ = c.ServeJSON()
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateMenu 创建菜单
|
||||||
|
// 路由:POST /platform/createmenu
|
||||||
|
func (c *AdminMenuController) CreateMenu() {
|
||||||
|
payload, ok := c.parseMenuPayload(true)
|
||||||
|
if !ok {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
menu := models.SystemMenu{
|
||||||
|
Pid: valueInt64(payload.Pid, 0),
|
||||||
|
Title: strings.TrimSpace(valueString(payload.Title, "")),
|
||||||
|
Sort: valueInt64(payload.Sort, 0),
|
||||||
|
Status: valueInt8(payload.Status, 1),
|
||||||
|
IsVisible: ptrInt8(valueInt8(payload.IsVisible, 1)),
|
||||||
|
IsPlatform: ptrInt8(valueInt8(payload.IsPlatform, 1)),
|
||||||
|
Type: valueInt8(payload.Type, 1),
|
||||||
|
}
|
||||||
|
|
||||||
|
menu.Path = ptrString(valueString(payload.Path, ""))
|
||||||
|
menu.ComponentPath = ptrString(valueString(payload.ComponentPath, ""))
|
||||||
|
menu.Icon = ptrString(valueString(payload.Icon, ""))
|
||||||
|
menu.Permission = ptrString(valueString(payload.Permission, ""))
|
||||||
|
|
||||||
|
id, err := models.Orm.Insert(&menu)
|
||||||
|
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": "创建成功",
|
||||||
|
"data": map[string]interface{}{"id": id},
|
||||||
|
}
|
||||||
|
_ = c.ServeJSON()
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateMenu 更新菜单
|
||||||
|
// 路由:PUT /platform/updatemenu/:id
|
||||||
|
func (c *AdminMenuController) UpdateMenu() {
|
||||||
|
id, err := strconv.ParseUint(c.Ctx.Input.Param(":id"), 10, 64)
|
||||||
|
if err != nil || id == 0 {
|
||||||
|
c.Data["json"] = map[string]interface{}{"code": 400, "msg": "无效菜单ID"}
|
||||||
|
_ = c.ServeJSON()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
payload, ok := c.parseMenuPayload(false)
|
||||||
|
if !ok {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
update := map[string]interface{}{
|
||||||
|
"pid": valueInt64(payload.Pid, 0),
|
||||||
|
"title": strings.TrimSpace(valueString(payload.Title, "")),
|
||||||
|
"path": valueString(payload.Path, ""),
|
||||||
|
"component_path": valueString(payload.ComponentPath, ""),
|
||||||
|
"icon": valueString(payload.Icon, ""),
|
||||||
|
"sort": valueInt64(payload.Sort, 0),
|
||||||
|
"status": valueInt8(payload.Status, 1),
|
||||||
|
"is_visible": valueInt8(payload.IsVisible, 1),
|
||||||
|
"is_platform": valueInt8(payload.IsPlatform, 1),
|
||||||
|
"type": valueInt8(payload.Type, 1),
|
||||||
|
"permission": valueString(payload.Permission, ""),
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = models.Orm.QueryTable(new(models.SystemMenu)).
|
||||||
|
Filter("id", id).
|
||||||
|
Update(update)
|
||||||
|
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()
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteMenu 删除菜单
|
||||||
|
// 路由:DELETE /platform/deletemenu/:id
|
||||||
|
func (c *AdminMenuController) DeleteMenu() {
|
||||||
|
id, err := strconv.ParseUint(c.Ctx.Input.Param(":id"), 10, 64)
|
||||||
|
if err != nil || id == 0 {
|
||||||
|
c.Data["json"] = map[string]interface{}{"code": 400, "msg": "无效菜单ID"}
|
||||||
|
_ = c.ServeJSON()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = models.Orm.QueryTable(new(models.SystemMenu)).Filter("id", id).Delete()
|
||||||
|
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": "删除成功", "success": true}
|
||||||
|
_ = c.ServeJSON()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *AdminMenuController) parseMenuPayload(needTitle bool) (*menuPayload, bool) {
|
||||||
|
rawBody, _ := io.ReadAll(c.Ctx.Request.Body)
|
||||||
|
var payload menuPayload
|
||||||
|
if err := json.Unmarshal(rawBody, &payload); err != nil {
|
||||||
|
c.Data["json"] = map[string]interface{}{"code": 400, "msg": "参数错误"}
|
||||||
|
_ = c.ServeJSON()
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
if needTitle && strings.TrimSpace(valueString(payload.Title, "")) == "" {
|
||||||
|
c.Data["json"] = map[string]interface{}{"code": 400, "msg": "菜单名称不能为空"}
|
||||||
|
_ = c.ServeJSON()
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
return &payload, true
|
||||||
|
}
|
||||||
|
|
||||||
|
func valueString(v *string, def string) string {
|
||||||
|
if v == nil {
|
||||||
|
return def
|
||||||
|
}
|
||||||
|
return *v
|
||||||
|
}
|
||||||
|
|
||||||
|
func valueInt8(v *int8, def int8) int8 {
|
||||||
|
if v == nil {
|
||||||
|
return def
|
||||||
|
}
|
||||||
|
return *v
|
||||||
|
}
|
||||||
|
|
||||||
|
func valueInt64(v *int64, def int64) int64 {
|
||||||
|
if v == nil {
|
||||||
|
return def
|
||||||
|
}
|
||||||
|
return *v
|
||||||
|
}
|
||||||
|
|
||||||
|
func ptrString(v string) *string {
|
||||||
|
return &v
|
||||||
|
}
|
||||||
|
|
||||||
|
func ptrInt8(v int8) *int8 {
|
||||||
|
return &v
|
||||||
|
}
|
||||||
|
|
||||||
303
controllers/platform_admin_user.go
Normal file
303
controllers/platform_admin_user.go
Normal file
@ -0,0 +1,303 @@
|
|||||||
|
package controllers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"io"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"server/models"
|
||||||
|
|
||||||
|
beego "github.com/beego/beego/v2/server/web"
|
||||||
|
)
|
||||||
|
|
||||||
|
// PlatformAdminUserController 平台管理员用户管理(yz_admin_user)
|
||||||
|
type PlatformAdminUserController struct {
|
||||||
|
beego.Controller
|
||||||
|
}
|
||||||
|
|
||||||
|
type adminUserDTO struct {
|
||||||
|
ID uint64 `json:"id"`
|
||||||
|
Account string `json:"account"`
|
||||||
|
Name *string `json:"name"`
|
||||||
|
Phone *string `json:"phone"`
|
||||||
|
Email *string `json:"email"`
|
||||||
|
Qq *string `json:"qq"`
|
||||||
|
Sex uint8 `json:"sex"`
|
||||||
|
Avatar *string `json:"avatar"`
|
||||||
|
GroupID uint64 `json:"group_id"`
|
||||||
|
LoginCount uint64 `json:"login_count"`
|
||||||
|
LastLoginIP *string `json:"last_login_ip"`
|
||||||
|
Status uint8 `json:"status"`
|
||||||
|
CreateTime string `json:"create_time"`
|
||||||
|
UpdateTime *string `json:"update_time"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func toAdminUserDTO(u models.AdminUser) adminUserDTO {
|
||||||
|
var updateTime *string
|
||||||
|
if u.UpdateTime != nil {
|
||||||
|
s := u.UpdateTime.Format("2006-01-02 15:04:05")
|
||||||
|
updateTime = &s
|
||||||
|
}
|
||||||
|
return adminUserDTO{
|
||||||
|
ID: u.ID,
|
||||||
|
Account: u.Account,
|
||||||
|
Name: u.Name,
|
||||||
|
Phone: u.Phone,
|
||||||
|
Email: u.Email,
|
||||||
|
Qq: u.Qq,
|
||||||
|
Sex: u.Sex,
|
||||||
|
Avatar: u.Avatar,
|
||||||
|
GroupID: u.RoleID,
|
||||||
|
LoginCount: u.LoginCount,
|
||||||
|
LastLoginIP: u.LastLoginIP,
|
||||||
|
Status: u.Status,
|
||||||
|
CreateTime: u.CreateTime.Format("2006-01-02 15:04:05"),
|
||||||
|
UpdateTime: updateTime,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetAllUsers 获取全部平台管理员用户
|
||||||
|
// GET /platform/getAllUsers
|
||||||
|
func (c *PlatformAdminUserController) GetAllUsers() {
|
||||||
|
rows, total, err := models.ListAdminUsers()
|
||||||
|
if err != nil {
|
||||||
|
c.Data["json"] = map[string]interface{}{"code": 500, "msg": "查询失败"}
|
||||||
|
_ = c.ServeJSON()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
list := make([]adminUserDTO, 0, len(rows))
|
||||||
|
for _, u := range rows {
|
||||||
|
list = append(list, toAdminUserDTO(u))
|
||||||
|
}
|
||||||
|
c.Data["json"] = map[string]interface{}{
|
||||||
|
"code": 200,
|
||||||
|
"msg": "success",
|
||||||
|
"data": map[string]interface{}{"list": list, "total": total},
|
||||||
|
}
|
||||||
|
_ = c.ServeJSON()
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetUserInfo 获取用户详情
|
||||||
|
// GET /platform/getUserInfo/:id
|
||||||
|
func (c *PlatformAdminUserController) GetUserInfo() {
|
||||||
|
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
|
||||||
|
}
|
||||||
|
u, err := models.GetAdminUserByID(id)
|
||||||
|
if err != nil {
|
||||||
|
c.Data["json"] = map[string]interface{}{"code": 404, "msg": "用户不存在"}
|
||||||
|
_ = c.ServeJSON()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.Data["json"] = map[string]interface{}{
|
||||||
|
"code": 200,
|
||||||
|
"msg": "success",
|
||||||
|
"data": toAdminUserDTO(*u),
|
||||||
|
}
|
||||||
|
_ = c.ServeJSON()
|
||||||
|
}
|
||||||
|
|
||||||
|
type adminAddUserPayload struct {
|
||||||
|
Account string `json:"account"`
|
||||||
|
Password string `json:"password"`
|
||||||
|
Name *string `json:"name"`
|
||||||
|
Phone *string `json:"phone"`
|
||||||
|
Email *string `json:"email"`
|
||||||
|
Qq *string `json:"qq"`
|
||||||
|
Sex *uint8 `json:"sex"`
|
||||||
|
Avatar *string `json:"avatar"`
|
||||||
|
GroupID *uint64 `json:"group_id"`
|
||||||
|
Status *uint8 `json:"status"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddUser 添加平台管理员用户(仅写 yz_admin_user,不处理 tid)
|
||||||
|
// POST /platform/addUser
|
||||||
|
func (c *PlatformAdminUserController) AddUser() {
|
||||||
|
var p adminAddUserPayload
|
||||||
|
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
|
||||||
|
}
|
||||||
|
p.Account = strings.TrimSpace(p.Account)
|
||||||
|
p.Password = strings.TrimSpace(p.Password)
|
||||||
|
if p.Account == "" {
|
||||||
|
c.Data["json"] = map[string]interface{}{"code": 400, "msg": "account 不能为空"}
|
||||||
|
_ = c.ServeJSON()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if p.Password == "" {
|
||||||
|
c.Data["json"] = map[string]interface{}{"code": 400, "msg": "password 不能为空"}
|
||||||
|
_ = c.ServeJSON()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
status := uint8(1)
|
||||||
|
if p.Status != nil {
|
||||||
|
status = *p.Status
|
||||||
|
}
|
||||||
|
sex := uint8(0)
|
||||||
|
if p.Sex != nil {
|
||||||
|
sex = *p.Sex
|
||||||
|
}
|
||||||
|
groupID := uint64(1)
|
||||||
|
if p.GroupID != nil && *p.GroupID != 0 {
|
||||||
|
groupID = *p.GroupID
|
||||||
|
}
|
||||||
|
|
||||||
|
id, err := models.CreateAdminUser(p.Account, p.Password, p.Name, p.Phone, p.Email, p.Qq, p.Avatar, sex, groupID, status)
|
||||||
|
if err != nil {
|
||||||
|
c.Data["json"] = map[string]interface{}{"code": 500, "msg": "添加失败"}
|
||||||
|
_ = c.ServeJSON()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.Data["json"] = map[string]interface{}{
|
||||||
|
"code": 200,
|
||||||
|
"msg": "success",
|
||||||
|
"data": map[string]interface{}{"id": id},
|
||||||
|
}
|
||||||
|
_ = c.ServeJSON()
|
||||||
|
}
|
||||||
|
|
||||||
|
type editUserPayload struct {
|
||||||
|
Account *string `json:"account"`
|
||||||
|
Password *string `json:"password"`
|
||||||
|
Name *string `json:"name"`
|
||||||
|
Phone *string `json:"phone"`
|
||||||
|
Email *string `json:"email"`
|
||||||
|
Qq *string `json:"qq"`
|
||||||
|
Sex *uint8 `json:"sex"`
|
||||||
|
Avatar *string `json:"avatar"`
|
||||||
|
GroupID *uint64 `json:"group_id"`
|
||||||
|
Status *uint8 `json:"status"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// EditUser 编辑用户信息(password 可选,存在则修改)
|
||||||
|
// POST /platform/editUser/:id
|
||||||
|
func (c *PlatformAdminUserController) 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
|
||||||
|
}
|
||||||
|
var p editUserPayload
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
fields := map[string]interface{}{}
|
||||||
|
if p.Account != nil {
|
||||||
|
acc := strings.TrimSpace(*p.Account)
|
||||||
|
if acc != "" {
|
||||||
|
fields["account"] = acc
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if p.Name != nil {
|
||||||
|
fields["name"] = *p.Name
|
||||||
|
}
|
||||||
|
if p.Phone != nil {
|
||||||
|
fields["phone"] = *p.Phone
|
||||||
|
}
|
||||||
|
if p.Email != nil {
|
||||||
|
fields["email"] = *p.Email
|
||||||
|
}
|
||||||
|
if p.Qq != nil {
|
||||||
|
fields["qq"] = *p.Qq
|
||||||
|
}
|
||||||
|
if p.Sex != nil {
|
||||||
|
fields["sex"] = *p.Sex
|
||||||
|
}
|
||||||
|
if p.Avatar != nil {
|
||||||
|
fields["avatar"] = *p.Avatar
|
||||||
|
}
|
||||||
|
if p.GroupID != nil && *p.GroupID != 0 {
|
||||||
|
fields["role_id"] = *p.GroupID
|
||||||
|
}
|
||||||
|
if p.Status != nil {
|
||||||
|
fields["status"] = *p.Status
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(fields) > 0 {
|
||||||
|
if err := models.UpdateAdminUser(id, fields); err != nil {
|
||||||
|
c.Data["json"] = map[string]interface{}{"code": 500, "msg": "编辑失败"}
|
||||||
|
_ = c.ServeJSON()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if p.Password != nil && strings.TrimSpace(*p.Password) != "" {
|
||||||
|
if err := models.ChangeAdminUserPassword(id, *p.Password); err != nil {
|
||||||
|
c.Data["json"] = map[string]interface{}{"code": 500, "msg": "密码修改失败"}
|
||||||
|
_ = c.ServeJSON()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
c.Data["json"] = map[string]interface{}{"code": 200, "msg": "success"}
|
||||||
|
_ = c.ServeJSON()
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteUser 删除用户
|
||||||
|
// DELETE /platform/deleteUser/:id
|
||||||
|
func (c *PlatformAdminUserController) 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
|
||||||
|
}
|
||||||
|
if err := models.DeleteAdminUser(id); err != nil {
|
||||||
|
c.Data["json"] = map[string]interface{}{"code": 500, "msg": "删除失败"}
|
||||||
|
_ = c.ServeJSON()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.Data["json"] = map[string]interface{}{"code": 200, "msg": "success"}
|
||||||
|
_ = c.ServeJSON()
|
||||||
|
}
|
||||||
|
|
||||||
|
type changePasswordPayload struct {
|
||||||
|
ID uint64 `json:"id"`
|
||||||
|
Password string `json:"password"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ChangePassword 修改密码
|
||||||
|
// POST /platform/changePassword
|
||||||
|
func (c *PlatformAdminUserController) ChangePassword() {
|
||||||
|
var p changePasswordPayload
|
||||||
|
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
|
||||||
|
}
|
||||||
|
if err := models.ChangeAdminUserPassword(p.ID, p.Password); err != nil {
|
||||||
|
c.Data["json"] = map[string]interface{}{"code": 500, "msg": "修改失败"}
|
||||||
|
_ = c.ServeJSON()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.Data["json"] = map[string]interface{}{"code": 200, "msg": "修改成功"}
|
||||||
|
_ = c.ServeJSON()
|
||||||
|
}
|
||||||
|
|
||||||
@ -53,7 +53,7 @@ func (c *PlatformAuthController) Login() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 控制器只做 HTTP 解析与响应编排,业务逻辑放 services 层
|
// 控制器只做 HTTP 解析与响应编排,业务逻辑放 services 层
|
||||||
token, err := services.PlatformLogin(req.Account, req.Password)
|
token, loginUser, err := services.PlatformLogin(req.Account, req.Password)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.Data["json"] = map[string]interface{}{
|
c.Data["json"] = map[string]interface{}{
|
||||||
"code": 401,
|
"code": 401,
|
||||||
@ -68,14 +68,12 @@ func (c *PlatformAuthController) Login() {
|
|||||||
"msg": "登录成功",
|
"msg": "登录成功",
|
||||||
"data": map[string]interface{}{
|
"data": map[string]interface{}{
|
||||||
"token": token,
|
"token": token,
|
||||||
// user 结构用于前端 authStore 兼容旧格式
|
|
||||||
"user": map[string]interface{}{
|
"user": map[string]interface{}{
|
||||||
"id": 1,
|
"id": loginUser.ID,
|
||||||
"account": req.Account,
|
"account": loginUser.Account,
|
||||||
"name": "平台管理员",
|
"name": loginUser.Name,
|
||||||
"group_id": "",
|
"rid": loginUser.Rid,
|
||||||
"tid": "",
|
"avatar": loginUser.Avatar,
|
||||||
"avatar": "",
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
202
controllers/platform_role.go
Normal file
202
controllers/platform_role.go
Normal file
@ -0,0 +1,202 @@
|
|||||||
|
package controllers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"io"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"server/models"
|
||||||
|
|
||||||
|
beego "github.com/beego/beego/v2/server/web"
|
||||||
|
)
|
||||||
|
|
||||||
|
// PlatformRoleController 平台角色管理(yz_admin_role)
|
||||||
|
type PlatformRoleController struct {
|
||||||
|
beego.Controller
|
||||||
|
}
|
||||||
|
|
||||||
|
type rolePayload struct {
|
||||||
|
Cid *uint8 `json:"cid"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
Status *uint8 `json:"status"`
|
||||||
|
Rights interface{} `json:"rights"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func normalizeRights(v interface{}) *string {
|
||||||
|
if v == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
switch t := v.(type) {
|
||||||
|
case string:
|
||||||
|
s := strings.TrimSpace(t)
|
||||||
|
if s == "" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return &s
|
||||||
|
default:
|
||||||
|
b, err := json.Marshal(v)
|
||||||
|
if err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
s := string(b)
|
||||||
|
return &s
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetAllRoles 获取角色列表
|
||||||
|
// GET /platform/allRoles
|
||||||
|
func (c *PlatformRoleController) GetAllRoles() {
|
||||||
|
var rows []models.AdminRole
|
||||||
|
_, err := models.Orm.QueryTable(new(models.AdminRole)).
|
||||||
|
OrderBy("-id").
|
||||||
|
All(&rows)
|
||||||
|
if err != nil {
|
||||||
|
c.Data["json"] = map[string]interface{}{"code": 500, "msg": "查询失败"}
|
||||||
|
_ = c.ServeJSON()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.Data["json"] = map[string]interface{}{"code": 200, "msg": "success", "data": rows}
|
||||||
|
_ = c.ServeJSON()
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetRoleByID 获取角色详情
|
||||||
|
// GET /platform/roles/:id
|
||||||
|
func (c *PlatformRoleController) GetRoleByID() {
|
||||||
|
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
|
||||||
|
}
|
||||||
|
role := models.AdminRole{ID: id}
|
||||||
|
if err := models.Orm.Read(&role); err != nil {
|
||||||
|
c.Data["json"] = map[string]interface{}{"code": 404, "msg": "角色不存在"}
|
||||||
|
_ = c.ServeJSON()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.Data["json"] = map[string]interface{}{"code": 200, "msg": "success", "data": role}
|
||||||
|
_ = c.ServeJSON()
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateRole 创建角色
|
||||||
|
// POST /platform/roles
|
||||||
|
func (c *PlatformRoleController) CreateRole() {
|
||||||
|
var p rolePayload
|
||||||
|
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
|
||||||
|
}
|
||||||
|
p.Name = strings.TrimSpace(p.Name)
|
||||||
|
if p.Name == "" {
|
||||||
|
c.Data["json"] = map[string]interface{}{"code": 400, "msg": "name 不能为空"}
|
||||||
|
_ = c.ServeJSON()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
status := uint8(1)
|
||||||
|
if p.Status != nil {
|
||||||
|
status = *p.Status
|
||||||
|
}
|
||||||
|
cid := uint8(1)
|
||||||
|
if p.Cid != nil {
|
||||||
|
cid = *p.Cid
|
||||||
|
}
|
||||||
|
if cid != 1 && cid != 2 {
|
||||||
|
c.Data["json"] = map[string]interface{}{"code": 400, "msg": "cid 仅支持 1/2"}
|
||||||
|
_ = c.ServeJSON()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
rights := normalizeRights(p.Rights)
|
||||||
|
role := &models.AdminRole{
|
||||||
|
Cid: cid,
|
||||||
|
Name: p.Name,
|
||||||
|
Status: status,
|
||||||
|
Rights: rights,
|
||||||
|
}
|
||||||
|
id, err := models.Orm.Insert(role)
|
||||||
|
if err != nil {
|
||||||
|
c.Data["json"] = map[string]interface{}{"code": 500, "msg": "创建失败"}
|
||||||
|
_ = c.ServeJSON()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.Data["json"] = map[string]interface{}{"code": 200, "msg": "success", "data": map[string]interface{}{"id": id}}
|
||||||
|
_ = c.ServeJSON()
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateRole 更新角色
|
||||||
|
// PUT /platform/roles/:id
|
||||||
|
func (c *PlatformRoleController) UpdateRole() {
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
var p rolePayload
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
update := map[string]interface{}{}
|
||||||
|
if strings.TrimSpace(p.Name) != "" {
|
||||||
|
update["name"] = strings.TrimSpace(p.Name)
|
||||||
|
}
|
||||||
|
if p.Status != nil {
|
||||||
|
update["status"] = *p.Status
|
||||||
|
}
|
||||||
|
if p.Cid != nil {
|
||||||
|
if *p.Cid != 1 && *p.Cid != 2 {
|
||||||
|
c.Data["json"] = map[string]interface{}{"code": 400, "msg": "cid 仅支持 1/2"}
|
||||||
|
_ = c.ServeJSON()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
update["cid"] = *p.Cid
|
||||||
|
}
|
||||||
|
if p.Rights != nil {
|
||||||
|
update["rights"] = normalizeRights(p.Rights)
|
||||||
|
}
|
||||||
|
if len(update) == 0 {
|
||||||
|
c.Data["json"] = map[string]interface{}{"code": 400, "msg": "无更新字段"}
|
||||||
|
_ = c.ServeJSON()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err := models.Orm.QueryTable(new(models.AdminRole)).Filter("id", id).Update(update)
|
||||||
|
if err != nil {
|
||||||
|
c.Data["json"] = map[string]interface{}{"code": 500, "msg": "更新失败"}
|
||||||
|
_ = c.ServeJSON()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.Data["json"] = map[string]interface{}{"code": 200, "msg": "success"}
|
||||||
|
_ = c.ServeJSON()
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteRole 删除角色
|
||||||
|
// DELETE /platform/roles/:id
|
||||||
|
func (c *PlatformRoleController) DeleteRole() {
|
||||||
|
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
|
||||||
|
}
|
||||||
|
_, err := models.Orm.QueryTable(new(models.AdminRole)).Filter("id", id).Delete()
|
||||||
|
if err != nil {
|
||||||
|
c.Data["json"] = map[string]interface{}{"code": 500, "msg": "删除失败"}
|
||||||
|
_ = c.ServeJSON()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.Data["json"] = map[string]interface{}{"code": 200, "msg": "success"}
|
||||||
|
_ = c.ServeJSON()
|
||||||
|
}
|
||||||
|
|
||||||
333
controllers/platform_tenant.go
Normal file
333
controllers/platform_tenant.go
Normal file
@ -0,0 +1,333 @@
|
|||||||
|
package controllers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"io"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"server/models"
|
||||||
|
|
||||||
|
beego "github.com/beego/beego/v2/server/web"
|
||||||
|
)
|
||||||
|
|
||||||
|
// PlatformTenantController 平台端租户管理
|
||||||
|
type PlatformTenantController struct {
|
||||||
|
beego.Controller
|
||||||
|
}
|
||||||
|
|
||||||
|
type tenantDTO struct {
|
||||||
|
ID uint64 `json:"id"`
|
||||||
|
TenantCode string `json:"tenant_code"`
|
||||||
|
TenantName string `json:"tenant_name"`
|
||||||
|
ContactPerson string `json:"contact_person"`
|
||||||
|
ContactPhone string `json:"contact_phone"`
|
||||||
|
ContactEmail string `json:"contact_email"`
|
||||||
|
Address string `json:"address"`
|
||||||
|
Worktime string `json:"worktime"`
|
||||||
|
Status int8 `json:"status"`
|
||||||
|
Remark string `json:"remark"`
|
||||||
|
CreateTime *time.Time `json:"create_time,omitempty"`
|
||||||
|
UpdateTime *time.Time `json:"update_time,omitempty"`
|
||||||
|
DeleteTime *time.Time `json:"delete_time,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func toTenantDTO(t models.Tenant) tenantDTO {
|
||||||
|
ct := t.CreateTime
|
||||||
|
ut := t.UpdateTime
|
||||||
|
return tenantDTO{
|
||||||
|
ID: t.ID,
|
||||||
|
TenantCode: t.TenantCode,
|
||||||
|
TenantName: t.TenantName,
|
||||||
|
ContactPerson: t.ContactPerson,
|
||||||
|
ContactPhone: t.ContactPhone,
|
||||||
|
ContactEmail: t.ContactEmail,
|
||||||
|
Address: t.Address,
|
||||||
|
Worktime: t.Worktime,
|
||||||
|
Status: t.Status,
|
||||||
|
Remark: t.Remark,
|
||||||
|
CreateTime: &ct,
|
||||||
|
UpdateTime: &ut,
|
||||||
|
DeleteTime: t.DeleteTime,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetTenant 获取租户列表
|
||||||
|
// GET /platform/tenant/getTenant?page=1&pageSize=10&tenant_name=...&tenant_code=...&contact_person=...&contact_phone=...
|
||||||
|
func (c *PlatformTenantController) GetTenant() {
|
||||||
|
page, _ := c.GetInt("page", 1)
|
||||||
|
pageSize, _ := c.GetInt("pageSize", 10)
|
||||||
|
if page < 1 {
|
||||||
|
page = 1
|
||||||
|
}
|
||||||
|
if pageSize < 1 {
|
||||||
|
pageSize = 10
|
||||||
|
}
|
||||||
|
|
||||||
|
tenantName := strings.TrimSpace(c.GetString("tenant_name"))
|
||||||
|
tenantCode := strings.TrimSpace(c.GetString("tenant_code"))
|
||||||
|
contactPerson := strings.TrimSpace(c.GetString("contact_person"))
|
||||||
|
contactPhone := strings.TrimSpace(c.GetString("contact_phone"))
|
||||||
|
|
||||||
|
qs := models.Orm.QueryTable(new(models.Tenant))
|
||||||
|
if tenantName != "" {
|
||||||
|
qs = qs.Filter("tenant_name__icontains", tenantName)
|
||||||
|
}
|
||||||
|
if tenantCode != "" {
|
||||||
|
qs = qs.Filter("tenant_code__icontains", tenantCode)
|
||||||
|
}
|
||||||
|
if contactPerson != "" {
|
||||||
|
qs = qs.Filter("contact_person__icontains", contactPerson)
|
||||||
|
}
|
||||||
|
if contactPhone != "" {
|
||||||
|
qs = qs.Filter("contact_phone__icontains", contactPhone)
|
||||||
|
}
|
||||||
|
|
||||||
|
total, err := qs.Count()
|
||||||
|
if err != nil {
|
||||||
|
c.Data["json"] = map[string]interface{}{"code": 500, "msg": "获取租户失败: " + err.Error()}
|
||||||
|
_ = c.ServeJSON()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var rows []models.Tenant
|
||||||
|
_, err = qs.OrderBy("-id").Limit(pageSize, (page-1)*pageSize).All(&rows)
|
||||||
|
if err != nil {
|
||||||
|
c.Data["json"] = map[string]interface{}{"code": 500, "msg": "获取租户失败: " + err.Error()}
|
||||||
|
_ = c.ServeJSON()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
list := make([]tenantDTO, 0, len(rows))
|
||||||
|
for _, t := range rows {
|
||||||
|
list = append(list, toTenantDTO(t))
|
||||||
|
}
|
||||||
|
|
||||||
|
c.Data["json"] = map[string]interface{}{
|
||||||
|
"code": 200,
|
||||||
|
"msg": "success",
|
||||||
|
"data": map[string]interface{}{
|
||||||
|
"list": list,
|
||||||
|
"total": total,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
_ = c.ServeJSON()
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetTenantDetail 获取租户详情
|
||||||
|
// GET /platform/tenant/getTenantDetail/:id
|
||||||
|
func (c *PlatformTenantController) GetTenantDetail() {
|
||||||
|
id, err := strconv.ParseUint(c.Ctx.Input.Param(":id"), 10, 64)
|
||||||
|
if err != nil || id == 0 {
|
||||||
|
c.Data["json"] = map[string]interface{}{"code": 400, "msg": "无效ID"}
|
||||||
|
_ = c.ServeJSON()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var t models.Tenant
|
||||||
|
err = models.Orm.QueryTable(new(models.Tenant)).Filter("id", id).One(&t)
|
||||||
|
if err != nil {
|
||||||
|
c.Data["json"] = map[string]interface{}{"code": 404, "msg": "租户不存在"}
|
||||||
|
_ = c.ServeJSON()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.Data["json"] = map[string]interface{}{
|
||||||
|
"code": 200,
|
||||||
|
"msg": "success",
|
||||||
|
"data": toTenantDTO(t),
|
||||||
|
}
|
||||||
|
_ = c.ServeJSON()
|
||||||
|
}
|
||||||
|
|
||||||
|
type tenantPayload struct {
|
||||||
|
TenantCode string `json:"tenant_code"`
|
||||||
|
TenantName string `json:"tenant_name"`
|
||||||
|
ContactPerson string `json:"contact_person"`
|
||||||
|
ContactPhone string `json:"contact_phone"`
|
||||||
|
ContactEmail string `json:"contact_email"`
|
||||||
|
Address string `json:"address"`
|
||||||
|
Worktime string `json:"worktime"`
|
||||||
|
Status *int8 `json:"status"`
|
||||||
|
Remark string `json:"remark"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *PlatformTenantController) parseTenantPayload() (tenantPayload, error) {
|
||||||
|
// 优先从表单读取(createTenant 使用 multipart/form-data)
|
||||||
|
p := tenantPayload{
|
||||||
|
TenantCode: strings.TrimSpace(c.GetString("tenant_code")),
|
||||||
|
TenantName: strings.TrimSpace(c.GetString("tenant_name")),
|
||||||
|
ContactPerson: strings.TrimSpace(c.GetString("contact_person")),
|
||||||
|
ContactPhone: strings.TrimSpace(c.GetString("contact_phone")),
|
||||||
|
ContactEmail: strings.TrimSpace(c.GetString("contact_email")),
|
||||||
|
Address: strings.TrimSpace(c.GetString("address")),
|
||||||
|
Worktime: strings.TrimSpace(c.GetString("worktime")),
|
||||||
|
Remark: strings.TrimSpace(c.GetString("remark")),
|
||||||
|
}
|
||||||
|
if s := strings.TrimSpace(c.GetString("status")); s != "" {
|
||||||
|
if v, err := strconv.ParseInt(s, 10, 8); err == nil {
|
||||||
|
tmp := int8(v)
|
||||||
|
p.Status = &tmp
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果关键字段为空,尝试从 JSON body 解析(editTenant 默认 JSON)
|
||||||
|
if p.TenantName == "" && p.TenantCode == "" {
|
||||||
|
raw, _ := io.ReadAll(c.Ctx.Request.Body)
|
||||||
|
if len(raw) > 0 {
|
||||||
|
_ = json.Unmarshal(raw, &p)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return p, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateTenant 创建租户
|
||||||
|
// POST /platform/tenant/createTenant
|
||||||
|
func (c *PlatformTenantController) CreateTenant() {
|
||||||
|
p, _ := c.parseTenantPayload()
|
||||||
|
if strings.TrimSpace(p.TenantName) == "" {
|
||||||
|
c.Data["json"] = map[string]interface{}{"code": 400, "msg": "租户名称不能为空"}
|
||||||
|
_ = c.ServeJSON()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if strings.TrimSpace(p.TenantCode) == "" {
|
||||||
|
c.Data["json"] = map[string]interface{}{"code": 400, "msg": "租户编码不能为空"}
|
||||||
|
_ = c.ServeJSON()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 校验编码唯一
|
||||||
|
cnt, err := models.Orm.QueryTable(new(models.Tenant)).Filter("tenant_code", p.TenantCode).Count()
|
||||||
|
if err != nil {
|
||||||
|
c.Data["json"] = map[string]interface{}{"code": 500, "msg": "创建失败: " + err.Error()}
|
||||||
|
_ = c.ServeJSON()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if cnt > 0 {
|
||||||
|
c.Data["json"] = map[string]interface{}{"code": 400, "msg": "租户编码已存在"}
|
||||||
|
_ = c.ServeJSON()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
status := int8(1)
|
||||||
|
if p.Status != nil {
|
||||||
|
status = *p.Status
|
||||||
|
}
|
||||||
|
|
||||||
|
t := models.Tenant{
|
||||||
|
TenantCode: p.TenantCode,
|
||||||
|
TenantName: p.TenantName,
|
||||||
|
ContactPerson: p.ContactPerson,
|
||||||
|
ContactPhone: p.ContactPhone,
|
||||||
|
ContactEmail: p.ContactEmail,
|
||||||
|
Address: p.Address,
|
||||||
|
Worktime: p.Worktime,
|
||||||
|
Status: status,
|
||||||
|
Remark: p.Remark,
|
||||||
|
}
|
||||||
|
|
||||||
|
id, err := models.Orm.Insert(&t)
|
||||||
|
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": "success",
|
||||||
|
"data": map[string]interface{}{"id": id},
|
||||||
|
}
|
||||||
|
_ = c.ServeJSON()
|
||||||
|
}
|
||||||
|
|
||||||
|
// EditTenant 编辑租户
|
||||||
|
// POST /platform/tenant/editTenant/:id
|
||||||
|
func (c *PlatformTenantController) EditTenant() {
|
||||||
|
id, err := strconv.ParseUint(c.Ctx.Input.Param(":id"), 10, 64)
|
||||||
|
if err != nil || id == 0 {
|
||||||
|
c.Data["json"] = map[string]interface{}{"code": 400, "msg": "无效ID"}
|
||||||
|
_ = c.ServeJSON()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
p, _ := c.parseTenantPayload()
|
||||||
|
if strings.TrimSpace(p.TenantName) == "" {
|
||||||
|
c.Data["json"] = map[string]interface{}{"code": 400, "msg": "租户名称不能为空"}
|
||||||
|
_ = c.ServeJSON()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
update := map[string]interface{}{
|
||||||
|
"tenant_name": p.TenantName,
|
||||||
|
"contact_person": p.ContactPerson,
|
||||||
|
"contact_phone": p.ContactPhone,
|
||||||
|
"contact_email": p.ContactEmail,
|
||||||
|
"address": p.Address,
|
||||||
|
"worktime": p.Worktime,
|
||||||
|
"remark": p.Remark,
|
||||||
|
}
|
||||||
|
if p.Status != nil {
|
||||||
|
update["status"] = *p.Status
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = models.Orm.QueryTable(new(models.Tenant)).Filter("id", id).Update(update)
|
||||||
|
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": "success"}
|
||||||
|
_ = c.ServeJSON()
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteTenant 删除租户
|
||||||
|
// DELETE /platform/tenant/deleteTenant/:id
|
||||||
|
func (c *PlatformTenantController) DeleteTenant() {
|
||||||
|
id, err := strconv.ParseUint(c.Ctx.Input.Param(":id"), 10, 64)
|
||||||
|
if err != nil || id == 0 {
|
||||||
|
c.Data["json"] = map[string]interface{}{"code": 400, "msg": "无效ID"}
|
||||||
|
_ = c.ServeJSON()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = models.Orm.QueryTable(new(models.Tenant)).Filter("id", id).Delete()
|
||||||
|
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": "success"}
|
||||||
|
_ = c.ServeJSON()
|
||||||
|
}
|
||||||
|
|
||||||
|
// FindTenantCode 校验租户编码是否重复
|
||||||
|
// GET /platform/tenant/findTenantCode?tenant_code=xxxxxx
|
||||||
|
// 返回 code=200 表示可用;非200表示重复/不可用(前端会自动重新生成)
|
||||||
|
func (c *PlatformTenantController) FindTenantCode() {
|
||||||
|
code := strings.TrimSpace(c.GetString("tenant_code"))
|
||||||
|
if code == "" {
|
||||||
|
c.Data["json"] = map[string]interface{}{"code": 400, "msg": "tenant_code 不能为空"}
|
||||||
|
_ = c.ServeJSON()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
cnt, err := models.Orm.QueryTable(new(models.Tenant)).Filter("tenant_code", code).Count()
|
||||||
|
if err != nil {
|
||||||
|
c.Data["json"] = map[string]interface{}{"code": 500, "msg": "校验失败: " + err.Error()}
|
||||||
|
_ = c.ServeJSON()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if cnt > 0 {
|
||||||
|
c.Data["json"] = map[string]interface{}{"code": 409, "msg": "租户编码已存在"}
|
||||||
|
_ = c.ServeJSON()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.Data["json"] = map[string]interface{}{"code": 200, "msg": "ok"}
|
||||||
|
_ = c.ServeJSON()
|
||||||
|
}
|
||||||
|
|
||||||
289
controllers/platform_tenant_user.go
Normal file
289
controllers/platform_tenant_user.go
Normal file
@ -0,0 +1,289 @@
|
|||||||
|
package controllers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"io"
|
||||||
|
"math/rand"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"server/models"
|
||||||
|
|
||||||
|
beego "github.com/beego/beego/v2/server/web"
|
||||||
|
)
|
||||||
|
|
||||||
|
// PlatformTenantUserController 平台端租户-用户绑定管理
|
||||||
|
type PlatformTenantUserController struct {
|
||||||
|
beego.Controller
|
||||||
|
}
|
||||||
|
|
||||||
|
type tenantUserPayload 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"`
|
||||||
|
Password *string `json:"password"`
|
||||||
|
IsDefault *int8 `json:"is_default"`
|
||||||
|
Status *int8 `json:"status"`
|
||||||
|
Remark *string `json:"remark"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetTenantUserList 获取绑定列表(支持按 tid / uid 过滤)
|
||||||
|
// GET /platform/tenantUser/list?tid=1&uid=2
|
||||||
|
func (c *PlatformTenantUserController) GetTenantUserList() {
|
||||||
|
tid, _ := c.GetUint64("tid")
|
||||||
|
uid, _ := c.GetUint64("uid")
|
||||||
|
|
||||||
|
qs := models.Orm.QueryTable(new(models.TenantUser))
|
||||||
|
if tid > 0 {
|
||||||
|
qs = qs.Filter("tid", tid)
|
||||||
|
}
|
||||||
|
if uid > 0 {
|
||||||
|
qs = qs.Filter("uid", uid)
|
||||||
|
}
|
||||||
|
|
||||||
|
var rows []models.TenantUser
|
||||||
|
_, err := qs.OrderBy("-is_default", "-id").All(&rows)
|
||||||
|
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": "success",
|
||||||
|
"data": map[string]interface{}{
|
||||||
|
"list": rows,
|
||||||
|
"total": len(rows),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
_ = c.ServeJSON()
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetTenantUsersByTid 兼容路径参数方式获取租户用户列表
|
||||||
|
// GET /platform/getTenantUsers/:tid
|
||||||
|
func (c *PlatformTenantUserController) GetTenantUsersByTid() {
|
||||||
|
tidStr := c.Ctx.Input.Param(":tid")
|
||||||
|
tid, _ := strconv.ParseUint(tidStr, 10, 64)
|
||||||
|
if tid == 0 {
|
||||||
|
c.Data["json"] = map[string]interface{}{"code": 400, "msg": "tid 不能为空"}
|
||||||
|
_ = c.ServeJSON()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
var rows []models.TenantUser
|
||||||
|
_, err := models.Orm.QueryTable(new(models.TenantUser)).
|
||||||
|
Filter("tid", tid).
|
||||||
|
OrderBy("-is_default", "-id").
|
||||||
|
All(&rows)
|
||||||
|
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": "success",
|
||||||
|
"data": map[string]interface{}{"list": rows, "total": len(rows)},
|
||||||
|
}
|
||||||
|
_ = c.ServeJSON()
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetTenantUserDetail 获取绑定详情
|
||||||
|
// GET /platform/tenantUser/detail/:id
|
||||||
|
func (c *PlatformTenantUserController) GetTenantUserDetail() {
|
||||||
|
id, err := strconv.ParseUint(c.Ctx.Input.Param(":id"), 10, 64)
|
||||||
|
if err != nil || id == 0 {
|
||||||
|
c.Data["json"] = map[string]interface{}{"code": 400, "msg": "无效ID"}
|
||||||
|
_ = c.ServeJSON()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var row models.TenantUser
|
||||||
|
err = models.Orm.QueryTable(new(models.TenantUser)).Filter("id", id).One(&row)
|
||||||
|
if err != nil {
|
||||||
|
c.Data["json"] = map[string]interface{}{"code": 404, "msg": "记录不存在"}
|
||||||
|
_ = c.ServeJSON()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.Data["json"] = map[string]interface{}{"code": 200, "msg": "success", "data": row}
|
||||||
|
_ = c.ServeJSON()
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateTenantUser 创建绑定
|
||||||
|
// POST /platform/tenantUser/create
|
||||||
|
func (c *PlatformTenantUserController) CreateTenantUser() {
|
||||||
|
p, ok := c.parsePayload()
|
||||||
|
if !ok {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
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
|
||||||
|
}
|
||||||
|
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)
|
||||||
|
status := int8(1)
|
||||||
|
if p.IsDefault != nil {
|
||||||
|
isDefault = *p.IsDefault
|
||||||
|
}
|
||||||
|
if p.Status != nil {
|
||||||
|
status = *p.Status
|
||||||
|
}
|
||||||
|
|
||||||
|
id, err := models.BindTenantUser(p.Tid, p.Uid, p.Account, p.Name, p.Phone, p.Email, 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 {
|
||||||
|
_ = models.SetDefaultTenant(p.Uid, p.Tid)
|
||||||
|
}
|
||||||
|
|
||||||
|
c.Data["json"] = map[string]interface{}{"code": 200, "msg": "success", "data": map[string]interface{}{"id": id}}
|
||||||
|
_ = c.ServeJSON()
|
||||||
|
}
|
||||||
|
|
||||||
|
// EditTenantUser 编辑绑定
|
||||||
|
// POST /platform/tenantUser/edit/:id
|
||||||
|
func (c *PlatformTenantUserController) EditTenantUser() {
|
||||||
|
id, err := strconv.ParseUint(c.Ctx.Input.Param(":id"), 10, 64)
|
||||||
|
if err != nil || id == 0 {
|
||||||
|
c.Data["json"] = map[string]interface{}{"code": 400, "msg": "无效ID"}
|
||||||
|
_ = c.ServeJSON()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
p, ok := c.parsePayload()
|
||||||
|
if !ok {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
update := map[string]interface{}{}
|
||||||
|
if p.Tid > 0 {
|
||||||
|
update["tid"] = p.Tid
|
||||||
|
}
|
||||||
|
if p.Uid > 0 {
|
||||||
|
update["uid"] = p.Uid
|
||||||
|
}
|
||||||
|
if p.Account != nil {
|
||||||
|
update["account"] = p.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.Password != nil {
|
||||||
|
update["password"] = p.Password
|
||||||
|
}
|
||||||
|
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.TenantUser)).Filter("id", 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 && p.Uid > 0 && p.Tid > 0 {
|
||||||
|
_ = models.SetDefaultTenant(p.Uid, p.Tid)
|
||||||
|
}
|
||||||
|
|
||||||
|
c.Data["json"] = map[string]interface{}{"code": 200, "msg": "success"}
|
||||||
|
_ = c.ServeJSON()
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteTenantUser 删除绑定
|
||||||
|
// DELETE /platform/tenantUser/delete/:id
|
||||||
|
func (c *PlatformTenantUserController) DeleteTenantUser() {
|
||||||
|
id, err := strconv.ParseUint(c.Ctx.Input.Param(":id"), 10, 64)
|
||||||
|
if err != nil || id == 0 {
|
||||||
|
c.Data["json"] = map[string]interface{}{"code": 400, "msg": "无效ID"}
|
||||||
|
_ = c.ServeJSON()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := models.UnbindTenantUser(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()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *PlatformTenantUserController) parsePayload() (tenantUserPayload, bool) {
|
||||||
|
var p tenantUserPayload
|
||||||
|
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 tenantUserPayload{}, false
|
||||||
|
}
|
||||||
|
return p, true
|
||||||
|
}
|
||||||
|
|
||||||
|
func generateTenantUID(tid uint64) (uint64, error) {
|
||||||
|
rand.Seed(time.Now().UnixNano())
|
||||||
|
for i := 0; i < 8; i++ {
|
||||||
|
uid := uint64(10000000 + rand.Intn(90000000))
|
||||||
|
cnt, err := models.Orm.QueryTable(new(models.TenantUser)).
|
||||||
|
Filter("tid", tid).
|
||||||
|
Filter("uid", uid).
|
||||||
|
Count()
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
if cnt == 0 {
|
||||||
|
return uid, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0, errors.New("uid collision")
|
||||||
|
}
|
||||||
|
|
||||||
100
controllers/platform_user.go
Normal file
100
controllers/platform_user.go
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
package controllers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"io"
|
||||||
|
"math/rand"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"server/models"
|
||||||
|
|
||||||
|
beego "github.com/beego/beego/v2/server/web"
|
||||||
|
)
|
||||||
|
|
||||||
|
// PlatformUserController 平台端用户相关(简化:当前用户信息落在 yz_tenant_user)
|
||||||
|
type PlatformUserController struct {
|
||||||
|
beego.Controller
|
||||||
|
}
|
||||||
|
|
||||||
|
type addUserPayload struct {
|
||||||
|
Tid uint64 `json:"tid"`
|
||||||
|
Account string `json:"account"`
|
||||||
|
Password string `json:"password"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
Phone string `json:"phone"`
|
||||||
|
Email string `json:"email"`
|
||||||
|
Status *int8 `json:"status"`
|
||||||
|
Remark *string `json:"remark"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddUser 添加用户(绑定到租户)
|
||||||
|
// POST /platform/addUser
|
||||||
|
func (c *PlatformUserController) AddUser() {
|
||||||
|
var p addUserPayload
|
||||||
|
|
||||||
|
// 兼容 JSON body
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
p.Account = strings.TrimSpace(p.Account)
|
||||||
|
p.Password = strings.TrimSpace(p.Password)
|
||||||
|
p.Name = strings.TrimSpace(p.Name)
|
||||||
|
p.Phone = strings.TrimSpace(p.Phone)
|
||||||
|
p.Email = strings.TrimSpace(p.Email)
|
||||||
|
|
||||||
|
if p.Tid == 0 {
|
||||||
|
c.Data["json"] = map[string]interface{}{"code": 400, "msg": "tid 不能为空"}
|
||||||
|
_ = c.ServeJSON()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if p.Account == "" {
|
||||||
|
c.Data["json"] = map[string]interface{}{"code": 400, "msg": "account 不能为空"}
|
||||||
|
_ = c.ServeJSON()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if p.Password == "" {
|
||||||
|
c.Data["json"] = map[string]interface{}{"code": 400, "msg": "password 不能为空"}
|
||||||
|
_ = c.ServeJSON()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
status := int8(1)
|
||||||
|
if p.Status != nil {
|
||||||
|
status = *p.Status
|
||||||
|
}
|
||||||
|
|
||||||
|
// 生成 uid:8位数字即可(10000000~99999999)
|
||||||
|
rand.Seed(time.Now().UnixNano())
|
||||||
|
var uid uint64
|
||||||
|
for i := 0; i < 5; i++ {
|
||||||
|
uid = uint64(10000000 + rand.Intn(90000000))
|
||||||
|
// 尝试写入(若冲突由唯一索引兜底,外层再重试)
|
||||||
|
account := &p.Account
|
||||||
|
name := &p.Name
|
||||||
|
phone := &p.Phone
|
||||||
|
email := &p.Email
|
||||||
|
password := &p.Password
|
||||||
|
|
||||||
|
_, err := models.BindTenantUser(p.Tid, uid, account, name, phone, email, password, 0, status, p.Remark)
|
||||||
|
if err == nil {
|
||||||
|
c.Data["json"] = map[string]interface{}{
|
||||||
|
"code": 200,
|
||||||
|
"msg": "success",
|
||||||
|
"data": map[string]interface{}{"tid": p.Tid, "uid": uid},
|
||||||
|
}
|
||||||
|
_ = c.ServeJSON()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// 轻量重试
|
||||||
|
time.Sleep(5 * time.Millisecond)
|
||||||
|
}
|
||||||
|
|
||||||
|
c.Data["json"] = map[string]interface{}{"code": 500, "msg": "添加失败,请重试"}
|
||||||
|
_ = c.ServeJSON()
|
||||||
|
}
|
||||||
|
|
||||||
20
models/admin_role.go
Normal file
20
models/admin_role.go
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
package models
|
||||||
|
|
||||||
|
import "time"
|
||||||
|
|
||||||
|
// AdminRole 平台角色表 yz_admin_role
|
||||||
|
type AdminRole struct {
|
||||||
|
ID uint64 `orm:"column(id);pk;auto" json:"id"`
|
||||||
|
Cid uint8 `orm:"column(cid);default(1)" json:"cid"` // 1平台角色 2租户角色
|
||||||
|
Name string `orm:"column(name);size(32)" json:"name"`
|
||||||
|
Status uint8 `orm:"column(status);default(1)" json:"status"`
|
||||||
|
Rights *string `orm:"column(rights);type(text);null" json:"rights"`
|
||||||
|
CreateTime time.Time `orm:"column(create_time);type(datetime);auto_now_add" json:"create_time"`
|
||||||
|
UpdateTime *time.Time `orm:"column(update_time);type(datetime);auto_now;null" json:"update_time"`
|
||||||
|
DeleteTime *time.Time `orm:"column(delete_time);type(datetime);null" json:"delete_time"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *AdminRole) TableName() string {
|
||||||
|
return "yz_admin_role"
|
||||||
|
}
|
||||||
|
|
||||||
96
models/admin_user.go
Normal file
96
models/admin_user.go
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
package models
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/md5"
|
||||||
|
"encoding/hex"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// AdminUser 平台管理员信息表 yz_admin_user
|
||||||
|
type AdminUser struct {
|
||||||
|
ID uint64 `orm:"column(id);pk;auto" json:"id"`
|
||||||
|
Account string `orm:"column(account);size(64)" json:"account"`
|
||||||
|
Password string `orm:"column(password);size(32)" json:"-"`
|
||||||
|
Name *string `orm:"column(name);size(32);null" json:"name"`
|
||||||
|
Phone *string `orm:"column(phone);size(18);null" json:"phone"`
|
||||||
|
Email *string `orm:"column(email);size(255);null" json:"email"`
|
||||||
|
Qq *string `orm:"column(qq);size(16);null" json:"qq"`
|
||||||
|
Sex uint8 `orm:"column(sex);default(0)" json:"sex"`
|
||||||
|
Avatar *string `orm:"column(avatar);size(255);null" json:"avatar"`
|
||||||
|
RoleID uint64 `orm:"column(role_id)" json:"group_id"`
|
||||||
|
LoginCount uint64 `orm:"column(login_count);default(0)" json:"login_count"`
|
||||||
|
LastLoginIP *string `orm:"column(last_login_ip);size(255);null" json:"last_login_ip"`
|
||||||
|
Status uint8 `orm:"column(status);default(1)" json:"status"`
|
||||||
|
CreateTime time.Time `orm:"column(create_time);type(datetime);auto_now_add" json:"create_time"`
|
||||||
|
UpdateTime *time.Time `orm:"column(update_time);type(datetime);auto_now;null" json:"update_time"`
|
||||||
|
DeleteTime *time.Time `orm:"column(delete_time);type(datetime);null" json:"delete_time"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *AdminUser) TableName() string {
|
||||||
|
return "yz_admin_user"
|
||||||
|
}
|
||||||
|
|
||||||
|
func md5Hex(s string) string {
|
||||||
|
sum := md5.Sum([]byte(s))
|
||||||
|
return hex.EncodeToString(sum[:])
|
||||||
|
}
|
||||||
|
|
||||||
|
func NormalizeAccount(s string) string {
|
||||||
|
return strings.TrimSpace(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateAdminUser 创建平台管理员用户(password 会被 md5)
|
||||||
|
func CreateAdminUser(account, password string, name, phone, email, qq, avatar *string, sex uint8, roleID uint64, status uint8) (uint64, error) {
|
||||||
|
u := &AdminUser{
|
||||||
|
Account: NormalizeAccount(account),
|
||||||
|
Password: md5Hex(strings.TrimSpace(password)),
|
||||||
|
Name: name,
|
||||||
|
Phone: phone,
|
||||||
|
Email: email,
|
||||||
|
Qq: qq,
|
||||||
|
Avatar: avatar,
|
||||||
|
Sex: sex,
|
||||||
|
RoleID: roleID,
|
||||||
|
Status: status,
|
||||||
|
}
|
||||||
|
id, err := Orm.Insert(u)
|
||||||
|
return uint64(id), err
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetAdminUserByID(id uint64) (*AdminUser, error) {
|
||||||
|
u := &AdminUser{ID: id}
|
||||||
|
if err := Orm.Read(u); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return u, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateAdminUser 更新用户基础信息(不含 password)
|
||||||
|
func UpdateAdminUser(id uint64, fields map[string]interface{}) error {
|
||||||
|
_, err := Orm.QueryTable(new(AdminUser)).Filter("id", id).Update(fields)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func DeleteAdminUser(id uint64) error {
|
||||||
|
_, err := Orm.QueryTable(new(AdminUser)).Filter("id", id).Delete()
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func ChangeAdminUserPassword(id uint64, newPassword string) error {
|
||||||
|
_, err := Orm.QueryTable(new(AdminUser)).Filter("id", id).Update(map[string]interface{}{
|
||||||
|
"password": md5Hex(strings.TrimSpace(newPassword)),
|
||||||
|
})
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func ListAdminUsers() ([]AdminUser, int64, error) {
|
||||||
|
var rows []AdminUser
|
||||||
|
total, err := Orm.QueryTable(new(AdminUser)).Count()
|
||||||
|
if err != nil {
|
||||||
|
return nil, 0, err
|
||||||
|
}
|
||||||
|
_, err = Orm.QueryTable(new(AdminUser)).OrderBy("-id").All(&rows)
|
||||||
|
return rows, total, err
|
||||||
|
}
|
||||||
|
|
||||||
@ -1,8 +1,46 @@
|
|||||||
package models
|
package models
|
||||||
|
|
||||||
// Init 初始化模型层资源(如:数据库连接、模型注册)。
|
import (
|
||||||
// 目前仅做占位以支持当前结构编译通过;后续按实际数据库/模型重写。
|
"fmt"
|
||||||
|
|
||||||
|
beego "github.com/beego/beego/v2/server/web"
|
||||||
|
"github.com/beego/beego/v2/client/orm"
|
||||||
|
_ "github.com/go-sql-driver/mysql"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Orm 全局 ORM 对象,供业务层和控制器使用
|
||||||
|
var Orm orm.Ormer
|
||||||
|
|
||||||
|
// Init 初始化模型层资源(数据库连接、模型注册等)。
|
||||||
func Init(_ string) {
|
func Init(_ string) {
|
||||||
// TODO: 初始化数据库连接等
|
// 从配置读取数据库连接信息
|
||||||
|
user, _ := beego.AppConfig.String("mysqluser")
|
||||||
|
pass, _ := beego.AppConfig.String("mysqlpass")
|
||||||
|
urls, _ := beego.AppConfig.String("mysqlurls")
|
||||||
|
dbname, _ := beego.AppConfig.String("mysqldb")
|
||||||
|
|
||||||
|
if user == "" || urls == "" || dbname == "" {
|
||||||
|
panic("数据库配置(mysqluser/mysqlurls/mysqldb) 未正确设置")
|
||||||
|
}
|
||||||
|
|
||||||
|
// 组装 DSN:user:pass@tcp(host:port)/dbname?charset=utf8mb4&parseTime=True&loc=Local
|
||||||
|
dsn := fmt.Sprintf("%s:%s@tcp(%s)/%s?charset=utf8mb4&parseTime=True&loc=Local", user, pass, urls, dbname)
|
||||||
|
|
||||||
|
// 注册默认数据库
|
||||||
|
if err := orm.RegisterDataBase("default", "mysql", dsn); err != nil {
|
||||||
|
panic("注册数据库失败: " + err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
// 注册模型
|
||||||
|
orm.RegisterModel(
|
||||||
|
new(Tenant),
|
||||||
|
new(TenantUser),
|
||||||
|
new(SystemMenu),
|
||||||
|
new(AdminUser),
|
||||||
|
new(AdminRole),
|
||||||
|
)
|
||||||
|
|
||||||
|
// 创建全局 Ormer
|
||||||
|
Orm = orm.NewOrm()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
30
models/system_menu.go
Normal file
30
models/system_menu.go
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
package models
|
||||||
|
|
||||||
|
import "time"
|
||||||
|
|
||||||
|
// SystemMenu 系统菜单表 yz_system_menu
|
||||||
|
type SystemMenu struct {
|
||||||
|
ID uint64 `orm:"column(id);pk;auto" json:"id"` // 菜单ID
|
||||||
|
Pid int64 `orm:"column(pid);default(0)" json:"pid"` // 上级菜单ID
|
||||||
|
Title string `orm:"column(title);size(50)" json:"title"` // 菜单名称
|
||||||
|
Path *string `orm:"column(path);size(200);null" json:"path"` // 路由路径
|
||||||
|
ComponentPath *string `orm:"column(component_path);size(255);null" json:"componentPath"` // 组件路径
|
||||||
|
Icon *string `orm:"column(icon);size(100);null" json:"icon"` // 菜单图标
|
||||||
|
Sort int64 `orm:"column(sort);default(0)" json:"sort"` // 排序号
|
||||||
|
Status int8 `orm:"column(status);default(0)" json:"status"` // 状态:1-启用,0-禁用
|
||||||
|
IsVisible *int8 `orm:"column(is_visible);null" json:"isVisible"` // 是否显示:1-显示 0-不显示
|
||||||
|
IsPlatform *int8 `orm:"column(is_platform);null" json:"isPlatform"` // 是否平台:1-是 0-否
|
||||||
|
Type int8 `orm:"column(type)" json:"type"` // 菜单类型:1-目录,2-页面,3-接口
|
||||||
|
Permission *string `orm:"column(permission);size(100);null" json:"permission"` // 权限标识(按钮类型时填写)
|
||||||
|
Creater *string `orm:"column(creater);size(50);null" json:"creater"` // 创建者
|
||||||
|
Remark *string `orm:"column(remark);size(500);null" json:"remark"` // 备注
|
||||||
|
CreateTime time.Time `orm:"column(create_time);auto_now_add;type(datetime)" json:"createTime"` // 创建时间
|
||||||
|
UpdateTime *time.Time `orm:"column(update_time);auto_now;type(datetime);null" json:"updateTime"` // 更新时间
|
||||||
|
DeleteTime *time.Time `orm:"column(delete_time);type(datetime);null" json:"deleteTime"` // 删除时间
|
||||||
|
}
|
||||||
|
|
||||||
|
// TableName 自定义表名
|
||||||
|
func (m *SystemMenu) TableName() string {
|
||||||
|
return "yz_system_menu"
|
||||||
|
}
|
||||||
|
|
||||||
106
models/tenant_user.go
Normal file
106
models/tenant_user.go
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
package models
|
||||||
|
|
||||||
|
import "time"
|
||||||
|
|
||||||
|
// TenantUser 租户用户绑定关系表 yz_tenant_user
|
||||||
|
type TenantUser struct {
|
||||||
|
ID uint64 `orm:"column(id);pk;auto" json:"id"`
|
||||||
|
Tid uint64 `orm:"column(tid)" json:"tid"` // 租户ID
|
||||||
|
Uid uint64 `orm:"column(uid)" json:"uid"` // 用户ID
|
||||||
|
Account *string `orm:"column(account);size(64);null" json:"account"` // 用户账号(冗余)
|
||||||
|
Name *string `orm:"column(name);size(64);null" json:"name"` // 用户名称(冗余)
|
||||||
|
Phone *string `orm:"column(phone);size(20);null" json:"phone"` // 手机号(冗余)
|
||||||
|
Email *string `orm:"column(email);size(128);null" json:"email"` // 邮箱(冗余)
|
||||||
|
Password *string `orm:"column(password);size(255);null" json:"password"` // 密码(冗余/可选)
|
||||||
|
IsDefault int8 `orm:"column(is_default);default(0)" json:"is_default"` // 是否默认租户
|
||||||
|
Status int8 `orm:"column(status);default(1)" json:"status"` // 状态:1启用,0禁用
|
||||||
|
Remark *string `orm:"column(remark);size(255);null" json:"remark"`
|
||||||
|
CreateTime time.Time `orm:"column(create_time);auto_now_add;type(datetime)" json:"create_time"`
|
||||||
|
UpdateTime *time.Time `orm:"column(update_time);auto_now;type(datetime);null" json:"update_time"`
|
||||||
|
DeleteTime *time.Time `orm:"column(delete_time);type(datetime);null" json:"delete_time"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// TableName 自定义表名
|
||||||
|
func (m *TenantUser) TableName() string {
|
||||||
|
return "yz_tenant_user"
|
||||||
|
}
|
||||||
|
|
||||||
|
// BindTenantUser 绑定用户到租户(若已存在则更新状态/默认值)
|
||||||
|
func BindTenantUser(tid, uid uint64, account, name, phone, email, password *string, isDefault, status int8, remark *string) (uint64, error) {
|
||||||
|
var existed TenantUser
|
||||||
|
err := Orm.QueryTable(new(TenantUser)).
|
||||||
|
Filter("tid", tid).
|
||||||
|
Filter("uid", uid).
|
||||||
|
One(&existed)
|
||||||
|
if err == nil {
|
||||||
|
update := map[string]interface{}{
|
||||||
|
"account": account,
|
||||||
|
"name": name,
|
||||||
|
"phone": phone,
|
||||||
|
"email": email,
|
||||||
|
"password": password,
|
||||||
|
"status": status,
|
||||||
|
"is_default": isDefault,
|
||||||
|
"remark": remark,
|
||||||
|
}
|
||||||
|
_, uErr := Orm.QueryTable(new(TenantUser)).Filter("id", existed.ID).Update(update)
|
||||||
|
return existed.ID, uErr
|
||||||
|
}
|
||||||
|
|
||||||
|
m := &TenantUser{
|
||||||
|
Tid: tid,
|
||||||
|
Uid: uid,
|
||||||
|
Account: account,
|
||||||
|
Name: name,
|
||||||
|
Phone: phone,
|
||||||
|
Email: email,
|
||||||
|
Password: password,
|
||||||
|
IsDefault: isDefault,
|
||||||
|
Status: status,
|
||||||
|
Remark: remark,
|
||||||
|
}
|
||||||
|
id, iErr := Orm.Insert(m)
|
||||||
|
return uint64(id), iErr
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnbindTenantUser 删除绑定关系
|
||||||
|
func UnbindTenantUser(id uint64) error {
|
||||||
|
_, err := Orm.QueryTable(new(TenantUser)).Filter("id", id).Delete()
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListTenantUsersByTid 根据租户ID查询绑定关系
|
||||||
|
func ListTenantUsersByTid(tid uint64) ([]TenantUser, error) {
|
||||||
|
var rows []TenantUser
|
||||||
|
_, err := Orm.QueryTable(new(TenantUser)).
|
||||||
|
Filter("tid", tid).
|
||||||
|
OrderBy("-is_default", "-id").
|
||||||
|
All(&rows)
|
||||||
|
return rows, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListTenantBindingsByUid 根据用户ID查询绑定关系
|
||||||
|
func ListTenantBindingsByUid(uid uint64) ([]TenantUser, error) {
|
||||||
|
var rows []TenantUser
|
||||||
|
_, err := Orm.QueryTable(new(TenantUser)).
|
||||||
|
Filter("uid", uid).
|
||||||
|
OrderBy("-is_default", "-id").
|
||||||
|
All(&rows)
|
||||||
|
return rows, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetDefaultTenant 设置用户默认租户(同一用户仅一个默认)
|
||||||
|
func SetDefaultTenant(uid, tid uint64) error {
|
||||||
|
_, err := Orm.QueryTable(new(TenantUser)).Filter("uid", uid).Update(map[string]interface{}{
|
||||||
|
"is_default": 0,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
_, err = Orm.QueryTable(new(TenantUser)).
|
||||||
|
Filter("uid", uid).
|
||||||
|
Filter("tid", tid).
|
||||||
|
Update(map[string]interface{}{"is_default": 1})
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
@ -1,7 +1,7 @@
|
|||||||
package backend
|
package backend
|
||||||
|
|
||||||
// Register 注册租户管理端(backend)路由。
|
// Register 注册租户端(backend)路由。
|
||||||
// 目前仅占位,后续按 /backend/* 规则补充具体接口。
|
// 该端不包含平台菜单配置接口。
|
||||||
func Register() {
|
func Register() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -22,5 +22,44 @@ func Register() {
|
|||||||
// 找回密码相关
|
// 找回密码相关
|
||||||
beego.Router("/platform/resetPassword", &controllers.PlatformAuthController{}, "post:ResetPassword")
|
beego.Router("/platform/resetPassword", &controllers.PlatformAuthController{}, "post:ResetPassword")
|
||||||
beego.Router("/platform/sendResetCode", &controllers.PlatformAuthController{}, "post:SendResetCode")
|
beego.Router("/platform/sendResetCode", &controllers.PlatformAuthController{}, "post:SendResetCode")
|
||||||
|
|
||||||
|
// 平台菜单配置相关
|
||||||
|
beego.Router("/platform/menu/:id", &controllers.AdminMenuController{}, "get:GetMenu")
|
||||||
|
beego.Router("/platform/allmenu", &controllers.AdminMenuController{}, "get:GetAllMenus")
|
||||||
|
beego.Router("/platform/menu/status/:id", &controllers.AdminMenuController{}, "patch:UpdateMenuStatus")
|
||||||
|
beego.Router("/platform/createmenu", &controllers.AdminMenuController{}, "post:CreateMenu")
|
||||||
|
beego.Router("/platform/updatemenu/:id", &controllers.AdminMenuController{}, "put:UpdateMenu")
|
||||||
|
beego.Router("/platform/deletemenu/:id", &controllers.AdminMenuController{}, "delete:DeleteMenu")
|
||||||
|
|
||||||
|
// 平台租户管理相关
|
||||||
|
beego.Router("/platform/tenant/getTenant", &controllers.PlatformTenantController{}, "get:GetTenant")
|
||||||
|
beego.Router("/platform/tenant/getTenantDetail/:id", &controllers.PlatformTenantController{}, "get:GetTenantDetail")
|
||||||
|
beego.Router("/platform/tenant/createTenant", &controllers.PlatformTenantController{}, "post:CreateTenant")
|
||||||
|
beego.Router("/platform/tenant/editTenant/:id", &controllers.PlatformTenantController{}, "post:EditTenant")
|
||||||
|
beego.Router("/platform/tenant/deleteTenant/:id", &controllers.PlatformTenantController{}, "delete:DeleteTenant")
|
||||||
|
beego.Router("/platform/tenant/findTenantCode", &controllers.PlatformTenantController{}, "get:FindTenantCode")
|
||||||
|
|
||||||
|
// 平台租户用户绑定相关
|
||||||
|
beego.Router("/platform/getTenantUsers/:tid", &controllers.PlatformTenantUserController{}, "get:GetTenantUsersByTid")
|
||||||
|
beego.Router("/platform/tenantUser/list", &controllers.PlatformTenantUserController{}, "get:GetTenantUserList")
|
||||||
|
beego.Router("/platform/tenantUser/detail/:id", &controllers.PlatformTenantUserController{}, "get:GetTenantUserDetail")
|
||||||
|
beego.Router("/platform/tenantUser/create", &controllers.PlatformTenantUserController{}, "post:CreateTenantUser")
|
||||||
|
beego.Router("/platform/tenantUser/edit/:id", &controllers.PlatformTenantUserController{}, "post:EditTenantUser")
|
||||||
|
beego.Router("/platform/tenantUser/delete/:id", &controllers.PlatformTenantUserController{}, "delete:DeleteTenantUser")
|
||||||
|
|
||||||
|
// 平台管理员用户管理(yz_admin_user)
|
||||||
|
beego.Router("/platform/getAllUsers", &controllers.PlatformAdminUserController{}, "get:GetAllUsers")
|
||||||
|
beego.Router("/platform/getUserInfo/:id", &controllers.PlatformAdminUserController{}, "get:GetUserInfo")
|
||||||
|
beego.Router("/platform/addUser", &controllers.PlatformAdminUserController{}, "post:AddUser")
|
||||||
|
beego.Router("/platform/editUser/:id", &controllers.PlatformAdminUserController{}, "post:EditUser")
|
||||||
|
beego.Router("/platform/deleteUser/:id", &controllers.PlatformAdminUserController{}, "delete:DeleteUser")
|
||||||
|
beego.Router("/platform/changePassword", &controllers.PlatformAdminUserController{}, "post:ChangePassword")
|
||||||
|
|
||||||
|
// 平台角色管理(yz_admin_role)
|
||||||
|
beego.Router("/platform/allRoles", &controllers.PlatformRoleController{}, "get:GetAllRoles")
|
||||||
|
beego.Router("/platform/roles/:id", &controllers.PlatformRoleController{}, "get:GetRoleByID")
|
||||||
|
beego.Router("/platform/roles", &controllers.PlatformRoleController{}, "post:CreateRole")
|
||||||
|
beego.Router("/platform/roles/:id", &controllers.PlatformRoleController{}, "put:UpdateRole")
|
||||||
|
beego.Router("/platform/roles/:id", &controllers.PlatformRoleController{}, "delete:DeleteRole")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,37 +1,72 @@
|
|||||||
package services
|
package services
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"crypto/md5"
|
||||||
|
"encoding/hex"
|
||||||
"errors"
|
"errors"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"server/models"
|
||||||
"server/pkg/jwtutil"
|
"server/pkg/jwtutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
// PlatformLogin 平台登录业务
|
type PlatformLoginUser struct {
|
||||||
// TODO: 后续接真实用户/租户表,这里先做最小可用实现。
|
ID uint64
|
||||||
func PlatformLogin(username, password string) (string, error) {
|
Account string
|
||||||
// 临时简单校验:用户名和密码非空
|
Name string
|
||||||
if username == "" || password == "" {
|
Rid uint64
|
||||||
return "", errors.New("用户名或密码不能为空")
|
Avatar string
|
||||||
}
|
}
|
||||||
|
|
||||||
// 测试账号:admin / admin123
|
func md5Hex(s string) string {
|
||||||
if username != "admin" || password != "admin123" {
|
sum := md5.Sum([]byte(s))
|
||||||
return "", errors.New("用户名或密码错误")
|
return hex.EncodeToString(sum[:])
|
||||||
}
|
}
|
||||||
|
|
||||||
// 这里后续应:
|
// PlatformLogin 平台登录业务(仅允许平台用户 yz_admin_user 登录)
|
||||||
// 1. 从平台用户表查询用户
|
func PlatformLogin(account, password string) (string, *PlatformLoginUser, error) {
|
||||||
// 2. 校验密码(含加盐加密)
|
account = strings.TrimSpace(account)
|
||||||
// 3. 绑定平台/租户信息
|
password = strings.TrimSpace(password)
|
||||||
// 目前先返回一个平台用户的 JWT 占位 token
|
if account == "" || password == "" {
|
||||||
const fakeUserID = 1
|
return "", nil, errors.New("用户名或密码不能为空")
|
||||||
|
}
|
||||||
|
|
||||||
|
var user models.AdminUser
|
||||||
|
err := models.Orm.QueryTable(new(models.AdminUser)).
|
||||||
|
Filter("account", account).
|
||||||
|
One(&user)
|
||||||
|
if err != nil {
|
||||||
|
return "", nil, errors.New("用户名或密码错误")
|
||||||
|
}
|
||||||
|
if user.Password != md5Hex(password) {
|
||||||
|
return "", nil, errors.New("用户名或密码错误")
|
||||||
|
}
|
||||||
|
|
||||||
|
if user.Status == 0 {
|
||||||
|
return "", nil, errors.New("账号已禁用")
|
||||||
|
}
|
||||||
const fakeTenantID = 0
|
const fakeTenantID = 0
|
||||||
const userType = "platform"
|
const userType = "platform"
|
||||||
|
token, err := jwtutil.GenerateToken(int(user.ID), user.Account, fakeTenantID, userType)
|
||||||
token, err := jwtutil.GenerateToken(fakeUserID, username, fakeTenantID, userType)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", nil, err
|
||||||
}
|
}
|
||||||
return token, nil
|
|
||||||
|
name := ""
|
||||||
|
if user.Name != nil {
|
||||||
|
name = *user.Name
|
||||||
|
}
|
||||||
|
avatar := ""
|
||||||
|
if user.Avatar != nil {
|
||||||
|
avatar = *user.Avatar
|
||||||
|
}
|
||||||
|
loginUser := &PlatformLoginUser{
|
||||||
|
ID: user.ID,
|
||||||
|
Account: user.Account,
|
||||||
|
Name: name,
|
||||||
|
Rid: user.RoleID,
|
||||||
|
Avatar: avatar,
|
||||||
|
}
|
||||||
|
return token, loginUser, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user