59eb34976a
iotlcm-admin-svr:管理后台服务。 - Go module:iotlcm → git.5iot.com/iotlcm-public/iotlcm-admin-svr(729 文件) - 凭据与地址脱敏:JWT signingKey(含代码里的 MustGet 默认值)、 MySQL DSN、Redis 口令、告警邮件发件人邮箱全部改为占位; 私网 IP → 文档地址段;库名 xiujie_admin → iotlcm - 真实手机号/邮箱 → 合法 11 位编造号 / example.com - 移除内部资产:CI 触发器、过时 DDL(sql/db_iotlcm.sql)、 私有依赖 go get 行、明文 registry 登录口令 - 启动 banner 统一 IOTLCM 方块字 + 社区惯例署名 - Dockerfile 改用公共基础镜像 - 拼错的 RADEME.md → README.md,README 重写 - 需要真实数据库的用例改为可用 IOTLCM_TEST_WITH_DB=1 显式启用 - 补 Apache-2.0 LICENSE,LF 行尾 + .gitattributes 数据库 schema 不随本仓发布(生产 DDL 已过时),README 已说明。
128 lines
5.9 KiB
Go
128 lines
5.9 KiB
Go
// Package v1
|
||
// @Link https://github.com/xiujiecn/xiu-admin
|
||
// @Copyright Copyright (c) 2025 LiXiujie
|
||
// @Author Lxj <li@xiujie.cn>
|
||
// @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE
|
||
package v1
|
||
|
||
import (
|
||
"git.5iot.com/iotlcm-public/iotlcm-admin-svr/internal/model"
|
||
|
||
"github.com/gogf/gf/v2/frame/g"
|
||
)
|
||
|
||
// 路由菜单
|
||
type RouteMenu struct {
|
||
Id int64 `json:"id" dc:"路由ID"`
|
||
ParentId int64 `json:"parentId" dc:"父路由ID"`
|
||
Path string `json:"path" dc:"路由路径"`
|
||
Redirect *string `json:"redirect,omitempty" dc:"重定向路径"`
|
||
Name string `json:"name" dc:"路由名称"` // 必须唯一
|
||
Component string `json:"component" dc:"组件路径"`
|
||
Meta *RouteMeta `json:"meta,omitempty" dc:"路由元数据"`
|
||
Children []*RouteMenu `json:"children,omitempty" dc:"子路由"`
|
||
}
|
||
|
||
// 路由元数据
|
||
// 对应 vue/packages/@core/base/typings/src/vue-router.d.ts
|
||
type RouteMeta struct {
|
||
Title string `json:"title" dc:"菜单标题"`
|
||
Icon *string `json:"icon,omitempty" dc:"菜单图标"`
|
||
Order *int `json:"order,omitempty" dc:"菜单排序"`
|
||
OpenInNewWindow *bool `json:"openInNewWindow,omitempty" dc:"是否在新窗口打开"`
|
||
NoBasicLayout *bool `json:"noBasicLayout,omitempty" dc:"是否不使用基础布局"`
|
||
HideInMenu *bool `json:"hideInMenu,omitempty" dc:"是否隐藏菜单"`
|
||
HideInBreadcrumb *bool `json:"hideInBreadcrumb,omitempty" dc:"是否隐藏面包屑"`
|
||
HideChildrenInMenu *bool `json:"hideChildrenInMenu,omitempty" dc:"是否隐藏子菜单"`
|
||
HideInTab *bool `json:"hideInTab,omitempty" dc:"是否隐藏标签页"`
|
||
MenuVisibleWithForbidden *bool `json:"menuVisibleWithForbidden,omitempty" dc:"菜单可见但访问会被重定向到403"`
|
||
IgnoreAccess *bool `json:"ignoreAccess,omitempty" dc:"忽略权限,直接可以访问"`
|
||
KeepAlive *bool `json:"keepAlive,omitempty" dc:"开启KeepAlive缓存"`
|
||
Link *string `json:"link,omitempty" dc:"外链-跳转路径"`
|
||
Query map[string]string `json:"query,omitempty" dc:"路由所携带的参数"`
|
||
IframeSrc *string `json:"iframeSrc,omitempty" dc:"iframe地址"`
|
||
MaxNumOfOpenTab *int `json:"maxNumOfOpenTab,omitempty" dc:"标签页最大打开数量"`
|
||
Badge *string `json:"badge,omitempty" dc:"徽标"`
|
||
BadgeType *string `json:"badgeType,omitempty" dc:"徽标类型"`
|
||
BadgeVariants *string `json:"badgeVariants,omitempty" dc:"徽标颜色"`
|
||
Authority []string `json:"authority,omitempty" dc:"需要特定的角色标识才可以访问"`
|
||
AffixTab *bool `json:"affixTab,omitempty" dc:"是否固定标签页"`
|
||
AffixTabOrder *int `json:"affixTabOrder,omitempty" dc:"固定标签页的顺序"`
|
||
ActiveIcon *string `json:"activeIcon,omitempty" dc:"激活图标"`
|
||
ActivePath *string `json:"activePath,omitempty" dc:"当前激活的菜单"`
|
||
}
|
||
|
||
// 获取用户所有菜单
|
||
type MenuAllReq struct {
|
||
g.Meta `path:"/menu/all" method:"get" tags:"系统-菜单管理" summary:"获取用户所有菜单" x-check-permission:""`
|
||
}
|
||
|
||
// type MenuAllRes struct {
|
||
// Data []RouteMenu `json:"data" dc:"菜单列表"`
|
||
// }
|
||
type MenuAllRes = []*RouteMenu
|
||
|
||
type MenuListReq struct {
|
||
g.Meta `path:"/menu/list" method:"get" tags:"系统-菜单管理" summary:"获取菜单列表" x-check-permission:"cpm:system:menu:list"`
|
||
model.SysMenuListParam
|
||
}
|
||
|
||
type MenuListRes struct {
|
||
Data []*model.SysMenuListModel `json:"items" dc:"菜单列表"`
|
||
Total int `json:"total" dc:"总数"`
|
||
}
|
||
|
||
type MenuViewReq struct {
|
||
g.Meta `path:"/menu/view" method:"get" tags:"系统-菜单管理" summary:"获取菜单详情" x-check-permission:"cpm:system:menu:query"`
|
||
MenuId int64 `json:"menuId" dc:"菜单ID"`
|
||
}
|
||
|
||
type MenuViewRes struct {
|
||
model.SysMenuViewModel
|
||
}
|
||
|
||
type MenuAddReq struct {
|
||
g.Meta `path:"/menu/add" method:"post" tags:"系统-菜单管理" summary:"添加菜单" x-check-permission:"cpm:system:menu:add"`
|
||
model.SysMenuAddModel
|
||
}
|
||
|
||
type MenuAddRes struct {
|
||
model.SysMenuViewModel
|
||
}
|
||
|
||
type MenuUpdateReq struct {
|
||
g.Meta `path:"/menu/update" method:"post" tags:"系统-菜单管理" summary:"更新菜单" x-check-permission:"cpm:system:menu:edit"`
|
||
model.SysMenuUpdateModel
|
||
}
|
||
|
||
type MenuUpdateRes struct {
|
||
model.SysMenuViewModel
|
||
}
|
||
|
||
type MenuDeleteReq struct {
|
||
g.Meta `path:"/menu/delete" method:"post" tags:"系统-菜单管理" summary:"删除菜单" x-check-permission:"cpm:system:menu:remove"`
|
||
MenuId int64 `json:"menuId" dc:"菜单ID"`
|
||
}
|
||
|
||
type MenuDeleteRes struct {
|
||
}
|
||
|
||
// MenuTreeReq 菜单树,服务于两个场景:
|
||
// 1. 菜单管理页(需要 cpm:system:menu:list)
|
||
// 2. 角色管理页里的授权树(需要 cpm:system:role:query)
|
||
//
|
||
// 二者权限域不同,因此用逗号分隔声明为「或」关系:拥有任一权限即可调用。
|
||
// 逗号 OR 语义由中间件实现(internal/logic/middleware/middleware.go 中对
|
||
// x-check-permission 按 "," 切分后逐个匹配,任一通过即放行)。
|
||
//
|
||
// 若只要求 cpm:system:menu:list,则只有角色管理权限、没有菜单管理权限的用户
|
||
// 将无法打开授权树。此设计与 /agent/menu/tree 使用角色权限的思路一致。
|
||
type MenuTreeReq struct {
|
||
g.Meta `path:"/menu/tree" method:"get" tags:"系统-菜单管理" summary:"获取菜单树" x-check-permission:"cpm:system:menu:list,cpm:system:role:query"`
|
||
model.SysMenuListParam
|
||
}
|
||
|
||
type MenuTreeRes struct {
|
||
Data []*model.SysMenuFullTreeModel `json:"items" dc:"菜单树"`
|
||
}
|