mirror of
https://gitee.com/ulthon/ulthon_admin.git
synced 2026-08-30 12:45:32 +08:00
- 新增 ulthon-file-override-mechanism.md:阐述 app/ 覆盖 extend/base/ 的三类机制(视图模板、include 标签、app_file_path)与不支持覆盖的反例清单 - ulthon-base-app-architecture:升格原孤立描述为独立小节"5. 文件级覆盖机制" - ulthon-timer:在 app_file_path 覆盖说明处增加规则引用 - AGENTS.md:登记新规则到框架内置规则索引 - ulthon-rules-manager:修订索引职责(AGENTS.md 仅 ulthon-、PROJECT.md 仅 project-,互斥不重复维护);索引格式从 4 列改为 3 列与项目实际一致;维护规则补充对称约束;泛化"迁移现有内容"章节
133 lines
6.4 KiB
Markdown
133 lines
6.4 KiB
Markdown
---
|
||
name: "ulthon-base-app-architecture"
|
||
description: "详细说明了 Base/App 双层架构的设计理念、三层结构、身份职责、目录映射、扩展模式及调用红线,帮助开发者理解框架结构并避免误操作。"
|
||
---
|
||
|
||
# Base/App 双层架构
|
||
|
||
本架构旨在解决**框架内核升级**与**业务代码定制**之间的矛盾。请根据您的身份阅读对应部分。
|
||
|
||
## 角色定位
|
||
|
||
| 你的身份 | 你的主要工作 | 请关注章节 |
|
||
| :--- | :--- | :--- |
|
||
| **框架使用者** | 开发具体业务功能、使用框架内置能力 | 一、我是框架使用者(做业务) |
|
||
| **框架作者** | 维护框架内核、修复 Bug、新增通用组件 | 二、我是框架作者(修内核) |
|
||
|
||
---
|
||
|
||
## 一、我是框架使用者(做业务)
|
||
|
||
### 1. 你的地盘与禁区
|
||
|
||
- **自由开发区**:除了 `extend/base/` 之外的所有目录。虽然业务代码通常推荐放在 `app/` 下,但你完全可以在项目中自由发挥。
|
||
- **绝对禁区**:`extend/base/` 目录。**严禁修改**这里的文件,因为 `php think admin:update` 会覆盖它。
|
||
|
||
### 2. 开发场景指南
|
||
|
||
#### 场景 A:新增全新的业务功能
|
||
|
||
直接在 `app/` 下创建控制器、模型或服务即可。不需要关心 Base 层,也不需要继承任何 Base 类(除非你需要利用框架基类的功能)。
|
||
|
||
- 公共代码放在 `app/common/`(工具类、基础类等)
|
||
- 命令类放在 `app/common/command/`(不放在 `app/admin/command/`)
|
||
- 新写业务能力:不需要、也不应该在 `extend/base/` 新建任何 `*Base.php`,这不是业务开发的默认模式
|
||
|
||
#### 场景 B:修改/扩展框架内置功能
|
||
|
||
如果你对框架默认的某个功能(如登录逻辑、CURD流程)不满意,请按以下步骤操作:
|
||
|
||
1. **定位**:找到该功能对应的 `app/` 入口类(例如 `app/admin/model/SystemAdmin.php`)。
|
||
2. **重写**:在该类中重写你需要修改的方法。
|
||
- 保持方法签名(参数、返回值)一致。
|
||
- 可以使用 `parent::method()` 复用父类逻辑,或复制父类代码后自行实现。
|
||
3. **生效**:系统会自动调用你的类,而不是底层的 Base 类。
|
||
|
||
#### 常见误区
|
||
|
||
- 误区:新增业务功能时,也要先在 `extend/base/` 建一个 `*Base` 再在 `app/` 继承
|
||
结论:不需要;这是框架内核维护模式,不是业务开发默认模式
|
||
- 误区:看到框架存在 Base/App 双层机制,就认为所有类都必须走"入口类"
|
||
结论:入口类主要用于"覆盖框架默认实现",纯业务类可以直接使用,不需要额外包装
|
||
|
||
### 3. 更新机制与保障
|
||
|
||
执行 `php think admin:update` 时,系统会检查框架所有文件的更新:
|
||
|
||
- **Base 层(extend/base/)**:默认为**覆盖更新**(Always Yes),因为这里是内核。
|
||
- **App 层(app/)及其他**:默认为**保护模式**(Default No)。命令会提示即将变动的文件列表。
|
||
- **推荐操作**:一般选择**跳过**,随后根据实际业务代码与上游更新进行对比,手动合并差异。
|
||
- **替代操作**:也可选择**覆盖**,更新后通过 Git 查看差异,并恢复不应变动的业务代码。
|
||
|
||
---
|
||
|
||
## 二、我是框架作者(修内核)
|
||
|
||
### 1. 你的地盘与职责
|
||
|
||
- **你的地盘**:`extend/base/` 目录。通用逻辑、基类代码写在这里。
|
||
- **你的义务**:每在 Base 层新增一个类(如 `UserBase`),**必须**在 `app/` 层提供对应的入口类(如 `User`),并让入口类继承 Base 类。
|
||
|
||
### 2. 开发关键原则(依赖倒置)
|
||
|
||
为了保证使用者的重写能生效,你必须遵守以下**铁律**:
|
||
|
||
> **严禁直接调用 Base 类**
|
||
> 无论在何处,禁止写 `new UserBase()` 或 `UserBase::find()`。
|
||
|
||
> **必须调用 App 入口类**
|
||
> 必须写 `new \app\...\User()`。
|
||
|
||
**为什么?**
|
||
如果代码直接调用了 `UserBase`,那么使用者在 `app/` 下重写的 `User` 类就变成了"摆设",无法拦截逻辑。只有调用 `app/` 下的子类,多态机制才能生效,使用者才有机会改变行为。
|
||
|
||
### 3. 文件组织规范
|
||
|
||
- **类文件**:以 `*Base.php` 结尾,放在 `extend/base/`。路径和名称与 `app/` 层一一对应。
|
||
- **辅助函数**:放在 `extend/base/helper.php`,通过 `app/common.php` 引入。
|
||
- **初始化数据**:放在 `extend/base/adminInitData/`(带 @internal-framework 注解标记)。
|
||
- **版本更新代码**:放在 `extend/base/adminUpdateCodeData/`(带 @internal-framework 注解标记)。
|
||
|
||
### 4. 核心层维护原则
|
||
|
||
- 稳定性优先:保证向下兼容
|
||
- 通用性优先:不引入具体业务逻辑
|
||
|
||
### 5. 文件级覆盖机制
|
||
|
||
除"类继承覆盖"外,框架还支持**文件级覆盖**:在 `app/` 下放置与 `extend/base/` 同路径同名的视图、模板、配置数组或 PHP 钩子文件,运行时会优先加载 app 版本。该能力覆盖三类文件:
|
||
|
||
- 视图模板(控制器 `fetch()` 渲染时三级回退:`app/<module>/view/` → `extend/base/<module>/view/` → `<root>/view/`)
|
||
- 模板内 `{include}` 标签(与视图同源的三级查找)
|
||
- `app_file_path()` 辅助函数显式加载的文件(两级回退:`app/<相对路径>` → `extend/base/<相对路径>`)
|
||
|
||
注意:文件级覆盖只对**特定类型**的文件生效。命令、语言包、路由、`config/*`、`public/static/*`、`AdminInitServiceBase::requireData()` 等均**不支持**——业务侧在 `app/` 下放同名文件不会生效。
|
||
|
||
完整的机制说明、7 处已知调用点清单与反例,见规则:[ulthon-file-override-mechanism](../../rules/ulthon-file-override-mechanism.md)。
|
||
|
||
---
|
||
|
||
## 三、架构参考资料
|
||
|
||
### 1. 三层结构图解
|
||
|
||
```
|
||
ThinkPHP 框架层(底层基础设施)
|
||
|
|
||
| 继承/扩展
|
||
ulthon_admin 内核层(extend/base/,框架作者维护)
|
||
|
|
||
| 继承/覆盖(依赖倒置:内核只调用 App 层入口)
|
||
App 应用层(app/,框架使用者维护)
|
||
```
|
||
|
||
### 2. 常见目录映射
|
||
|
||
| Base 层(内核实现) | App 层(调用入口) |
|
||
| :--- | :--- |
|
||
| `extend/base/admin/controller/system/AdminBase.php` | `app/admin/controller/system/Admin.php` |
|
||
| `extend/base/admin/model/SystemAdminBase.php` | `app/admin/model/SystemAdmin.php` |
|
||
| `extend/base/common/service/SmsBase.php` | `app/common/service/Sms.php` |
|
||
| `extend/base/common/command/CurdBase.php` | `app/common/command/Curd.php` |
|
||
| `extend/base/common/command/admin/role/AdminRoleCreateBase.php` | `app/common/command/admin/role/AdminRoleCreate.php` |
|