ThinkAdmin/docs/architecture/route-dispatch-standard.md
Anyon 6f4056f64d docs(architecture): 完善 v8 架构与迁移说明
补充 v8 重构后的架构文档、组件说明和迁移记录,方便后续维护者理解插件边界。

主要内容:

- 更新根 README,说明 v8 插件分层、系统模块、交付命令和验证流程。

- 新增组件明细、插件边界、路由分发、软删除和稳定性文档。

- 记录 Storage 合并到 System、旧 View 移除和 Helper 并入 System 的决策。

- 补充文档注释报告和后续重构计划,便于持续演进。
2026-05-08 15:31:22 +08:00

119 lines
3.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Route Dispatch Standard
## 目标
当前项目的最佳实践不是让根路由“先命中、后猜应用”,而是让根路由先声明目标应用或插件,再进入真实调度。
这样可以在分发前就绑定正确的:
- 应用目录
- 命名空间
- `view_path`
- 应用级配置
- 中间件
- 语言包
- 插件入口类型(`web` / `api`
否则全局路由虽然能命中,但很容易出现这些问题:
- 模板从错误目录加载
- 控制器命名空间错误
- 插件 API 被当成普通页面入口
- 本地应用配置和中间件没有生效
## 当前标准
### 1. 本地与插件模型
- `app/*`:本地多应用
- `plugin/*`:插件应用
- 默认本地应用:`index`
### 2. 分发优先级
`MultAccess` 当前的标准优先级是:
1. 显式插件前缀
2. 显式本地应用前缀
3. 根路由声明的目标应用/插件
4. 动态插件切换(兼容入口,默认关闭)
5. 默认本地应用
### 3. 标准入口
- 本地应用显式入口:`/{app}/{controller}/{action}`
- 默认本地应用:生成 URL 时可省略 `index`
- 插件页面入口:`/{plugin}/{controller}/{action}`
- 插件 API 入口:`/api/{plugin}/{controller}/{action}`
## 路由注册标准
### 1. 单条路由
```php
use think\admin\runtime\RequestContext;
use think\facade\Route;
Route::bindApp('portal', 'home/index', 'index');
Route::bindPlugin('open-upload', 'api.upload/file', 'system', RequestContext::ENTRY_API);
```
约束:
- `portal``open-upload` 是根路由规则
- `home/index``api.upload/file` 是目标应用内部相对路径
- 不再推荐把目标地址写成带应用前缀的旧三段式
### 2. 分组路由
```php
use think\admin\runtime\RequestContext;
use think\facade\Route;
Route::appGroup('member', function () {
Route::get('member-center', 'center/index');
});
Route::pluginGroup('system', function () {
Route::get('quick-upload', 'api.upload/file');
}, RequestContext::ENTRY_API);
```
这适合一批根路由都指向同一个本地应用或插件的场景。
### 3. 兼容旧路由
以下旧写法仍会尝试做目标推断:
```php
Route::rule('legacy-demo', 'index/demo/index');
Route::rule('legacy-login', 'system/login/index');
```
兼容规则只用于过渡:
- 如果第一段能识别为插件编码,优先按插件处理
- 否则如果第一段能识别为本地应用编码,按本地应用处理
新代码不要继续依赖这种隐式推断。
## 为什么这样最好
这套机制的关键价值是“先选上下文,再执行路由”。
只要目标应用/插件已经在分发前绑定完成,后面的控制器解析、模板加载、配置加载和中间件链都会落在正确目录,不需要再用各种运行时补丁去修视图路径或命名空间。
这比单纯在 `MultAccess` 里追加更多 if/else 更稳,因为:
- 路由语义在注册阶段就是显式的
- 全局路由不会再偷偷依赖当前默认应用
- 本地多应用和插件机制可以同时存在
- 迁移旧路由时有明确新标准和兼容兜底
## 推荐约束
- 根目录 `route/*.php` 只写跨应用或跨插件的全局路由
- 应用内部路由放各自 `app/{name}/route``plugin/*/src/route`
- 根路由一律使用 `bindApp` / `bindPlugin` / `appGroup` / `pluginGroup`
- 如果必须保留旧三段式,后续要逐步迁成显式目标声明