docs(agents): 重构技能文档,合并扩展模式到架构指南

- 删除独立的 ulthon-core-extend-pattern 技能文档
- 将扩展模式内容整合到 ulthon-base-app-architecture 架构指南
- 简化 AGENTS.md 中的架构说明,移除冗余内容
- 在架构指南中按角色(框架使用者/作者)分章节组织内容
This commit is contained in:
augushong
2026-04-29 21:37:35 +08:00
parent 59c5222497
commit 77da693d80
3 changed files with 63 additions and 124 deletions

View File

@@ -5,69 +5,94 @@ description: "详细说明了 Base/App 双层架构的设计理念、三层结
# Base/App 双层架构
本架构旨在解决**框架内核升级**与**业务代码定制**之间的矛盾。为了清晰起见,请根据您的身份阅读对应部分。
本架构旨在解决**框架内核升级**与**业务代码定制**之间的矛盾。请根据您的身份阅读对应部分。
## 🎭 角色定位
## 角色定位
| 你的身份 | 你的主要工作 | 请关注章节 |
| :--- | :--- | :--- |
| **框架使用者** | 开发具体业务功能、使用框架内置能力 | 👉 [一、我是框架使用者(做业务)](#一我是框架使用者做业务) |
| **框架作者** | 维护框架内核、修复 Bug、新增通用组件 | 👉 [二、我是框架作者(修内核)](#二我是框架作者修内核) |
| **框架使用者** | 开发具体业务功能、使用框架内置能力 | 一、我是框架使用者(做业务) |
| **框架作者** | 维护框架内核、修复 Bug、新增通用组件 | 二、我是框架作者(修内核) |
---
## 一、我是框架使用者(做业务)
### 1. 你的地盘与禁区
-**自由开发区**:除了 `extend/base/` 之外的所有目录。虽然业务代码通常推荐放在 `app/` 下,但你完全可以在项目中自由发挥。
- **绝对禁区**`extend/base/` 目录。**严禁修改**这里的文件,因为 `php think admin:update` 会无情覆盖它
- **自由开发区**:除了 `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()` 复用父类逻辑。
- 可以使用 `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 查看差异,并恢复不应变动的业务代码
- **Base 层extend/base/**:默认为**覆盖更新**Always Yes因为这里是内核
- **App 层app/)及其他**:默认为**保护模式**Default No。命令会提示即将变动的文件列表
- **推荐操作**一般选择**跳过**,随后根据实际业务代码与上游更新进行对比,手动合并差异
- **替代操作**:也可选择**覆盖**,更新后通过 Git 查看差异,并恢复不应变动的业务代码。
---
## 二、我是框架作者(修内核)
### 1. 你的地盘与职责
-**你的地盘**`extend/base/` 目录。通用逻辑、基类代码写在这里。
- 📝 **你的义务**:每在 Base 层新增一个类(如 `UserBase`**必须**在 `app/` 层提供对应的入口类(如 `User`),并让入口类继承 Base 类
- **你的地盘**`extend/base/` 目录。通用逻辑、基类代码写在这里
- **你的义务**:每在 Base 层新增一个类(如 `UserBase`**必须**在 `app/` 层提供对应的入口类(如 `User`),并让入口类继承 Base 类。
### 2. 开发关键原则(依赖倒置)
为了保证使用者的重写能生效,你必须遵守以下**铁律**
> **严禁直接调用 Base 类**
> **严禁直接调用 Base 类**
> 无论在何处,禁止写 `new UserBase()` 或 `UserBase::find()`。
> **必须调用 App 入口类**
> **必须调用 App 入口类**
> 必须写 `new \app\...\User()`。
**为什么?**
如果代码直接调用了 `UserBase`,那么使用者在 `app/` 下重写的 `User` 类就变成了摆设,无法拦截逻辑。只有调用 `app/` 下的子类,多态机制才能生效,使用者才有机会改变世界
如果代码直接调用了 `UserBase`,那么使用者在 `app/` 下重写的 `User` 类就变成了"摆设",无法拦截逻辑。只有调用 `app/` 下的子类,多态机制才能生效,使用者才有机会改变行为
### 3. 文件组织规范
- **类文件**:以 `*Base.php` 结尾,放在 `extend/base/`
- **类文件**:以 `*Base.php` 结尾,放在 `extend/base/`。路径和名称与 `app/` 层一一对应。
- **辅助函数**:放在 `extend/base/helper.php`,通过 `app/common.php` 引入。
- **初始化数据**:放在 `extend/base/adminInitData/`
- **初始化数据**:放在 `extend/base/adminInitData/`(带 @internal-framework 注解标记)
- **版本更新代码**:放在 `extend/base/adminUpdateCodeData/`(带 @internal-framework 注解标记)。
- 静态文件/模板/配置支持分层加载:优先加载 `app/`,不存在时再回落到框架默认实现(例如 `app_file_path`)。
### 4. 核心层维护原则
- 稳定性优先:保证向下兼容
- 通用性优先:不引入具体业务逻辑
---
@@ -77,11 +102,11 @@ description: "详细说明了 Base/App 双层架构的设计理念、三层结
```
ThinkPHP 框架层(底层基础设施)
继承/扩展
|
| 继承/扩展
ulthon_admin 内核层extend/base/,框架作者维护)
继承/覆盖(依赖倒置:内核只调用 App 层入口)
|
| 继承/覆盖(依赖倒置:内核只调用 App 层入口)
App 应用层app/,框架使用者维护)
```
@@ -91,5 +116,6 @@ App 应用层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/command/CurdBase.php` | `app/common/command/Curd.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` |

