diff --git a/.agents/skills/ulthon-base-app-architecture/SKILL.md b/.agents/skills/ulthon-base-app-architecture/SKILL.md index af9652e..572d9e5 100644 --- a/.agents/skills/ulthon-base-app-architecture/SKILL.md +++ b/.agents/skills/ulthon-base-app-architecture/SKILL.md @@ -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` | diff --git a/.agents/skills/ulthon-core-extend-pattern/SKILL.md b/.agents/skills/ulthon-core-extend-pattern/SKILL.md deleted file mode 100644 index dfcc48b..0000000 --- a/.agents/skills/ulthon-core-extend-pattern/SKILL.md +++ /dev/null @@ -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` diff --git a/AGENTS.md b/AGENTS.md index 95fb2a9..71cb71a 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -17,66 +17,25 @@ - 表结构设计规范(必读): - 项目文档主页: -### 代码分层(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)