文档目录
后台架构设计

简介

本文面向 DouPHP 后台管理系统的架构与实现,聚焦以下目标:

  • 解释后台 MVC 架构设计,尤其是控制器基类 BaseController 的设计模式与初始化流程 Init.php 的工作机制。
  • 深入解析路由解析器 AdminResolver 的实现原理与中间件链执行顺序(认证、权限、安全等)。
  • 梳理从入口 index.php 到最终响应返回的完整请求处理链路。
  • 提供扩展后台功能的具体实践:新增控制器、服务层与视图模板的步骤。
  • 给出性能优化建议与最佳实践指导。

项目结构

后台模块采用分层清晰的 MVC + 中间件管道架构:

  • 入口与调度:admin/index.php 负责引导、异常处理与响应发送;admin/foundation/routing/* 负责路由解析与分发。
  • 初始化:admin/init/Init.php 完成会话、配置、视图引擎、模块装配、语言包、主题与工作区变量注入。
  • 控制器:admin/controller/* 下的业务控制器统一继承 BaseController,封装视图渲染、AI 工具栏注入、删除/开关响应等通用逻辑。
  • 服务层:admin/service/* 承载领域逻辑,控制器通过依赖注入或门面调用。
  • 模型:admin/model/* 对应数据访问。
  • 路由声明:admin/route/*.php 以声明式方式定义 URL 到控制器方法的映射。
  • 中间件:admin/middleware/* 实现安全、认证、权限、CSRF、工作台变量注入等横切关注点。
  • 视图:admin/view/* 为 .htm 模板,配合 DouView 引擎渲染。
  • 新增 模块化导航配置:admin/nav/*.php 为各功能模块提供独立的菜单定义文件。
graph TB
A["admin/index.php<br/>入口与异常处理"] --> B["Admin\\Init\\Init::boot()<br/>初始化核心对象/视图/模块"]
B --> C["Route::dispatch()<br/>调度"]
C --> D["Admin\\Foundation\\Routing\\Router::dispatch()"]
D --> E["Admin\\Foundation\\Routing\\AdminResolver::resolve()"]
E --> F["中间件栈<br/>security_headers → trust_proxy → auth → permission → csrf → workspace"]
F --> G["Dispatcher 执行控制器方法"]
G --> H["BaseController::view()<br/>合并布局变量/AI工具栏"]
H --> I["DouView 渲染模板"]
I --> J["Response->send()"]
K["模块化导航配置<br/>admin/nav/*.php"] --> L["AdminMenuRegistry<br/>扫描并装配"]
L --> M["AdminNavResolver<br/>计算导航状态"]
M --> N["模板渲染<br/>sidebar.tpl"]

核心组件

  • 入口与异常处理:admin/index.php 设置路由委托、写入 route 参数、启动 Init、调度路由、捕获并统一输出错误。
  • 初始化:Init.php 按序启动会话、错误报告、时区、常量、核心对象、视图引擎、模块加载、语言包、授权检测、工作区变量注入。
  • 路由解析:AdminResolver.php 基于 BackendDeclaredMatcher 匹配 admin/route/*.php 中的 declared 条目,产出 DispatchPlan,组装中间件栈。
  • 路由调度:Router.php 将 DispatchPlan 交给 Dispatcher 执行,未命中或方法不允许时重定向至首页并携带提示。
  • 控制器基类:BaseController.php 提供 view()、layoutVars()、AI 工具栏注入、删除结果响应、布尔切换响应等通用能力。
  • 菜单注册表:AdminMenuRegistry.php 提供声明式的菜单定义,支持核心族和模块族动态装配。
  • 导航解析器:AdminNavResolver.php 基于当前路由名计算激活状态,生成统一的导航数据结构。
  • 中间件:AuthMiddleware、PermissionMiddleware、CsrfMiddleware、AdminWorkspaceMiddleware 分别承担认证恢复、权限校验、CSRF 校验、工作台变量注入。
  • 新增 模块化导航配置:六个独立模块的导航配置文件,提供细粒度的菜单管理能力。

架构总览

后台采用"声明式路由 + 中间件管道 + 声明式菜单"的 MVC 架构:

  • 入口将 ?route=... 解析为 Request 的路由字符串,交由 Router 调度。
  • AdminResolver 根据声明式路由表匹配模块、动作、路径参数,生成 DispatchPlan。
  • 中间件栈按默认顺序执行:安全头、代理信任、认证、权限、CSRF、工作台变量注入。
  • AdminMenuRegistry 提供声明式菜单定义,AdminNavResolver 基于当前路由计算激活状态。
  • 控制器方法执行后返回 Response(视图/JSON/重定向),由入口统一发送。
  • 新增 模块化导航配置系统,通过 glob 扫描 admin/nav/*.php 文件自动装配各模块菜单。
sequenceDiagram
participant Client as "客户端"
participant Entry as "admin/index.php"
participant Init as "Init : : boot()"
participant Route as "Route : : dispatch()"
participant Rtr as "Router : : dispatch()"
participant Res as "AdminResolver : : resolve()"
participant MW as "中间件栈"
participant MenuReg as "AdminMenuRegistry"
participant NavRes as "AdminNavResolver"
participant Ctrl as "控制器方法"
participant View as "DouView"
Client->>Entry : HTTP 请求
Entry->>Init : boot()
Init-->>Entry : 初始化完成
Entry->>Route : dispatch()
Route->>Rtr : dispatch()
Rtr->>Res : resolve(request, container)
Res-->>Rtr : DispatchPlan(含中间件)
Rtr->>MW : 依次执行中间件
MW-->>Ctrl : 放行后执行业务方法
Ctrl->>MenuReg : 获取菜单定义
MenuReg-->>Ctrl : 菜单族数据
Ctrl->>NavRes : 计算导航状态
NavRes-->>Ctrl : $nav 数据结构
Ctrl->>View : 渲染模板/返回响应
View-->>Ctrl : Response
Ctrl-->>Rtr : Response
Rtr-->>Entry : Response
Entry->>Client : send()

详细组件分析

入口与异常处理(admin/index.php)

  • 设置路由委托为 Admin\Router,并将 $_GET['route'] 写入 Request 后清理超全局,避免污染。
  • 启动 Init 进行系统初始化,随后调用 Route::dispatch() 执行路由。
  • 捕获 HttpResponseException、RedirectException、DomainException 以及通用 Exception/Throwable,统一输出 JSON 或后台提示页。

初始化流程(admin/init/Init.php)

  • 启动会话、错误报告、时区、后台常量(IS_ADMIN、ADMIN_DIR 等)。
  • 启动核心对象、注册守卫、ProviderRegistry、语言契约、插件服务、消息响应器等。
  • 计算 ROOT_URL/SITE_URL/HOME_URL/ADMIN_URL/API_URL/PLUGIN_URL,并设置 Request base URL。
  • 设置视图引擎 DouView,配置模板目录、编译目录、转义、预处理器,并注入站点信息、主题、语言、CSRF token、工作区变量等。
  • 加载模块与语言包,同步 features、module、system、param 等配置。
  • 授权检测:读取 cdkey 并设置 app.licensed、pure_mode、partner_authorize 等。
  • 注册 WorkspaceBuilder、UpdateBadgeBuilder、ThemeSettingsReader 等服务,供后续中间件与模板使用。

更新 增强了未命中路由的安全处理,在 loadModules 阶段添加了 nav 变量的兜底初始化,确保即使路由未正确派发也能提供安全的默认导航状态。

路由解析器(AdminResolver.php)

  • 默认中间件别名栈:security_headers、trust_proxy、auth、permission、csrf、workspace。
  • 通过 BackendDeclaredMatcher 匹配 admin/route/*.php 中声明的条目,支持 HTTP 方法与优先级排序。
  • 若未命中返回 notFound,方法不允许返回 methodNotAllowed。
  • 组装 Request 路由信息(base URL、模块、动作、子路径、参数),并注入 cur 与表单提交目标(create/edit)。
  • 构建 MiddlewareRegistry 并组合最终中间件实例链,返回 DispatchPlan。

更新 引入了新的 $nav 变量结构,通过 AdminNavResolver::resolve() 方法解析路由名为统一的导航数据结构,替代了传统的单个变量处理方式。

模块化导航配置系统

AI 模块导航配置

AI 模块提供了完整的 AI 功能菜单结构,包括 AI 生成、模型管理、日志查看和任务管理等子菜单项。

return array(
    'title' => 'ai',
    'icon' => 'bi-robot',
    'items' => array(
        array(
            'key' => 'ai', 'name' => 'ai', 'link' => 'admin.ai',
            'match' => array('admin.ai.*', 'admin.ai_generate.*'),
        ),
        array(
            'key' => 'model', 'name' => 'ai_model', 'link' => 'admin.ai.model',
            'match' => array('admin.ai.model.*', 'admin.ai.key.*'),
        ),
        array(
            'key' => 'log', 'name' => 'ai_log', 'link' => 'admin.ai.log',
            'match' => array('admin.ai.log.*'),
        ),
        array(
            'key' => 'task', 'name' => 'ai_task', 'link' => 'admin.ai.task',
            'match' => array('admin.ai.task.*'),
        ),
    ),
);

Book 模块导航配置

Book 模块专注于预约管理系统,包含作品管理、日程安排、规则配置、分类管理和黑名单等功能。

return array(
    'title' => 'book',
    'icon' => 'bi-book',
    'items' => array(
        array(
            'key' => 'book', 'name' => 'book', 'link' => 'admin.book',
            'match' => array('admin.book.*'), 'exclude' => array('admin.book.work.*'),
        ),
        array('key' => 'item', 'name' => 'book_item', 'link' => 'admin.book.item', 'match' => array('admin.book.item.*')),
        array('key' => 'schedule', 'name' => 'book_schedule', 'link' => 'admin.book.schedule', 'match' => array('admin.book.schedule.*')),
        array(
            'key' => 'rule', 'name' => 'book_rule', 'link' => 'admin.book.rule',
            'match' => array('admin.book.rule.*', 'admin.book.rule_slot.*'),
        ),
        array('key' => 'class', 'name' => 'book_class', 'link' => 'admin.book.class', 'match' => array('admin.book.class.*')),
        array('key' => 'contact', 'name' => 'book_contact', 'link' => 'admin.book.contact', 'match' => array('admin.book.contact.*')),
        array('key' => 'blacklist', 'name' => 'book_blacklist', 'link' => 'admin.book.blacklist', 'match' => array('admin.book.blacklist.*')),
        array(
            'key' => 'set', 'name' => 'book_set', 'link' => 'admin.book.set',
            'match' => array('admin.book.set'),
        ),
    ),
);

Chat 模块导航配置

Chat 模块提供智能聊天功能,包含会话管理、知识库、套餐订阅、配额管理和使用统计等高级功能。

return array(
    'title' => 'chat',
    'icon' => 'bi-chat',
    'items' => array(
        array('key' => 'chat', 'name' => 'chat', 'link' => 'admin.chat', 'match' => array('admin.chat.*')),
        array('key' => 'session', 'name' => 'chat_session', 'link' => 'admin.chat.session', 'match' => array('admin.chat.session.*')),
        array(
            'key' => 'knowledge', 'name' => 'chat_knowledge', 'link' => 'admin.chat.knowledge',
            'match' => array('admin.chat.knowledge.*', 'admin.chat_knowledge.category.*'),
        ),
        array('key' => 'package', 'name' => 'chat_package', 'link' => 'admin.chat.package', 'match' => array('admin.chat.package.*')),
        array('key' => 'subscription', 'name' => 'chat_subscription', 'link' => 'admin.chat.subscription', 'match' => array('admin.chat.subscription.*')),
        array('key' => 'quota', 'name' => 'chat_quota', 'link' => 'admin.chat.quota', 'match' => array('admin.chat.quota.*')),
        array('key' => 'usage_log', 'name' => 'chat_usage_log', 'link' => 'admin.chat.usage_log', 'match' => array('admin.chat.usage_log.*')),
        array('key' => 'daily_stats', 'name' => 'chat_daily_stats', 'link' => 'admin.chat.daily_stats', 'match' => array('admin.chat.daily_stats.*')),
        array('key' => 'task', 'name' => 'chat_task', 'link' => 'admin.chat.task', 'match' => array('admin.chat.task.*')),
    ),
);

Distribution 模块导航配置

Distribution 模块专注于分销系统,包含分销申请、奖励管理、等级系统和等级日志等功能。

return array(
    'title' => 'distribution',
    'icon' => 'bi-diagram-3',
    'items' => array(
        array('key' => 'people', 'name' => 'distribution_apply', 'link' => 'admin.distribution', 'match' => array('admin.distribution.*')),
        array('key' => 'reward', 'name' => 'distribution_reward', 'link' => 'admin.distribution.reward', 'match' => array('admin.distribution.reward.*')),
        array('key' => 'level', 'name' => 'distribution_level', 'link' => 'admin.distribution.level', 'match' => array('admin.distribution.level.*')),
        array('key' => 'level_log', 'name' => 'distribution_level_log_manager', 'link' => 'admin.distribution.level_log', 'match' => array('admin.distribution.level_log.*')),
    ),
);

User 模块导航配置

User 模块提供用户管理功能,包含会员管理、联系方式、操作日志和等级日志等核心功能。

return array(
    'title' => 'user',
    'icon' => 'bi-people',
    'items' => array(
        array(
            'key' => 'user', 'name' => 'user', 'link' => 'admin.user',
            'match' => array('admin.user.*'),
        ),
        array('key' => 'user_center_placeholder', 'source' => 'user_center'),
        array(
            'key' => 'contact', 'name' => 'user_contact_manager', 'link' => 'admin.user.contact',
            'match' => array('admin.user.contact.*'),
        ),
        array(
            'key' => 'log', 'name' => 'user_log_manager', 'link' => 'admin.user.log',
            'match' => array('admin.user.log.*'),
        ),
        array(
            'key' => 'level_log', 'name' => 'user_level_log_manager', 'link' => 'admin.user.level_log',
            'match' => array('admin.user.level_log.*'),
        ),
    ),
);

Weixin 模块导航配置

Weixin 模块集成微信功能,包含菜单管理、媒体管理和系统配置等微信相关功能。

return array(
    'title' => 'weixin',
    'icon' => 'bi-weixin',
    'items' => array(
        array('key' => 'menu', 'name' => 'weixin_menu', 'link' => 'admin.weixin.menu', 'match' => array('admin.weixin.menu.*')),
        array(
            'key' => 'media', 'name' => 'weixin_media', 'link' => 'admin.weixin.media',
            'match' => array('admin.weixin.media.*', 'admin.weixin_media.*'),
        ),
        array('key' => 'system', 'name' => 'weixin_system', 'link' => 'admin.weixin.system', 'match' => array('admin.weixin.system.*')),
    ),
);

新增 这是新引入的模块化导航配置系统,为六个核心功能模块提供了独立的菜单定义,支持更清晰的职责分离和更好的可维护性。

菜单注册表(AdminMenuRegistry.php)

  • 提供声明式的菜单定义,包含核心族(manager、miniprogram、site_home)和模块族。
  • 支持条件判断(when)、路由匹配(match/exclude)、可见性控制等功能。
  • 模块族通过 glob 扫描 admin/nav/*.php 文件动态装配,随模块安装/卸载生命周期管理。
  • 提供侧栏节点定义(sideNodes)和会员中心入口映射(userCenterFamilies)。

更新 增强了模块化导航配置的扫描和装配机制,现在支持六个核心模块的独立导航配置文件。

导航解析器(AdminNavResolver.php)

  • 基于当前路由名计算激活状态,生成统一的导航数据结构。
  • 支持段边界通配匹配(如 admin.user.*)、精确匹配、排除规则等。
  • 计算子菜单激活项、侧栏节点激活状态、页面级覆盖等。
  • 提供 emptyNav() 方法处理未派发场景的默认导航状态。

更新 增强了对模块化导航配置的支持,能够正确处理新增的六个模块的导航状态计算。

数据控制器(DataController.php)

  • 继承 BaseController,提供数据管理的完整 CRUD 功能。
  • 实现了数据驱动的导航状态计算,通过 navVars() 方法根据记录所属数据组动态确定导航状态。
  • 支持 banner、miniprogram 等特殊数据组的导航分组逻辑。

更新 重构了渲染逻辑以支持新的 $nav 变量结构,通过页面级覆盖机制处理复杂的导航场景。

路由调度(Router.php)

  • 获取 Request,调用 AdminResolver::resolve 得到 DispatchPlan。
  • 未命中或方法不允许时,重定向到后台首页并携带 page_wrong 提示。
  • 成功则交由 Dispatcher 运行中间件与控制器,返回 Response。

控制器基类(BaseController.php)

  • view():创建 ViewResponse,自动合并 layoutVars() 与 action data,并注入 AI 工具栏与绝对化按钮链接。
  • layoutVars():默认注入 flashes、page_actions、page_sub_actions、breadcrumb、cue 等公共变量。
  • respondDeleteResult():统一删除结果分流,支持二次确认页面或 302 + flash。
  • respondToggle():行内布尔切换,AJAX 返回 JSON,普通请求 302 + flash。
  • buildLinkUserCenter():会员中心子导航 ViewModel 构建。

更新 新增了导航兜底变量机制,通过 navFallbackVars() 方法确保向后兼容,同时支持新的 $nav 结构。

中间件机制

  • AuthMiddleware:从 Session 恢复管理员登录态,未登录抛异常跳转登录页。
  • PermissionMiddleware:校验当前管理员对模块/动作的访问权限,越权重定向至后台首页。
  • CsrfMiddleware:校验 CSRF 令牌,支持特定路由豁免与 GET 续跑场景;失败抛出 DomainException 走 message()->respond()。
  • AdminWorkspaceMiddleware:在认证与权限通过后注入 global_admin、workspace、unum 等视图变量。
flowchart TD
Start(["进入中间件栈"]) --> SH["SecurityHeadersMiddleware"]
SH --> TP["TrustProxyMiddleware"]
TP --> AUTH["AuthMiddleware<br/>恢复登录态"]
AUTH --> |未登录| REDIR1["重定向到登录页"]
AUTH --> PERM["PermissionMiddleware<br/>校验模块/动作权限"]
PERM --> |无权限| REDIR2["重定向到后台首页"]
PERM --> CSRF["CsrfMiddleware<br/>校验CSRF令牌"]
CSRF --> |失败| MSG["message()->respond()<br/>提示页"]
CSRF --> WS["AdminWorkspaceMiddleware<br/>注入全局变量"]
WS --> End(["放行到控制器"])

示例:后台首页 IndexController

  • 继承 BaseController,重写 layoutVars() 注入 cur='index'。
  • index() 方法调用 IndexService 维护缓存、同步 root_url、刷新更新角标,并渲染 index.htm。
  • clearCache()/closeQuickStart()/deleteInstall() 演示了 service 调用、审计日志、消息响应与重定向。

依赖关系分析

  • 入口依赖 Init、Route、异常处理函数与 Response。
  • Init 依赖容器、ProviderRegistry、DouView、语言服务、工作区构建器、主题设置读取器等。
  • AdminResolver 依赖 BackendDeclaredMatcher、MethodResolver、MiddlewareRegistry、Request、Container。
  • 中间件之间通过顺序组合形成管道,彼此职责单一且可插拔。
  • 控制器依赖服务层与门面,视图通过 TemplateRendererInterface 解耦。
  • 导航系统依赖 AdminMenuRegistry 提供菜单定义,AdminNavResolver 计算激活状态。
  • 新增 模块化导航配置依赖文件系统扫描机制,自动发现并加载各模块的导航配置文件。
graph LR
Entry["admin/index.php"] --> Init["Init::boot()"]
Init --> Container["Container/ProviderRegistry"]
Init --> View["DouView/TemplateRendererInterface"]
Entry --> Router["Router::dispatch()"]
Router --> Resolver["AdminResolver::resolve()"]
Resolver --> MWReg["MiddlewareRegistry"]
MWReg --> MW1["AuthMiddleware"]
MWReg --> MW2["PermissionMiddleware"]
MWReg --> MW3["CsrfMiddleware"]
MWReg --> MW4["AdminWorkspaceMiddleware"]
Resolver --> Dispatcher["Dispatcher"]
Dispatcher --> Controller["BaseController子类"]
Controller --> Service["Service层"]
Controller --> MenuReg["AdminMenuRegistry"]
Controller --> NavRes["AdminNavResolver"]
Controller --> View
ModuleNav["模块化导航配置<br/>admin/nav/*.php"] --> MenuReg

性能考虑

  • 视图编译缓存:Init 已配置 DouView 的 compile_dir 为 storage/cache/template/admin,确保模板编译产物复用。
  • 中间件短路:认证失败、权限不足、CSRF 失败尽早返回,减少后续开销。
  • 延迟求值:BaseController::layoutVars() 仅在真正渲染模板时执行,避免不必要的 Session 读取与计算。
  • 配置与语言包:Init 在 loadModules 阶段集中加载并缓存 module/system/features/lang,减少重复 IO。
  • 静态资源与 JS 路由:Init 注入 js_routes_script_url 与 js_lang_script_url,利用版本化 manifest 提升缓存命中率。
  • 数据库与缓存:服务层应合理使用查询缓存与批量操作,避免 N+1 查询。
  • 日志与调试:DOU_DEBUG 开启时注意生产环境关闭详细错误输出,避免泄露敏感信息。
  • 菜单注册表缓存:AdminMenuRegistry::subMenus() 使用静态缓存避免重复扫描文件系统。
  • 新增 模块化导航配置的文件系统扫描已在运行时缓存,避免每次请求都重新扫描 admin/nav/ 目录。

故障排查指南

  • 未捕获异常:admin/index.php 的 admin_render_uncaught 会记录错误日志,并根据是否 JSON 请求返回 JSON 或后台提示页;若 SiteDebugExceptionRenderer 启用,可渲染详细堆栈。
  • CSRF 失败:CsrfMiddleware 抛出 DomainException,入口捕获后通过 message()->respond() 输出统一提示页,包含倒计时与返回按钮。
  • 认证失败:AuthMiddleware 抛出 HttpResponseException 并重定向到登录页。
  • 权限不足:PermissionMiddleware 抛出 HttpResponseException 并重定向到后台首页。
  • 404/405:Router 对未命中与方法不允许的情况统一重定向到首页并携带 page_wrong 提示。

更新 新增了导航状态相关的故障排查要点,包括 $nav 变量结构不正确时的检查方法和菜单匹配规则验证。

结论

DouPHP 后台采用清晰的分层与声明式路由,结合中间件管道实现安全、认证、权限与横切关注点的解耦。Init 负责系统初始化与视图变量注入,BaseController 提供统一的视图渲染与响应处理,AdminResolver 与 Router 协同完成路由匹配与调度。最新的导航系统重构通过 AdminMenuRegistry 和 AdminNavResolver 提供了更强大、灵活的菜单管理能力。整体架构具备良好的可扩展性与可维护性,便于添加新功能与优化性能。

更新 最新的改进包括增强的未命中路由安全处理、新的 $nav 变量结构、声明式菜单注册表以及数据驱动的导航状态计算,进一步提升了系统的健壮性和灵活性。特别是新增的六个模块化导航配置文件,为 AI、Book、Chat、Distribution、User、Weixin 等核心功能模块提供了独立的菜单管理能力。

附录:扩展指南

新增后台控制器

  • 在 admin/controller/&lt;module>/ 下新建控制器类,继承 BaseController。
  • 在 admin/route/&lt;module>.php 中声明路由条目,映射到控制器的方法。
  • 在控制器方法中调用服务层,返回 $this->view('xxx.htm', $data) 或重定向/JSON。

参考路径

  • admin/controller/BaseController.php:60-68
  • admin/route/index.php:30-36
  • admin/controller/index/IndexController.php:73-108

新增服务层

  • 在 admin/service/&lt;module>/ 下新建服务类,封装业务逻辑。
  • 在控制器中通过构造函数注入或门面调用服务。
  • 服务层可依赖容器、ORM、缓存、外部 API 等。

参考路径

  • admin/controller/index/IndexController.php:45-58
  • admin/init/Init.php:219-356

新增视图模板

  • 在 admin/view/ 下新建 xxx.htm 模板文件。
  • 控制器通过 $this->view('xxx.htm', $data) 渲染,模板可使用 {$cur}、{$setting}、{$workspace}、{$nav} 等全局变量。
  • 如需自定义布局变量,可在控制器中重写 layoutVars() 或直接在 action data 中传递。

更新 模板现在使用新的 $nav 变量结构,包含 side(侧栏状态)、sub_menu(子菜单)、route_name(路由名)等键。

参考路径

  • admin/controller/BaseController.php:205-245
  • admin/init/Init.php:186-212
  • admin/controller/index/IndexController.php:98-108
  • admin/view/inc/sidebar.tpl:11-18

中间件扩展

  • 在 admin/middleware/ 下新建中间件类,实现 MiddlewareInterface。
  • 在 AdminResolver::$aliasMap 中注册别名,并在默认栈或路由级按需启用。
  • 中间件内可执行安全头、代理信任、认证、权限、CSRF、工作区变量注入等逻辑。

参考路径

  • admin/foundation/routing/AdminResolver.php:44-63
  • admin/middleware/AdminWorkspaceMiddleware.php:58-83

模块化导航配置扩展

创建新的模块导航配置

要为新的功能模块添加导航配置,只需在 admin/nav/ 目录下创建一个 PHP 文件,文件名即为模块标识符。

<?php
// admin/nav/my_module.php

if (!defined('IN_DOUCO')) {
    die('Hacking attempt');
}

return array(
    'title' => 'my_module',
    'icon' => 'bi-folder',
    'items' => array(
        array(
            'key' => 'main', 
            'name' => 'my_module_main', 
            'link' => 'admin.my_module',
            'match' => array('admin.my_module.*'),
        ),
        array(
            'key' => 'settings', 
            'name' => 'my_module_settings', 
            'link' => 'admin.my_module.settings',
            'match' => array('admin.my_module.settings.*'),
        ),
    ),
);

导航配置字段说明

  • title: 模块标题标识符,用于语言包翻译
  • icon: Bootstrap Icons 图标类名
  • items: 菜单项数组,每个项包含:
    • key: 菜单项唯一标识符
    • name: 显示名称标识符,用于语言包翻译
    • link: 路由名称
    • match: 路由匹配模式数组
    • exclude: 排除的路由模式数组
    • renders: 指定渲染哪个子菜单族
    • when: 条件判断数组

路由匹配规则

  • 段边界通配:admin.user.* 匹配 admin.user 及其任意层下级
  • 精确匹配:admin.user.log 精确匹配路由名
  • 排除规则:exclude 数组用于排除特定路由
  • 条件判断:when 数组支持多种条件判断

新增 这是新增的模块化导航配置扩展指南,帮助开发者为新功能模块创建独立的导航配置。

参考路径

  • admin/nav/ai.php:27-48
  • admin/nav/book.php:27-51
  • admin/service/menu/AdminMenuRegistry.php:147-154

导航状态扩展

  • 在控制器中使用 AdminNavResolver::resolve() 方法计算导航状态。
  • 支持页面级覆盖(overrides)处理复杂场景。
  • 使用 match/exclude 规则精确控制菜单激活状态。

新增 这是新增的导航状态扩展指南,帮助开发者正确处理复杂的导航场景。

参考路径

  • admin/controller/data/DataController.php:67-102
  • admin/service/menu/AdminNavResolver.php:64-136

配置与环境

  • 数据库与系统常量在 config/config.php 中定义,包括 DOU_CHARSET、SYSTEM_SIGN、ADMIN_DIR、API_DIR、MINIPROGRAM_DIR、DOU_APP_KEY、DOU_DEBUG。
  • 运行时可通过 Config 门面读写配置项,如 site、module、features、param 等。

参考路径

  • config/config.php:15-53
  • admin/init/Init.php:219-241

导航系统重构说明

重要更新 后台导航系统已完成重构,主要变更如下:

移除旧的 NavState 系统

  • 不再使用基于 NavState 的导航状态管理
  • 移除了控制器中的手动导航变量声明(cur、submenu、sub_cur)
  • BaseController 的 layoutVars() 方法不再包含导航相关变量

引入声明式菜单注册表

  • AdminMenuRegistry 提供集中式的菜单定义管理
  • 支持核心族和模块族的动态装配
  • 通过配置文件声明菜单结构和行为

基于路由的自动导航高亮

  • AdminNavResolver 基于当前路由名计算激活状态
  • 模板层统一消费 $nav 变量结构
  • sidebar.tpl 模板已更新为使用新的变量结构

模块化导航配置

  • 六个核心模块(AI、Book、Chat、Distribution、User、Weixin)拥有独立的导航配置文件
  • 每个模块的菜单定义集中在各自的 admin/nav/*.php 文件中
  • 通过 AdminMenuRegistry::subMenus() 自动扫描并装配所有模块导航配置

向后兼容性保证

  • BaseController::navFallbackVars() 提供向后兼容的导航变量
  • 旧模板代码仍可正常工作,无需立即修改
  • 渐进式迁移到新架构

参考路径

  • admin/controller/BaseController.php:74-90
  • admin/foundation/routing/AdminResolver.php:98-99
  • admin/view/inc/sidebar.tpl:11-18

导航系统架构详解

AdminMenuRegistry 的核心作用

AdminMenuRegistry 作为菜单注册表的核心组件,提供了声明式的菜单定义和管理:

// 模块化导航配置示例(AI 模块)
return array(
    'title' => 'ai',
    'icon' => 'bi-robot',
    'items' => array(
        array(
            'key' => 'ai', 'name' => 'ai', 'link' => 'admin.ai',
            'match' => array('admin.ai.*', 'admin.ai_generate.*'),
        ),
        // 更多菜单项...
    ),
);

模块化导航配置扫描机制

系统通过 glob 模式扫描 admin/nav/*.php 文件,自动发现并加载所有模块的导航配置:

$navDir = rtrim(str_replace('\\', '/', ROOT_PATH), '/') . '/admin/nav/';
foreach ((array) glob($navDir . '*.php') as $file) {
    $declared = include $file;
    if (is_array($declared) && isset($declared['title'], $declared['items'])) {
        $families[basename($file, '.php')] = $declared;
    }
}

菜单匹配规则

  • 段边界通配:admin.user.* 匹配 admin.user 及其任意层下级
  • 精确匹配:admin.user.log 精确匹配路由名
  • 排除规则:exclude 数组用于排除特定路由
  • 条件判断:when 数组支持多种条件判断

DataController 的特殊处理

DataController 实现了数据驱动的导航状态计算,通过页面级覆盖机制处理复杂场景:

private function navVars(array $bundle)
{
    $overrides = array();
    if ($dataGroup === 'miniprogram') {
        $overrides['sub_menu'] = 'miniprogram';
        $overrides['sub_item'] = 'data';
    } elseif ($dataGroup === 'banner') {
        $overrides['sub_item'] = 'data_banner';
    }
    // 其他处理逻辑...

    return array(
        'cur' => $cur,
        'nav' => AdminNavResolver::resolve($routeName, $overrides),
    );
}

模板层的适配

模板层已完全适配新的 $nav 变量结构,所有导航判断都使用新的数据结构:

<!-- 侧边栏模板中的新用法 -->
<li{if $nav.side.setting.is_active} class="cur"{/if} data-id="setting">
    <a href="{url link='admin.setting'}"><i class="{$workspace.menu_icon_map.setting}"></i><em>{$lang.setting}</em></a>
</li>

章节来源

  • admin/service/menu/AdminMenuRegistry.php:77-159
  • admin/service/menu/AdminNavResolver.php:64-136
  • admin/controller/data/DataController.php:67-102
  • admin/view/inc/sidebar.tpl:11-18
  • admin/nav/ai.php:27-48
  • admin/nav/book.php:27-51
  • admin/nav/chat.php:27-44
  • admin/nav/distribution.php:28-37
  • admin/nav/user.php:27-51
  • admin/nav/weixin.php:27-38
添加日期:2026-10-05