diff --git a/jituan/management/commands/seed_kefu_menu.py b/jituan/management/commands/seed_kefu_menu.py index 3ae68c4..4930d60 100644 --- a/jituan/management/commands/seed_kefu_menu.py +++ b/jituan/management/commands/seed_kefu_menu.py @@ -2,120 +2,7 @@ from django.core.management.base import BaseCommand from jituan.models import KefuMenuPage - -# 固定 page_id,与前端 Layout 一致 -MENU_ROWS = [ - # 板块与财务 - {'page_id': 'finance', 'name': '板块与财务', 'path': '', 'parent_id': '', 'sort_order': 10}, - {'page_id': 'finance.bankuai', 'name': '板块配置', 'path': '/finance/bankuai', 'parent_id': 'finance', 'sort_order': 11, - 'perm_codes': ['bankuai']}, - {'page_id': 'finance.data', 'name': '财务数据', 'path': '/finance/data', 'parent_id': 'finance', 'sort_order': 12, - 'perm_codes': ['caiwu']}, - # 考核 - {'page_id': 'assessment', 'name': '考核管理', 'path': '', 'parent_id': '', 'sort_order': 20}, - {'page_id': 'assessment.examiner', 'name': '考核官管理', 'path': '/assessment/examiner', 'parent_id': 'assessment', 'sort_order': 21, - 'perm_codes': ['kaohepeizhi']}, - {'page_id': 'assessment.config', 'name': '考核配置', 'path': '/assessment/config', 'parent_id': 'assessment', 'sort_order': 22, - 'perm_codes': ['kaohepeizhi']}, - {'page_id': 'assessment.record', 'name': '考核记录', 'path': '/assessment/record', 'parent_id': 'assessment', 'sort_order': 23, - 'perm_codes': ['kaohepeizhi']}, - # 订单 - {'page_id': 'order', 'name': '订单管理', 'path': '', 'parent_id': '', 'sort_order': 30}, - {'page_id': 'order.platform', 'name': '平台订单', 'path': '/order/platform', 'parent_id': 'order', 'sort_order': 31, - 'perm_codes': ['002ab']}, - {'page_id': 'order.merchant', 'name': '商家订单', 'path': '/order/merchant', 'parent_id': 'order', 'sort_order': 32, - 'perm_codes': ['002ac']}, - # 跨平台 - {'page_id': 'cross-platform', 'name': '跨平台管理', 'path': '', 'parent_id': '', 'sort_order': 40}, - {'page_id': 'cross-platform.order', 'name': '跨平台订单', 'path': '/cross-order', 'parent_id': 'cross-platform', 'sort_order': 41, - 'perm_codes': ['003aa']}, - {'page_id': 'cross-platform.settings', 'name': '跨平台设置', 'path': '/cross-settings', 'parent_id': 'cross-platform', 'sort_order': 42, - 'perm_codes': ['003aa']}, - {'page_id': 'cross-platform.data', 'name': '跨平台数据', 'path': '/cross-data', 'parent_id': 'cross-platform', 'sort_order': 43, - 'perm_codes': ['003aa']}, - {'page_id': 'cross-platform.pre', 'name': '预结算管理', 'path': '/cross-pre', 'parent_id': 'cross-platform', 'sort_order': 44, - 'perm_codes': ['003aa']}, - # 用户 - {'page_id': 'user', 'name': '用户管理', 'path': '', 'parent_id': '', 'sort_order': 50}, - {'page_id': 'user.player', 'name': '打手管理', 'path': '/user/player', 'parent_id': 'user', 'sort_order': 51, - 'perm_codes': ['001aa', '001bb', '001cc', '001dd', '001ee', '001ff', '001gg']}, - {'page_id': 'user.guanli', 'name': '管事管理', 'path': '/user/guanli', 'parent_id': 'user', 'sort_order': 52, - 'perm_codes': ['4400a', '4400b', '4400c', '4400d', '4400e', '4400f']}, - {'page_id': 'user.shangjia', 'name': '商家管理', 'path': '/user/shangjia', 'parent_id': 'user', 'sort_order': 53, - 'perm_codes': ['1100a', '1100b']}, - {'page_id': 'user.zuzhang', 'name': '组长管理', 'path': '/user/zuzhang', 'parent_id': 'user', 'sort_order': 54, - 'perm_codes': ['6600a', '6600b', '6600c', '6600d', '6600e']}, - {'page_id': 'user.identity-tag', 'name': '身份装饰标签', 'path': '/user/identity-tag', 'parent_id': 'user', 'sort_order': 55, - 'perm_codes': ['8080a', 'sfbq666']}, - # 提现 - {'page_id': 'withdraw', 'name': '提现管理', 'path': '', 'parent_id': '', 'sort_order': 60}, - {'page_id': 'withdraw.audit', 'name': '提现审核', 'path': '/withdraw/audit', 'parent_id': 'withdraw', 'sort_order': 61, - 'perm_codes': ['005bb']}, - {'page_id': 'withdraw.detail', 'name': '提现详情', 'path': '/withdraw/detail', 'parent_id': 'withdraw', 'sort_order': 62, - 'perm_codes': ['005bb']}, - {'page_id': 'withdraw.data', 'name': '提现数据', 'path': '/withdraw/data', 'parent_id': 'withdraw', 'sort_order': 63, - 'perm_codes': ['005bb']}, - {'page_id': 'withdraw.settings', 'name': '提现设置', 'path': '/withdraw/settings', 'parent_id': 'withdraw', 'sort_order': 64, - 'perm_codes': ['5500a', '5500b', '5500c']}, - # 管理员 - {'page_id': 'admin', 'name': '管理员管理', 'path': '', 'parent_id': '', 'sort_order': 70}, - {'page_id': 'admin.role', 'name': '角色管理', 'path': '/admin/role', 'parent_id': 'admin', 'sort_order': 71, - 'require_super': True}, - {'page_id': 'admin.data-scope', 'name': '数据范围配置', 'path': '/admin/data-scope', 'parent_id': 'admin', 'sort_order': 72, - 'require_group_manage': True}, - {'page_id': 'admin.club-config', 'name': '俱乐部密钥配置', 'path': '/admin/club-config', 'parent_id': 'admin', 'sort_order': 73, - 'require_group_manage': True}, - {'page_id': 'admin.user', 'name': '后台用户', 'path': '/admin/user', 'parent_id': 'admin', 'sort_order': 74, - 'require_super': True}, - {'page_id': 'admin.operation-log', 'name': '操作日志', 'path': '/admin/operation-log', 'parent_id': 'admin', 'sort_order': 75, - 'perm_codes': ['czrz666']}, - # 处罚 - {'page_id': 'punishment', 'name': '处罚管理', 'path': '/punishment', 'parent_id': '', 'sort_order': 80, - 'perm_codes': ['005aa', '66693a', '66693b', '66693c', '66694c', '99933abs']}, - {'page_id': 'punishment.detail', 'name': '积分处罚详情', 'path': '/punishment/detail', 'parent_id': 'punishment', 'sort_order': 81, - 'perm_codes': ['005aa', '66693a', '66693b', '66693c', '66694c', '99933abs']}, - # 商品 - {'page_id': 'product', 'name': '商品管理', 'path': '', 'parent_id': '', 'sort_order': 90}, - {'page_id': 'product.list', 'name': '商品列表', 'path': '/product/list', 'parent_id': 'product', 'sort_order': 91, - 'perm_codes': ['2200a']}, - {'page_id': 'product.type-zone', 'name': '商品类型专区管理', 'path': '/product/type-zone', 'parent_id': 'product', 'sort_order': 92, - 'perm_codes': ['7007a']}, - {'page_id': 'product.data', 'name': '商品数据分析', 'path': '/product/data', 'parent_id': 'product', 'sort_order': 93, - 'perm_codes': ['2200a']}, - # 会员 - {'page_id': 'member', 'name': '会员管理', 'path': '', 'parent_id': '', 'sort_order': 100}, - {'page_id': 'member.list', 'name': '会员管理', 'path': '/member/list', 'parent_id': 'member', 'sort_order': 101, - 'perm_codes': ['3300a']}, - {'page_id': 'member.data', 'name': '会员数据分析', 'path': '/member/data', 'parent_id': 'member', 'sort_order': 102, - 'perm_codes': ['huiyuancaiwu']}, - # 小程序 - {'page_id': 'miniapp', 'name': '小程序配置', 'path': '', 'parent_id': '', 'sort_order': 110}, - {'page_id': 'miniapp.carousel', 'name': '轮播图与公告', 'path': '/miniapp/carousel', 'parent_id': 'miniapp', 'sort_order': 111, - 'perm_codes': ['8080a']}, - {'page_id': 'miniapp.assets', 'name': '图标与频道', 'path': '/miniapp/assets', 'parent_id': 'miniapp', 'sort_order': 112, - 'perm_codes': ['8080a']}, - {'page_id': 'miniapp.popup', 'name': '弹窗公告管理', 'path': '/miniapp/popup-notice', 'parent_id': 'miniapp', 'sort_order': 113, - 'perm_codes': ['8080a']}, - {'page_id': 'miniapp.withdraw-settings', 'name': '提现与收款设置', 'path': '/withdraw/settings', 'parent_id': 'miniapp', 'sort_order': 114, - 'perm_codes': ['5500a', '5500b', '5500c']}, - {'page_id': 'miniapp.leixing', 'name': '抢单商品类型', 'path': '/miniapp/leixing', 'parent_id': 'miniapp', 'sort_order': 115, - 'perm_codes': ['8080a']}, - {'page_id': 'miniapp.kaohe-tags', 'name': '抢单考核标签', 'path': '/miniapp/kaohe-tags', 'parent_id': 'miniapp', 'sort_order': 116, - 'perm_codes': ['8080a']}, - {'page_id': 'miniapp.dashou-exam', 'name': '打手接单考试', 'path': '/miniapp/dashou-exam', 'parent_id': 'miniapp', 'sort_order': 117, - 'perm_codes': ['dsks666', '8080a']}, - # 店铺 - {'page_id': 'shop', 'name': '店铺管理', 'path': '', 'parent_id': '', 'sort_order': 120}, - {'page_id': 'shop.list', 'name': '店铺列表', 'path': '/shop/list', 'parent_id': 'shop', 'sort_order': 121, - 'perm_codes': ['999a', '999b', '999c', '999d', '999e']}, - {'page_id': 'shop.withdraw', 'name': '店铺提现申请', 'path': '/shop/withdraw-apply', 'parent_id': 'shop', 'sort_order': 122, - 'perm_codes': ['999a', '999b', '999c', '999d', '999e']}, - {'page_id': 'shop.products', 'name': '店铺商品管理', 'path': '/shop/products', 'parent_id': 'shop', 'sort_order': 123, - 'perm_codes': ['999a', '999b', '999c', '999d', '999e']}, - # 会话 - {'page_id': 'chat.agent', 'name': '会话管理', 'path': '/chat/agent', 'parent_id': '', 'sort_order': 130, - 'perm_codes': ['abca1', 'baac2', 'cabc3', 'cb3a2', 'bcaa4']}, -] +from jituan.services.kefu_menu_definitions import KEFU_MENU_ROW_DEFS class Command(BaseCommand): @@ -123,7 +10,7 @@ class Command(BaseCommand): def handle(self, *args, **options): created, updated = 0, 0 - for row in MENU_ROWS: + for row in KEFU_MENU_ROW_DEFS: defaults = { 'name': row['name'], 'path': row.get('path', ''), @@ -143,7 +30,7 @@ class Command(BaseCommand): KefuMenuPage(page_id=row['page_id'], **defaults).save() created += 1 self.stdout.write(self.style.SUCCESS( - f'kefu_menu_page 种子完成:新增 {created},更新 {updated},共 {len(MENU_ROWS)} 条' + f'kefu_menu_page 种子完成:新增 {created},更新 {updated},共 {len(KEFU_MENU_ROW_DEFS)} 条' )) try: from django.core.management import call_command diff --git a/jituan/services/kefu_menu.py b/jituan/services/kefu_menu.py index 3c10be1..277b55f 100644 --- a/jituan/services/kefu_menu.py +++ b/jituan/services/kefu_menu.py @@ -1,4 +1,7 @@ """客服后台菜单可见性(侧栏展示,不影响各页面原有权限校验)。""" +import logging +from types import SimpleNamespace + from backend.utils import _AllPermissions, verify_kefu_permission from jituan.models import KefuMenuPage from jituan.services.admin_context import ( @@ -6,6 +9,9 @@ from jituan.services.admin_context import ( can_manage_admin_assignments, is_system_super_admin, ) +from jituan.services.kefu_menu_definitions import KEFU_MENU_ROW_DEFS + +logger = logging.getLogger(__name__) def _is_super_permissions(permissions): @@ -20,15 +26,12 @@ def _has_super_perm(permissions): def _page_visible(page, permissions, user): - # 集团级页面:数据范围、俱乐部密钥等,俱乐部 000001 不可见 if page.require_group_manage: return can_manage_admin_assignments(user) - # 俱乐部超管页面:角色管理、后台用户等 if page.require_super: return _has_super_perm(permissions) or is_system_super_admin(user) - # 000001 拥有全部业务功能菜单(订单/用户/财务等),但不绕过上面的集团级限制 if _is_super_permissions(permissions): return True @@ -44,6 +47,58 @@ def _permission_codes_list(permissions): return list(permissions) if permissions else [] +def _builtin_menu_pages(): + """DB 无数据时的内置菜单(与 seed_kefu_menu 定义一致)。""" + pages = [] + for row in KEFU_MENU_ROW_DEFS: + pages.append(SimpleNamespace( + page_id=row['page_id'], + name=row['name'], + path=row.get('path', ''), + parent_id=row.get('parent_id', ''), + sort_order=row.get('sort_order', 0), + perm_codes=row.get('perm_codes', []), + require_super=row.get('require_super', False), + require_group_manage=row.get('require_group_manage', False), + )) + return pages + + +def _load_menu_pages(): + """从 DB 加载菜单;失败或空表时尝试 seed,仍空则用内置定义。""" + pages = [] + menu_source = 'db' + try: + pages = KefuMenuPage.objects.all().order_by('sort_order', 'page_id') + pages = list(pages) + except Exception as e: + logger.warning('KefuMenuPage.objects 读取失败: %s', e) + pages = [] + + if not pages: + try: + pages = KefuMenuPage.query.order_by('sort_order', 'page_id').to_list() + except Exception as e: + logger.warning('KefuMenuPage.query 读取失败: %s', e) + pages = [] + + need_seed = not pages or not any(p.page_id == 'miniapp.assets' for p in pages) + if need_seed: + try: + from django.core.management import call_command + call_command('seed_kefu_menu') + pages = list(KefuMenuPage.objects.all().order_by('sort_order', 'page_id')) + except Exception as e: + logger.warning('seed_kefu_menu 自动执行失败: %s', e) + + if not pages: + pages = _builtin_menu_pages() + menu_source = 'builtin' + logger.warning('kefu_menu_page 表无数据,使用内置菜单定义(请执行 migrate jituan + seed_kefu_menu)') + + return pages, menu_source + + def build_menu_access_payload(request, username=None): """ 根据用户 gvsdsdk 权限计算可见菜单 page_id 列表。 @@ -54,16 +109,7 @@ def build_menu_access_payload(request, username=None): if kefu is None: return None, permissions - pages = list(KefuMenuPage.query.all().order_by('sort_order', 'page_id')) - need_seed = not pages or not any(p.page_id == 'miniapp.assets' for p in pages) - if need_seed: - try: - from django.core.management import call_command - call_command('seed_kefu_menu') - pages = list(KefuMenuPage.query.all().order_by('sort_order', 'page_id')) - except Exception: - if not pages: - pages = [] + pages, menu_source = _load_menu_pages() visible_ids = [] for page in pages: @@ -88,5 +134,6 @@ def build_menu_access_payload(request, username=None): 'permission_codes': _permission_codes_list(permissions), 'can_switch_club': bool(club_ctx.get('can_switch_club')), 'is_group_admin': bool(club_ctx.get('is_group_admin')), - 'menu_ready': bool(pages), + 'menu_ready': True, + 'menu_source': menu_source, }, None diff --git a/jituan/services/kefu_menu_definitions.py b/jituan/services/kefu_menu_definitions.py new file mode 100644 index 0000000..6ea837e --- /dev/null +++ b/jituan/services/kefu_menu_definitions.py @@ -0,0 +1,101 @@ +"""客服后台菜单定义(与前端 Layout / router 一致,种子与运行时回退共用)。""" + +KEFU_MENU_ROW_DEFS = [ + {'page_id': 'finance', 'name': '板块与财务', 'path': '', 'parent_id': '', 'sort_order': 10}, + {'page_id': 'finance.bankuai', 'name': '板块配置', 'path': '/finance/bankuai', 'parent_id': 'finance', 'sort_order': 11, + 'perm_codes': ['bankuai']}, + {'page_id': 'finance.data', 'name': '财务数据', 'path': '/finance/data', 'parent_id': 'finance', 'sort_order': 12, + 'perm_codes': ['caiwu']}, + {'page_id': 'assessment', 'name': '考核管理', 'path': '', 'parent_id': '', 'sort_order': 20}, + {'page_id': 'assessment.examiner', 'name': '考核官管理', 'path': '/assessment/examiner', 'parent_id': 'assessment', 'sort_order': 21, + 'perm_codes': ['kaohepeizhi']}, + {'page_id': 'assessment.config', 'name': '考核配置', 'path': '/assessment/config', 'parent_id': 'assessment', 'sort_order': 22, + 'perm_codes': ['kaohepeizhi']}, + {'page_id': 'assessment.record', 'name': '考核记录', 'path': '/assessment/record', 'parent_id': 'assessment', 'sort_order': 23, + 'perm_codes': ['kaohepeizhi']}, + {'page_id': 'order', 'name': '订单管理', 'path': '', 'parent_id': '', 'sort_order': 30}, + {'page_id': 'order.platform', 'name': '平台订单', 'path': '/order/platform', 'parent_id': 'order', 'sort_order': 31, + 'perm_codes': ['002ab']}, + {'page_id': 'order.merchant', 'name': '商家订单', 'path': '/order/merchant', 'parent_id': 'order', 'sort_order': 32, + 'perm_codes': ['002ac']}, + {'page_id': 'cross-platform', 'name': '跨平台管理', 'path': '', 'parent_id': '', 'sort_order': 40}, + {'page_id': 'cross-platform.order', 'name': '跨平台订单', 'path': '/cross-order', 'parent_id': 'cross-platform', 'sort_order': 41, + 'perm_codes': ['003aa']}, + {'page_id': 'cross-platform.settings', 'name': '跨平台设置', 'path': '/cross-settings', 'parent_id': 'cross-platform', 'sort_order': 42, + 'perm_codes': ['003aa']}, + {'page_id': 'cross-platform.data', 'name': '跨平台数据', 'path': '/cross-data', 'parent_id': 'cross-platform', 'sort_order': 43, + 'perm_codes': ['003aa']}, + {'page_id': 'cross-platform.pre', 'name': '预结算管理', 'path': '/cross-pre', 'parent_id': 'cross-platform', 'sort_order': 44, + 'perm_codes': ['003aa']}, + {'page_id': 'user', 'name': '用户管理', 'path': '', 'parent_id': '', 'sort_order': 50}, + {'page_id': 'user.player', 'name': '打手管理', 'path': '/user/player', 'parent_id': 'user', 'sort_order': 51, + 'perm_codes': ['001aa', '001bb', '001cc', '001dd', '001ee', '001ff', '001gg']}, + {'page_id': 'user.guanli', 'name': '管事管理', 'path': '/user/guanli', 'parent_id': 'user', 'sort_order': 52, + 'perm_codes': ['4400a', '4400b', '4400c', '4400d', '4400e', '4400f']}, + {'page_id': 'user.shangjia', 'name': '商家管理', 'path': '/user/shangjia', 'parent_id': 'user', 'sort_order': 53, + 'perm_codes': ['1100a', '1100b']}, + {'page_id': 'user.zuzhang', 'name': '组长管理', 'path': '/user/zuzhang', 'parent_id': 'user', 'sort_order': 54, + 'perm_codes': ['6600a', '6600b', '6600c', '6600d', '6600e']}, + {'page_id': 'user.identity-tag', 'name': '身份装饰标签', 'path': '/user/identity-tag', 'parent_id': 'user', 'sort_order': 55, + 'perm_codes': ['8080a', 'sfbq666']}, + {'page_id': 'withdraw', 'name': '提现管理', 'path': '', 'parent_id': '', 'sort_order': 60}, + {'page_id': 'withdraw.audit', 'name': '提现审核', 'path': '/withdraw/audit', 'parent_id': 'withdraw', 'sort_order': 61, + 'perm_codes': ['005bb']}, + {'page_id': 'withdraw.detail', 'name': '提现详情', 'path': '/withdraw/detail', 'parent_id': 'withdraw', 'sort_order': 62, + 'perm_codes': ['005bb']}, + {'page_id': 'withdraw.data', 'name': '提现数据', 'path': '/withdraw/data', 'parent_id': 'withdraw', 'sort_order': 63, + 'perm_codes': ['005bb']}, + {'page_id': 'withdraw.settings', 'name': '提现设置', 'path': '/withdraw/settings', 'parent_id': 'withdraw', 'sort_order': 64, + 'perm_codes': ['5500a', '5500b', '5500c']}, + {'page_id': 'admin', 'name': '管理员管理', 'path': '', 'parent_id': '', 'sort_order': 70}, + {'page_id': 'admin.role', 'name': '角色管理', 'path': '/admin/role', 'parent_id': 'admin', 'sort_order': 71, + 'require_super': True}, + {'page_id': 'admin.data-scope', 'name': '数据范围配置', 'path': '/admin/data-scope', 'parent_id': 'admin', 'sort_order': 72, + 'require_group_manage': True}, + {'page_id': 'admin.club-config', 'name': '俱乐部密钥配置', 'path': '/admin/club-config', 'parent_id': 'admin', 'sort_order': 73, + 'require_group_manage': True}, + {'page_id': 'admin.user', 'name': '后台用户', 'path': '/admin/user', 'parent_id': 'admin', 'sort_order': 74, + 'require_super': True}, + {'page_id': 'admin.operation-log', 'name': '操作日志', 'path': '/admin/operation-log', 'parent_id': 'admin', 'sort_order': 75, + 'perm_codes': ['czrz666']}, + {'page_id': 'punishment', 'name': '处罚管理', 'path': '/punishment', 'parent_id': '', 'sort_order': 80, + 'perm_codes': ['005aa', '66693a', '66693b', '66693c', '66694c', '99933abs']}, + {'page_id': 'punishment.detail', 'name': '积分处罚详情', 'path': '/punishment/detail', 'parent_id': 'punishment', 'sort_order': 81, + 'perm_codes': ['005aa', '66693a', '66693b', '66693c', '66694c', '99933abs']}, + {'page_id': 'product', 'name': '商品管理', 'path': '', 'parent_id': '', 'sort_order': 90}, + {'page_id': 'product.list', 'name': '商品列表', 'path': '/product/list', 'parent_id': 'product', 'sort_order': 91, + 'perm_codes': ['2200a']}, + {'page_id': 'product.type-zone', 'name': '商品类型专区管理', 'path': '/product/type-zone', 'parent_id': 'product', 'sort_order': 92, + 'perm_codes': ['7007a']}, + {'page_id': 'product.data', 'name': '商品数据分析', 'path': '/product/data', 'parent_id': 'product', 'sort_order': 93, + 'perm_codes': ['2200a']}, + {'page_id': 'member', 'name': '会员管理', 'path': '', 'parent_id': '', 'sort_order': 100}, + {'page_id': 'member.list', 'name': '会员管理', 'path': '/member/list', 'parent_id': 'member', 'sort_order': 101, + 'perm_codes': ['3300a']}, + {'page_id': 'member.data', 'name': '会员数据分析', 'path': '/member/data', 'parent_id': 'member', 'sort_order': 102, + 'perm_codes': ['huiyuancaiwu']}, + {'page_id': 'miniapp', 'name': '小程序配置', 'path': '', 'parent_id': '', 'sort_order': 110}, + {'page_id': 'miniapp.carousel', 'name': '轮播图与公告', 'path': '/miniapp/carousel', 'parent_id': 'miniapp', 'sort_order': 111, + 'perm_codes': ['8080a']}, + {'page_id': 'miniapp.assets', 'name': '图标与频道', 'path': '/miniapp/assets', 'parent_id': 'miniapp', 'sort_order': 112, + 'perm_codes': ['8080a']}, + {'page_id': 'miniapp.popup', 'name': '弹窗公告管理', 'path': '/miniapp/popup-notice', 'parent_id': 'miniapp', 'sort_order': 113, + 'perm_codes': ['8080a']}, + {'page_id': 'miniapp.withdraw-settings', 'name': '提现与收款设置', 'path': '/withdraw/settings', 'parent_id': 'miniapp', 'sort_order': 114, + 'perm_codes': ['5500a', '5500b', '5500c']}, + {'page_id': 'miniapp.leixing', 'name': '抢单商品类型', 'path': '/miniapp/leixing', 'parent_id': 'miniapp', 'sort_order': 115, + 'perm_codes': ['8080a']}, + {'page_id': 'miniapp.kaohe-tags', 'name': '抢单考核标签', 'path': '/miniapp/kaohe-tags', 'parent_id': 'miniapp', 'sort_order': 116, + 'perm_codes': ['8080a']}, + {'page_id': 'miniapp.dashou-exam', 'name': '打手接单考试', 'path': '/miniapp/dashou-exam', 'parent_id': 'miniapp', 'sort_order': 117, + 'perm_codes': ['dsks666', '8080a']}, + {'page_id': 'shop', 'name': '店铺管理', 'path': '', 'parent_id': '', 'sort_order': 120}, + {'page_id': 'shop.list', 'name': '店铺列表', 'path': '/shop/list', 'parent_id': 'shop', 'sort_order': 121, + 'perm_codes': ['999a', '999b', '999c', '999d', '999e']}, + {'page_id': 'shop.withdraw', 'name': '店铺提现申请', 'path': '/shop/withdraw-apply', 'parent_id': 'shop', 'sort_order': 122, + 'perm_codes': ['999a', '999b', '999c', '999d', '999e']}, + {'page_id': 'shop.products', 'name': '店铺商品管理', 'path': '/shop/products', 'parent_id': 'shop', 'sort_order': 123, + 'perm_codes': ['999a', '999b', '999c', '999d', '999e']}, + {'page_id': 'chat.agent', 'name': '会话管理', 'path': '/chat/agent', 'parent_id': '', 'sort_order': 130, + 'perm_codes': ['abca1', 'baac2', 'cabc3', 'cb3a2', 'bcaa4']}, +]