2026-07-29 13:18:52 +08:00
|
|
|
|
package platform
|
|
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
|
"git.apinb.com/heqiapp/platforms/backend/api/internal/impl"
|
|
|
|
|
|
"git.apinb.com/heqiapp/platforms/backend/api/internal/logic/common"
|
|
|
|
|
|
"git.apinb.com/heqiapp/platforms/backend/api/internal/models"
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
// Menu 是平台后台的静态菜单定义,不对应数据库表。
|
|
|
|
|
|
type Menu struct {
|
|
|
|
|
|
Identity string `json:"identity"`
|
|
|
|
|
|
ParentIdentity string `json:"parent_identity,omitempty"`
|
2026-07-29 14:25:38 +08:00
|
|
|
|
GroupCode string `json:"group_code"`
|
2026-07-29 13:18:52 +08:00
|
|
|
|
Name string `json:"name"`
|
|
|
|
|
|
Icon string `json:"icon"`
|
|
|
|
|
|
Path string `json:"path"`
|
|
|
|
|
|
SortNo int `json:"sort_no"`
|
|
|
|
|
|
Status int `json:"status"`
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// PlatformMenus 使用二维数据组织菜单;每一行表示一个菜单分组。
|
|
|
|
|
|
var PlatformMenus = [][]Menu{
|
|
|
|
|
|
{
|
2026-08-04 23:23:12 +08:00
|
|
|
|
{Identity: "dashboard_overview", GroupCode: "dashboard", Name: "数据概览", Icon: "icon-dashboard", Path: "/dashboard/overview", SortNo: 10, Status: common.StatusEnable},
|
2026-07-29 13:18:52 +08:00
|
|
|
|
},
|
|
|
|
|
|
{
|
2026-07-29 14:51:13 +08:00
|
|
|
|
{Identity: "organization", GroupCode: "organization", Name: "机构管理", Icon: "icon-storage", Path: "/organization", SortNo: 20, Status: common.StatusEnable},
|
|
|
|
|
|
{Identity: "gas_basic", ParentIdentity: "organization", GroupCode: "organization", Name: "气站管理", Path: "/gas/gas-basic", SortNo: 1, Status: common.StatusEnable},
|
|
|
|
|
|
{Identity: "delivery_basic", ParentIdentity: "organization", GroupCode: "organization", Name: "配送点管理", Path: "/delivery/delivery-basic", SortNo: 2, Status: common.StatusEnable},
|
2026-07-29 13:18:52 +08:00
|
|
|
|
},
|
|
|
|
|
|
{
|
2026-07-29 14:25:38 +08:00
|
|
|
|
{Identity: "staff", GroupCode: "staff", Name: "工作人员管理", Icon: "icon-user-group", Path: "/staff", SortNo: 40, Status: common.StatusEnable},
|
2026-07-29 15:00:09 +08:00
|
|
|
|
{Identity: "staff_add", ParentIdentity: "staff", GroupCode: "staff", Name: "新增工作人员", Path: "/staff/add", SortNo: 1, Status: common.StatusEnable},
|
|
|
|
|
|
{Identity: "staff_installer", ParentIdentity: "staff", GroupCode: "staff", Name: "安装人员管理", Path: "/staff/installers", SortNo: 2, Status: common.StatusEnable},
|
|
|
|
|
|
{Identity: "staff_delivery", ParentIdentity: "staff", GroupCode: "staff", Name: "配送人员管理", Path: "/staff/delivery", SortNo: 3, Status: common.StatusEnable},
|
|
|
|
|
|
{Identity: "staff_operations", ParentIdentity: "staff", GroupCode: "staff", Name: "运维人员管理", Path: "/staff/operations", SortNo: 4, Status: common.StatusEnable},
|
2026-07-29 13:18:52 +08:00
|
|
|
|
},
|
|
|
|
|
|
{
|
2026-07-29 14:25:38 +08:00
|
|
|
|
{Identity: "user", GroupCode: "user", Name: "用户管理", Icon: "icon-user", Path: "/user", SortNo: 50, Status: common.StatusEnable},
|
|
|
|
|
|
{Identity: "user_account", ParentIdentity: "user", GroupCode: "user", Name: "用户账户", Path: "/user/user-account", SortNo: 1, Status: common.StatusEnable},
|
|
|
|
|
|
{Identity: "user_address", ParentIdentity: "user", GroupCode: "user", Name: "用户地址", Path: "/user/user-address", SortNo: 2, Status: common.StatusEnable},
|
|
|
|
|
|
{Identity: "user_service_relation", ParentIdentity: "user", GroupCode: "user", Name: "服务关系", Path: "/user/service-relation", SortNo: 3, Status: common.StatusEnable},
|
2026-07-29 15:09:54 +08:00
|
|
|
|
{Identity: "gasorder_contract", ParentIdentity: "user", GroupCode: "user", Name: "合同管理", Path: "/user/contracts", SortNo: 4, Status: common.StatusEnable},
|
2026-07-29 13:18:52 +08:00
|
|
|
|
},
|
|
|
|
|
|
{
|
2026-07-29 15:05:44 +08:00
|
|
|
|
{Identity: "device", GroupCode: "device", Name: "智能气阀管理", Icon: "icon-common", Path: "/product", SortNo: 60, Status: common.StatusEnable},
|
2026-08-04 15:21:39 +08:00
|
|
|
|
{Identity: "producer_account", ParentIdentity: "device", GroupCode: "device", Name: "生产商管理", Path: "/product/producers", SortNo: 1, Status: common.StatusEnable},
|
|
|
|
|
|
{Identity: "product_type", ParentIdentity: "device", GroupCode: "device", Name: "类型管理", Path: "/product/product-type", SortNo: 2, Status: common.StatusEnable},
|
|
|
|
|
|
{Identity: "product_warehouse", ParentIdentity: "device", GroupCode: "device", Name: "库房管理", Path: "/product/warehouse", SortNo: 3, Status: common.StatusEnable},
|
|
|
|
|
|
{Identity: "product_info", ParentIdentity: "device", GroupCode: "device", Name: "智能气阀管理", Path: "/product/product-info", SortNo: 4, Status: common.StatusEnable},
|
2026-07-29 13:18:52 +08:00
|
|
|
|
},
|
|
|
|
|
|
{
|
2026-07-29 14:25:38 +08:00
|
|
|
|
{Identity: "gasorder", GroupCode: "gasorder", Name: "气体配送订单管理", Icon: "icon-list", Path: "/gasorder", SortNo: 70, Status: common.StatusEnable},
|
2026-07-29 15:09:54 +08:00
|
|
|
|
{Identity: "gasorder_create", ParentIdentity: "gasorder", GroupCode: "gasorder", Name: "创建订单", Path: "/gasorder/create", SortNo: 1, Status: common.StatusEnable},
|
2026-07-29 14:25:38 +08:00
|
|
|
|
{Identity: "gasorder_basic", ParentIdentity: "gasorder", GroupCode: "gasorder", Name: "配送订单", Path: "/gasorder/orders", SortNo: 2, Status: common.StatusEnable},
|
|
|
|
|
|
{Identity: "gasorder_track", ParentIdentity: "gasorder", GroupCode: "gasorder", Name: "运行轨迹", Path: "/gasorder/tracks", SortNo: 3, Status: common.StatusEnable},
|
2026-07-29 13:18:52 +08:00
|
|
|
|
},
|
|
|
|
|
|
{
|
2026-07-29 15:29:49 +08:00
|
|
|
|
{Identity: "ec", GroupCode: "ec", Name: "电商平台管理", Icon: "icon-gift", Path: "/ec", SortNo: 80, Status: common.StatusEnable},
|
2026-07-29 14:25:38 +08:00
|
|
|
|
{Identity: "ec_category", ParentIdentity: "ec", GroupCode: "ec", Name: "商品分类", Path: "/ec/categories", SortNo: 1, Status: common.StatusEnable},
|
2026-07-29 15:29:49 +08:00
|
|
|
|
{Identity: "ec_product", ParentIdentity: "ec", GroupCode: "ec", Name: "商品管理", Path: "/ec/products", SortNo: 2, Status: common.StatusEnable},
|
2026-07-29 14:25:38 +08:00
|
|
|
|
{Identity: "ec_cart", ParentIdentity: "ec", GroupCode: "ec", Name: "购物车", Path: "/ec/carts", SortNo: 3, Status: common.StatusEnable},
|
|
|
|
|
|
{Identity: "ec_order", ParentIdentity: "ec", GroupCode: "ec", Name: "商城订单", Path: "/ec/orders", SortNo: 4, Status: common.StatusEnable},
|
|
|
|
|
|
{Identity: "ec_review", ParentIdentity: "ec", GroupCode: "ec", Name: "商品评价", Path: "/ec/reviews", SortNo: 5, Status: common.StatusEnable},
|
2026-07-29 13:18:52 +08:00
|
|
|
|
},
|
|
|
|
|
|
{
|
2026-07-29 14:25:38 +08:00
|
|
|
|
{Identity: "finance", GroupCode: "finance", Name: "财务管理", Icon: "icon-bar-chart", Path: "/finance", SortNo: 100, Status: common.StatusEnable},
|
2026-07-29 15:29:49 +08:00
|
|
|
|
{Identity: "wallet_apply_cash", ParentIdentity: "finance", GroupCode: "finance", Name: "提现记录", Path: "/finance/withdrawals", SortNo: 1, Status: common.StatusEnable},
|
|
|
|
|
|
{Identity: "fin_payment", ParentIdentity: "finance", GroupCode: "finance", Name: "支付记录", Path: "/finance/payments", SortNo: 2, Status: common.StatusEnable},
|
2026-08-02 23:24:32 +08:00
|
|
|
|
{Identity: "payment_refund", ParentIdentity: "finance", GroupCode: "finance", Name: "退款审核", Path: "/finance/refunds", SortNo: 3, Status: common.StatusEnable},
|
|
|
|
|
|
{Identity: "fin_settlement", ParentIdentity: "finance", GroupCode: "finance", Name: "财务结算", Path: "/finance/settlements", SortNo: 4, Status: common.StatusEnable},
|
|
|
|
|
|
{Identity: "fin_reconciliation", ParentIdentity: "finance", GroupCode: "finance", Name: "财务对账", Path: "/finance/reconciliations", SortNo: 5, Status: common.StatusEnable},
|
2026-07-29 13:18:52 +08:00
|
|
|
|
},
|
|
|
|
|
|
{
|
2026-07-29 14:25:38 +08:00
|
|
|
|
{Identity: "content", GroupCode: "content", Name: "内容管理", Icon: "icon-file", Path: "/content", SortNo: 110, Status: common.StatusEnable},
|
|
|
|
|
|
{Identity: "cms_content", ParentIdentity: "content", GroupCode: "content", Name: "内容", Path: "/content/contents", SortNo: 1, Status: common.StatusEnable},
|
2026-07-29 13:18:52 +08:00
|
|
|
|
},
|
|
|
|
|
|
{
|
2026-07-29 14:25:38 +08:00
|
|
|
|
{Identity: "customer_service", GroupCode: "customer_service", Name: "客服管理", Icon: "icon-customer-service", Path: "/customer-service", SortNo: 120, Status: common.StatusEnable},
|
|
|
|
|
|
{Identity: "cs_ticket", ParentIdentity: "customer_service", GroupCode: "customer_service", Name: "客服工单", Path: "/customer-service/tickets", SortNo: 1, Status: common.StatusEnable},
|
2026-07-29 13:18:52 +08:00
|
|
|
|
},
|
|
|
|
|
|
{
|
2026-07-29 14:25:38 +08:00
|
|
|
|
{Identity: "platform", GroupCode: "platform", Name: "平台管理", Icon: "icon-settings", Path: "/platform", SortNo: 130, Status: common.StatusEnable},
|
|
|
|
|
|
{Identity: "platform_account", ParentIdentity: "platform", GroupCode: "platform", Name: "平台账户", Path: "/platform/accounts", SortNo: 1, Status: common.StatusEnable},
|
|
|
|
|
|
{Identity: "platform_role", ParentIdentity: "platform", GroupCode: "platform", Name: "平台角色", Path: "/platform/roles", SortNo: 2, Status: common.StatusEnable},
|
|
|
|
|
|
{Identity: "platform_menu", ParentIdentity: "platform", GroupCode: "platform", Name: "平台菜单", Path: "/platform/menus", SortNo: 3, Status: common.StatusEnable},
|
2026-07-29 13:18:52 +08:00
|
|
|
|
},
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// AllPlatformMenus 返回静态菜单的扁平副本。
|
|
|
|
|
|
func AllPlatformMenus() []Menu {
|
|
|
|
|
|
menus := make([]Menu, 0, len(PlatformMenus))
|
|
|
|
|
|
for _, group := range PlatformMenus {
|
|
|
|
|
|
menus = append(menus, group...)
|
|
|
|
|
|
}
|
|
|
|
|
|
return menus
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// FindPlatformMenu 根据稳定 identity 查找静态菜单。
|
|
|
|
|
|
func FindPlatformMenu(identity string) (Menu, bool) {
|
|
|
|
|
|
for _, menu := range AllPlatformMenus() {
|
|
|
|
|
|
if menu.Identity == identity {
|
|
|
|
|
|
return menu, true
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
return Menu{}, false
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// LoadPlatformMenus 返回角色获授权的静态菜单;root 默认拥有全部菜单。
|
|
|
|
|
|
func LoadPlatformMenus(roleCode string) ([]Menu, error) {
|
|
|
|
|
|
menus := AllPlatformMenus()
|
|
|
|
|
|
if roleCode == "root" {
|
|
|
|
|
|
return menus, nil
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var role models.PlatformRole
|
|
|
|
|
|
if err := impl.DBService.Where("role_code = ? AND status = ?", roleCode, common.StatusEnable).First(&role).Error; err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
2026-07-29 14:03:10 +08:00
|
|
|
|
var identities []string
|
2026-07-29 13:18:52 +08:00
|
|
|
|
if err := impl.DBService.Model(&models.PlatformRoleMenu{}).
|
|
|
|
|
|
Where("platform_role_id = ?", role.ID).
|
2026-07-29 14:03:10 +08:00
|
|
|
|
Pluck("menu_identity", &identities).Error; err != nil {
|
2026-07-29 13:18:52 +08:00
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
2026-07-29 14:03:10 +08:00
|
|
|
|
allowed := make(map[string]struct{}, len(identities))
|
|
|
|
|
|
for _, identity := range identities {
|
|
|
|
|
|
allowed[identity] = struct{}{}
|
2026-08-04 23:23:12 +08:00
|
|
|
|
// 兼容历史角色保存的 dashboard 父菜单或报表菜单授权。
|
|
|
|
|
|
if identity == "dashboard" || identity == "dashboard_reports" {
|
|
|
|
|
|
allowed["dashboard_overview"] = struct{}{}
|
|
|
|
|
|
}
|
2026-07-29 14:03:10 +08:00
|
|
|
|
}
|
|
|
|
|
|
for _, menu := range menus {
|
|
|
|
|
|
if _, ok := allowed[menu.Identity]; ok && menu.ParentIdentity != "" {
|
|
|
|
|
|
allowed[menu.ParentIdentity] = struct{}{}
|
|
|
|
|
|
}
|
2026-07-29 13:18:52 +08:00
|
|
|
|
}
|
|
|
|
|
|
filtered := make([]Menu, 0, len(menus))
|
|
|
|
|
|
for _, menu := range menus {
|
2026-07-29 14:03:10 +08:00
|
|
|
|
if _, ok := allowed[menu.Identity]; ok {
|
2026-07-29 13:18:52 +08:00
|
|
|
|
filtered = append(filtered, menu)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
return filtered, nil
|
|
|
|
|
|
}
|