View File

@@ -1,45 +0,0 @@
---
name: "ulthon-core-extend-pattern"
description: "业务开发默认只写 app需要改内置能力时通过 app 入口类覆盖 *Base 默认实现。"
---
# 扩展内置能力(继承与重写)
## 何时调用
- 需要新增业务能力(新控制器/模型/服务/命令等):直接在 `app/` 写代码。
- 需要扩展/调整系统已有能力(默认实现存在于 `extend/base/`):在 `app/` 下对应入口类重写以覆盖默认实现。
## 关键原则
- 新写业务代码:只写 `app/`,不需要、也不应该去 `extend/base/` 做任何“对齐”。
- 改内置能力:只改 `app/` 下对应入口类(必要时 `extends` 对应 `*Base`)。
- 严禁直接修改 `extend/base/` 下任何文件。
- 重写时保持方法签名一致;可用 `parent::method()` 复用父类逻辑,或复制父类代码后自行实现。
## 操作流程
### A. 新写业务能力(推荐默认路径)
1. 直接在 `app/` 下创建需要的控制器/模型/服务/命令等类文件(按项目命名规范与目录约定放置)。
2. 让业务入口只依赖 `app/` 下的类,不需要为“对应 Base 层文件”做额外映射。
### B. 覆盖框架默认行为(扩展/调整已有能力)
1. 定位对应的 `*Base` 默认实现文件路径(通常在 `extend/base/`)。
2.`app/` 下创建或修改同路径的入口类文件,并 `extends` 对应 `*Base`
3. 在入口类中重写需要调整的方法,确保方法签名一致。
## 常见误区(避免歧义)
- 误区:新增业务功能时,也要先在 `extend/base/` 建一个 `*Base` 再在 `app/` 继承
结论:不需要;这是框架内核维护模式,不是业务开发默认模式
- 误区:看到框架存在 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/admin/role/AdminRoleCreateBase.php``app/common/command/admin/role/AdminRoleCreate.php`

View File

@@ -17,66 +17,25 @@
- 表结构设计规范(必读):<https://doc.ulthon.com/read/augushong/ulthon_admin/619efc9d7af62/zh-cn/2.x.html>
- 项目文档主页:<https://doc.ulthon.com/read/augushong/ulthon_admin/home/zh-cn/2.x.html>
### 代码分层3 层
### 代码分层铁律(不可协商
- ThinkPHP 层:框架本身;通过 Provider 机制可以替换/扩展 ThinkPHP 的行为(配置通常在 `app/provider.php`,例如绑定核心类实现、注册中间件等)
- ulthon\_admin 层:框架内核与默认实现,主要位于 `extend/base/`\*Base`extend/think/`(对 ThinkPHP 行为的适配/替换)
- App 层:业务代码与系统唯一调用入口,位于 `app/`(包含:用于覆盖框架默认实现的入口类;以及:业务自行新增的普通类)
框架采用 Base/App 双层架构。根据当前任务的开发者身份,遵守对应约束:
### 身份与职责2 种)
**所有身份通用**
- `extend/base/` 是框架内核(`*Base``app/` 是业务代码入口,目录路径一一对应
一句话讲清楚
**框架使用者(默认身份,除非明确说"修内核/改框架"**
- 严禁修改 `extend/base/` 下任何文件
- 所有开发只在 `app/` 目录进行;新写业务能力直接在 `app/` 下实现即可
- 扩展内置能力时,只改 `app/` 下对应入口类(必要时 `extends` 对应 `*Base`),保持方法签名一致
- 框架作者:代码写在 `extend/base/`,但系统调用入口必须在 `app/`(保证使用者可在 `app/` 继承重写)
- 框架使用者:内置能力要改就改 `app/` 的对应入口类;自己新增的业务代码直接写 `app/`,不需要关心 Base/App 双层机制
#### ulthon\_admin 框架作者(维护框架/内核)
- 新增通用能力:实现写到 `extend/base/`(必要时通过 Provider 机制扩展 ThinkPHP 行为)
- 同时在 `app/` 下建立对应入口类(可为空类继承 Base作为系统唯一调用入口
- Base 内部引用模型/服务/控制器时,一律引用 `app/` 下的类(保证业务层扩展始终生效)
- 静态文件/模板/配置支持分层加载:优先加载 `app/`,不存在时再回落到框架默认实现(例如 `app_file_path`
- Base层代码一般以 `*Base.php` 命名,放在 `extend/base/`
- Base层代码和app层代码的文件路径和名称一般是对应的。
**框架作者(仅当任务涉及 `extend/base/` 时)**
- 每新增一个 Base 类,必须同时在 `app/` 提供入口类(可为空类继承 Base
- Base 内部禁止直接引用/调用 `extend/base/` 下的类(含内部互调),必须引用 `app/` 下的入口类
- 例外:`app/common.php` 引用 `extend/base/helper.php` 是全局辅助函数的唯一特许
- 核心层维护原则:稳定性优先(保证向下兼容);通用性优先(不引入具体业务逻辑)
**Base 层文件分类**
- `*Base.php`:控制器/模型/服务/命令基类(被 App 层继承)
- `helper.php`:全局辅助函数(通过 app/common.php 引用)
- `adminInitData/`:框架核心初始化数据(带 @internal-framework 注解标记)
- `adminUpdateCodeData/`:框架版本更新代码(带 @internal-framework 注解标记)
#### 使用框架的开发者(做业务)
- 严禁修改 `extend/base/` 下任何文件
- 业务逻辑一般放在 `app/` 下(优先 `app/admin/`
- 修改/扩展框架内置能力:只改 `app/` 下对应入口类(必要时 `extends` 对应 `*Base`);仍严禁直接改动 `extend/base/`
- 新写业务能力:直接在 `app/` 下实现即可;不需要、也不应该在 `extend/base/` 新建任何 `*Base.php`
- 公共代码放在 `app/common/`(工具类、基础类等)
- 命令类特殊一些,放在 `app/common/command/`(不放在 `app/admin/command/`
- 重写规范:保持方法签名一致;可用 `parent::method()` 复用父类逻辑,或复制父类代码后自行实现
- 其他无任何特殊要求可以按照任意方式写代码以上只是对base层作说明。但框架仍然规定了大量的开发规范需要参考在线文档。
- 尽量按框架的规范、内置规则、内置技能进行开发,避免违反框架的设计初衷。
### Base/App 双层机制调用红线(内核开发约束)
- `extend/base/` 为框架内核实现(`*Base`),仅作为 `app/` 的继承基类使用,不作为系统调用入口
- 在实现通用能力/内核代码时,禁止直接引用或调用 `extend/base/` 下的类(包括 `extend/base/` 内部互相调用)
- 模型/服务/控制器/命令的引用与调用必须指向 `app/` 下的对应入口类(保证覆盖/重写始终生效)
- 例外:
1. 允许在 `app/` 下类定义中使用 `extends` 继承对应 `*Base`
2. `app/common.php` 中包含 `include App::getRootPath() . '/extend/base/helper.php';`,这是全局辅助函数文件的引用特例
- `extend/base/helper.php` 仅包含**全局辅助函数**(非类),属于框架内核能力的一部分
- 这些函数需要在整个应用范围内可用(如 `__url()`, `password()`, `sysconfig()`, `auth()`, `app_file_path()` 等)
- 该引用为框架设计要求的合理例外,不影响 Base/App 双层机制原则
### 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/admin/role/AdminRoleCreateBase.php``app/common/command/admin/role/AdminRoleCreate.php`
详细架构说明与操作流程:[ulthon-base-app-architecture](./.agents/skills/ulthon-base-app-architecture/SKILL.md)
### 其他规则
@@ -141,8 +100,7 @@
Skills 是“按场景调用的工作流说明”,统一以 `.agents/skills/*/SKILL.md` 为准;`.trae/skills/` 为 Trae 集成的镜像目录(内容保持同步)。
- 扩展内置能力(继承与重写):[ulthon-core-extend-pattern](./.agents/skills/ulthon-core-extend-pattern/SKILL.md)
- Base/App 架构指南:[ulthon-base-app-architecture](./.agents/skills/ulthon-base-app-architecture/SKILL.md)
- Base/App 架构与扩展指南(含身份分章节):[ulthon-base-app-architecture](./.agents/skills/ulthon-base-app-architecture/SKILL.md)
- CLI 命令参考文档:[ulthon-cli-reference](./.agents/skills/ulthon-cli-reference/SKILL.md)
- Scheme + CURD 工作流:[ulthon-scheme-curd-workflow](./.agents/skills/ulthon-scheme-curd-workflow/SKILL.md)
- Scheme 定义指南:[ulthon-scheme-definition](./.agents/skills/ulthon-scheme-definition/SKILL.md)