mirror of
https://gitee.com/ulthon/ulthon_admin.git
synced 2026-07-05 17:42:49 +08:00
feat: 发布智能体版
This commit is contained in:
53
.agents/skills/tp-controller-url-rules/SKILL.md
Normal file
53
.agents/skills/tp-controller-url-rules/SKILL.md
Normal file
@@ -0,0 +1,53 @@
|
||||
---
|
||||
name: "tp-controller-url-rules"
|
||||
description: "解释 ThinkPHP 8 多级控制器与大驼峰控制器的 URL 访问规则。当用户询问如何访问控制器、URL 报错或需要配置路由时调用。"
|
||||
---
|
||||
|
||||
# ThinkPHP 8 控制器 URL 访问规则
|
||||
|
||||
本 Skill 指导如何在 ThinkPHP 8 框架中正确访问多级控制器以及采用大驼峰命名的控制器和方法。
|
||||
|
||||
## 1. 大驼峰命名转换规则
|
||||
|
||||
ThinkPHP 8 默认开启了 URL 自动转换(`url_convert`)。大驼峰命名(CamelCase)的控制器和方法在 URL 中会被转换为小写+下划线(snake_case)。
|
||||
|
||||
- **控制器类名**:`UserGroup` → URL:`user_group`
|
||||
- **操作方法名**:`public function editInfo()` → URL:`edit_info`
|
||||
|
||||
**示例:**
|
||||
控制器 `app\admin\controller\UserGroup.php` 中的 `editInfo` 方法:
|
||||
访问路径:`/admin/user_group/edit_info`
|
||||
|
||||
## 2. 多级控制器访问规则
|
||||
|
||||
当控制器存放在子目录中时,URL 访问需要使用 `.`(点号)来连接目录名和控制器名。
|
||||
|
||||
- **目录结构**:`app/admin/controller/system/Config.php`
|
||||
- **访问路径**:`/admin/system.config/index`
|
||||
|
||||
**注意:**
|
||||
- 子目录名建议使用全小写。
|
||||
- 如果子目录名也是大驼峰,同样遵循转换规则(取决于具体配置,但通常建议目录名保持简单)。
|
||||
|
||||
## 3. 混合使用示例
|
||||
|
||||
结合多级目录和大驼峰命名的复杂情况:
|
||||
|
||||
| 控制器文件路径 | 类名 | 方法名 | 对应 URL 路径 |
|
||||
| :--- | :--- | :--- | :--- |
|
||||
| `controller/Index.php` | `Index` | `index` | `/admin/index/index` |
|
||||
| `controller/UserGroup.php` | `UserGroup` | `add` | `/admin/user_group/add` |
|
||||
| `controller/system/Admin.php` | `Admin` | `login` | `/admin/system.admin/login` |
|
||||
| `controller/mall/GoodsCate.php` | `GoodsCate` | `getList` | `/admin/mall.goods_cate/get_list` |
|
||||
|
||||
## 4. 常见问题排查
|
||||
|
||||
- **404 错误**:检查是否漏掉了多级控制器的 `.` 分隔符。
|
||||
- **大小写敏感**:如果 URL 无法识别下划线,检查 `config/route.php` 中的 `url_convert` 是否被设置为 `false`。
|
||||
- **多应用影响**:在多应用模式下,URL 的第一段通常是应用名(如 `admin`),后续才是控制器和方法。
|
||||
|
||||
## 5. 开发者建议
|
||||
|
||||
- **统一风格**:在代码中使用大驼峰命名类和方法,但在前端请求、模板链接(如 `{:url('...')}`)中建议明确指向转换后的路径或使用系统助手函数自动生成。
|
||||
- **路由定义**:对于复杂的 URL,建议在 `route/*.php` 中手动定义路由规则,以提供更友好的访问地址。
|
||||
|
||||
86
.agents/skills/ulthon-admin-menu-cli/SKILL.md
Normal file
86
.agents/skills/ulthon-admin-menu-cli/SKILL.md
Normal file
@@ -0,0 +1,86 @@
|
||||
---
|
||||
name: "ulthon-admin-menu-cli"
|
||||
description: "解释并指导后台菜单(system_menu)与 admin:menu:* 命令的使用方式。需要导出菜单、通过命令行创建/更新/删除菜单、或排查菜单字段映射(pid/href/auth_node)时调用。"
|
||||
---
|
||||
|
||||
# 菜单管理(admin:menu:* CLI)
|
||||
|
||||
## 何时调用
|
||||
|
||||
- 需要导出当前系统菜单数据,用于备份/迁移/对比。
|
||||
- 需要在不进入后台页面的情况下,通过命令行创建/更新/删除菜单。
|
||||
- 需要排查菜单字段映射:`pid`/`href`/`auth_node` 与命令参数 `parent-id`/`path`/`node` 的对应关系。
|
||||
- 需要脚本化输出(JSON)对接自动化运维/测试(仅导出命令支持)。
|
||||
|
||||
## 命令清单
|
||||
|
||||
### 1) 导出菜单
|
||||
|
||||
```bash
|
||||
php think admin:menu:export
|
||||
```
|
||||
|
||||
常用参数:
|
||||
- `--format=json`:JSON 输出(含 count/exported_at)
|
||||
- `--output=<文件路径>`:把导出的菜单数组写入文件(JSON)
|
||||
|
||||
示例:
|
||||
|
||||
```bash
|
||||
php think admin:menu:export --format=json
|
||||
php think admin:menu:export --output=runtime/agent/menu_export.json
|
||||
php think admin:menu:export --output=runtime/agent/menu_export.json --format=json
|
||||
```
|
||||
|
||||
### 2) 创建菜单(会写入数据库)
|
||||
|
||||
```bash
|
||||
php think admin:menu:create --title="测试菜单" --path="demo.index/index" --icon="fa fa-list" --parent-id=0 --sort=100
|
||||
```
|
||||
|
||||
### 3) 更新菜单(会写入数据库)
|
||||
|
||||
```bash
|
||||
php think admin:menu:update --id=123 --title="新标题" --path="demo.index/index" --icon="fa fa-list" --parent-id=0 --sort=100
|
||||
```
|
||||
|
||||
说明:
|
||||
- `--id` 必填;其余参数不传则不更新该字段。
|
||||
- `--path` 更新的是数据库字段 `href`。
|
||||
- `--parent-id` 更新的是数据库字段 `pid`。
|
||||
|
||||
### 4) 删除菜单(会写入数据库,软删除)
|
||||
|
||||
```bash
|
||||
php think admin:menu:delete --id=123
|
||||
```
|
||||
|
||||
说明:
|
||||
- 若存在子菜单会拒绝删除(需先删除子菜单)。
|
||||
|
||||
## 字段映射速查
|
||||
|
||||
- `--parent-id` → `system_menu.pid`
|
||||
- `--path` → `system_menu.href`
|
||||
- `--node` → `system_menu.auth_node`
|
||||
|
||||
## 典型工作流
|
||||
|
||||
### 工作流 A:备份菜单到文件
|
||||
|
||||
```bash
|
||||
php think admin:menu:export --output=runtime/agent/menu_export.json
|
||||
```
|
||||
|
||||
### 工作流 B:创建 → 更新 → 删除(用于验证命令链路)
|
||||
|
||||
```bash
|
||||
php think admin:menu:create --title="CLI测试菜单" --path="test.cli/index" --parent-id=0
|
||||
php think admin:menu:update --id=<上一步返回的id> --title="CLI测试菜单_改"
|
||||
php think admin:menu:delete --id=<上一步返回的id>
|
||||
```
|
||||
|
||||
## 注意事项
|
||||
|
||||
- `create/update/delete` 会实际修改数据库,建议在测试环境或确认无风险后执行。
|
||||
- 导出默认过滤 `delete_time=0`(只导出未删除菜单)。
|
||||
28
.agents/skills/ulthon-auth-session-token/SKILL.md
Normal file
28
.agents/skills/ulthon-auth-session-token/SKILL.md
Normal file
@@ -0,0 +1,28 @@
|
||||
---
|
||||
name: "ulthon-auth-session-token"
|
||||
description: "解释并指导 Session+Token 登录认证的使用方式。需要实现接口鉴权或联调移动端请求时调用。"
|
||||
---
|
||||
|
||||
# 登录认证(Session + Token)
|
||||
|
||||
## 何时调用
|
||||
|
||||
- 编写/联调需要登录态的接口。
|
||||
- 需要在非浏览器环境(移动端、小程序、跨域脚本)调用后台接口。
|
||||
|
||||
## 机制概览
|
||||
|
||||
- Session:主要用于浏览器环境,依赖 Cookie。
|
||||
- Token:用于接口与无 Cookie 场景,通过 Header 传递完成认证。
|
||||
|
||||
## 使用方式
|
||||
|
||||
1. 登录成功后,接口会返回 `token` 数据。
|
||||
2. 后续请求在 Header 携带:
|
||||
|
||||
```text
|
||||
Authorization: Bearer <token>
|
||||
```
|
||||
|
||||
3. 系统会自动识别并完成身份认证。
|
||||
|
||||
95
.agents/skills/ulthon-base-app-architecture/SKILL.md
Normal file
95
.agents/skills/ulthon-base-app-architecture/SKILL.md
Normal file
@@ -0,0 +1,95 @@
|
||||
---
|
||||
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 类(除非你需要利用框架基类的功能)。
|
||||
|
||||
#### 场景 B:修改/扩展框架内置功能
|
||||
如果你对框架默认的某个功能(如登录逻辑、CURD流程)不满意,请按以下步骤操作:
|
||||
|
||||
1. **定位**:找到该功能对应的 `app/` 入口类(例如 `app/admin/model/SystemAdmin.php`)。
|
||||
2. **重写**:在该类中重写你需要修改的方法。
|
||||
- 保持方法签名(参数、返回值)一致。
|
||||
- 可以使用 `parent::method()` 复用父类逻辑。
|
||||
3. **生效**:系统会自动调用你的类,而不是底层的 Base 类。
|
||||
|
||||
### 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/`。
|
||||
- **辅助函数**:放在 `extend/base/helper.php`,通过 `app/common.php` 引入。
|
||||
- **初始化数据**:放在 `extend/base/adminInitData/`。
|
||||
|
||||
---
|
||||
|
||||
## 三、架构参考资料
|
||||
|
||||
### 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/command/CurdBase.php` | `app/common/command/Curd.php` |
|
||||
| `extend/base/common/service/SmsBase.php` | `app/common/service/Sms.php` |
|
||||
78
.agents/skills/ulthon-cli-reference/SKILL.md
Normal file
78
.agents/skills/ulthon-cli-reference/SKILL.md
Normal file
@@ -0,0 +1,78 @@
|
||||
---
|
||||
name: "ulthon-cli-reference"
|
||||
description: "Ulthon Admin 框架常用 CLI 命令速查手册,包括菜单管理、Scheme 同步与 CURD 生成等命令说明。"
|
||||
---
|
||||
|
||||
# CLI 命令参考文档
|
||||
|
||||
本文档提供 Ulthon Admin 框架的常用 CLI 命令速查手册。
|
||||
|
||||
## 何时调用
|
||||
|
||||
- 当需要查找 Ulthon Admin 特定的 CLI 命令(如菜单管理、Scheme 同步、CURD 生成)及其参数时。
|
||||
- 当需要验证或调试 CLI 命令功能时。
|
||||
|
||||
## 关键原则
|
||||
|
||||
- 菜单管理命令用于操作后台菜单结构,支持 JSON/Tree 格式输出。
|
||||
- Scheme 与 CURD 命令用于保持数据库与代码的一致性,以及生成基础代码。
|
||||
- CURD 操作建议先使用 `-r` 生成到临时目录进行预览。
|
||||
- Scheme 同步操作涉及数据库变更,需谨慎使用。
|
||||
|
||||
## 菜单管理
|
||||
|
||||
| 命令 | 说明 | 常用参数 |
|
||||
|------|------|----------|
|
||||
| `admin:menu:list` | 列出菜单(树形) | `--format`, `--status`, `--pid` |
|
||||
| `admin:menu:create` | 创建菜单 | - |
|
||||
| `admin:menu:update` | 编辑菜单 | - |
|
||||
| `admin:menu:delete` | 删除菜单 | - |
|
||||
| `admin:menu:export` | 导出菜单数据 | `--format=json` |
|
||||
|
||||
## Scheme & CURD
|
||||
|
||||
| 命令 | 说明 | 常用参数 |
|
||||
|------|------|----------|
|
||||
| `scheme:sync` | 同步 Scheme 到数据库 | `--force` (跳过确认) |
|
||||
| `scheme:make` | 从数据库生成 Scheme | `-t {table}` |
|
||||
| `curd` | 生成 CURD 代码 | `-t {table}` `-r` (临时) `-f` (强制) `-d` (删除) |
|
||||
|
||||
### CURD 参数说明
|
||||
|
||||
| 参数 | 简写 | 说明 |
|
||||
|------|------|------|
|
||||
| `--table` | `-t` | 主表名(支持带前缀或不带前缀) |
|
||||
| `--force` | `-f` | 强制覆盖模式(**谨慎使用**) |
|
||||
| `--delete` | `-d` | 删除模式(**删除生成的文件,不是数据库操作**) |
|
||||
| `--runtime` | `-r` | 临时生成模式(**推荐用于预览**) |
|
||||
| `--examples` | | 显示使用示例 |
|
||||
|
||||
## 快速示例
|
||||
|
||||
### 菜单管理
|
||||
|
||||
```bash
|
||||
php think admin:menu:list # 查看菜单树
|
||||
php think admin:menu:create # 创建菜单
|
||||
php think admin:menu:export --format=json # 导出菜单
|
||||
```
|
||||
|
||||
### CURD 操作
|
||||
|
||||
```bash
|
||||
# 预览生成(推荐)
|
||||
php think curd -t daka_record -r
|
||||
|
||||
# 正式生成
|
||||
php think curd -t daka_record
|
||||
|
||||
# 强制覆盖(小心)
|
||||
php think curd -t daka_record -f
|
||||
```
|
||||
|
||||
## 注意事项
|
||||
|
||||
1. **表名参数**:CURD 和 Scheme 命令的表名支持带前缀或不带前缀(v2.x+ 自动检测)
|
||||
2. **安全确认**:`scheme:sync` 默认需要确认,使用 `-ff` 跳过
|
||||
3. **临时生成**:CURD 使用 `-r` 可生成到临时目录预览
|
||||
4. **删除模式**:CURD 的 `-d` 是删除生成的文件,不是数据库操作
|
||||
45
.agents/skills/ulthon-core-extend-pattern/SKILL.md
Normal file
45
.agents/skills/ulthon-core-extend-pattern/SKILL.md
Normal file
@@ -0,0 +1,45 @@
|
||||
---
|
||||
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`
|
||||
35
.agents/skills/ulthon-db-tools-debug/SKILL.md
Normal file
35
.agents/skills/ulthon-db-tools-debug/SKILL.md
Normal file
@@ -0,0 +1,35 @@
|
||||
---
|
||||
name: "ulthon-db-tools-debug"
|
||||
description: "封装 tools:db 命令的使用方法。需要快速查询/执行 SQL 或查看表信息进行调试时调用。"
|
||||
---
|
||||
|
||||
# 内置数据库调试命令(tools:db)
|
||||
|
||||
## 何时调用
|
||||
|
||||
- 需要快速查看数据、验证 SQL、检查表结构(字段/索引/行数)用于排错。
|
||||
- 需要在不写临时代码的情况下做一次性查询或数据检查。
|
||||
|
||||
## 必须注意
|
||||
|
||||
- 这些命令用于“调试数据”,不要用来“设计表结构”。
|
||||
- 如果为了排错临时改了表结构或数据,需要在任务结束前确保影响可控并记录变更点。
|
||||
|
||||
## 常用命令
|
||||
|
||||
```bash
|
||||
php think tools:db:query
|
||||
php think tools:db:execute
|
||||
php think tools:db:table
|
||||
php think tools:db:count
|
||||
php think tools:db:info
|
||||
php think tools:db:desc
|
||||
```
|
||||
|
||||
通过 `--help` 查看每个命令参数说明。
|
||||
|
||||
## 使用建议
|
||||
|
||||
- 优先用 `query/desc/info/table/count` 做只读检查。
|
||||
- 需要变更数据时再用 `execute`,并尽量将变更限制在最小范围。
|
||||
|
||||
48
.agents/skills/ulthon-page-api-dual-mode/SKILL.md
Normal file
48
.agents/skills/ulthon-page-api-dual-mode/SKILL.md
Normal file
@@ -0,0 +1,48 @@
|
||||
---
|
||||
name: "ulthon-page-api-dual-mode"
|
||||
description: "指导控制器实现“页面/接口同体”。需要同一路由同时返回 HTML 与 JSON 时调用。"
|
||||
---
|
||||
|
||||
# 页面 / 接口同体(Controller Dual Mode)
|
||||
|
||||
## 何时调用
|
||||
|
||||
- 希望同一个控制器方法既能渲染页面(HTML),也能作为接口返回 JSON。
|
||||
- 需要让现有页面接口在移动端/脚本调用时返回结构化数据。
|
||||
|
||||
## 触发与认证
|
||||
|
||||
- 触发:请求头 `Accept` 包含 `application/json`(框架使用 `request()->isJson()` 判断)。
|
||||
- 认证:Header 传 `Authorization: Bearer <tokenContent>`。
|
||||
|
||||
## 实现要点
|
||||
|
||||
- 控制器方法必须调用 `$this->fetch()`,不要使用 `View::fetch()`。
|
||||
- 无论使用 `$this->assign()` 还是 `View::assign()`,其数据都会被转换为 JSON 返回。
|
||||
- 若不希望某个 assign 字段出现在 JSON 中,可使用:
|
||||
|
||||
```php
|
||||
$this->assign('name', 'value', -1);
|
||||
```
|
||||
|
||||
## 特殊行为
|
||||
|
||||
- 这里存在两种“JSON 语义”,不要混淆:
|
||||
- **接口模式(API)**:只需要 `Accept: application/json`。典型用法是 `index` 的表格分页数据、以及所有 `POST` 提交的 success/error JSON 返回。
|
||||
- **页面数据模式(Page Data)**:用于“拿页面 assign 的数据”(例如表单的下拉选项、默认值等),需要在 `Accept: application/json` 的基础上追加 `get_page_data=1`。
|
||||
- `get_page_data=1` 会强制让 `request()->isAjax()` 返回 false,从而避免 `index` 这类方法走“Ajax 分页数据分支”,转而执行 `$this->fetch()`;随后 `$this->fetch()` 会把 `View::fetchData()`(即 assign 的变量)打包成 `json_message()` 返回。
|
||||
- 当 URL 带 `get_page_data=1` 但请求头不含 `Accept: application/json` 时,框架会直接返回 JSON 错误提示,避免“看起来参数写了但返回了 HTML”的误解。
|
||||
- 仅在控制器模式(Controller Mode)生效;路由模式(Route Mode)不生效。
|
||||
|
||||
## 常见例子
|
||||
|
||||
- 获取列表分页数据(API):只加 `Accept: application/json`,不要带 `get_page_data`
|
||||
- `GET /admin/system.admin/index`
|
||||
- 获取页面 assign 数据(Page Data):`Accept: application/json` + `get_page_data=1`
|
||||
- `GET /admin/system.menu/add?get_page_data=1`
|
||||
- `GET /admin/system.admin/add?get_page_data=1`
|
||||
|
||||
## 命令行联调建议
|
||||
|
||||
- `php think tools:http:call --app=admin --controller=system.admin --action=index`:默认按 API 语义调用(不再自动追加 `get_page_data=1`)
|
||||
- `php think tools:http:call --app=admin --controller=system.admin --action=add --page-data`:获取该页面的 assign 数据(等价于追加 `get_page_data=1`)
|
||||
106
.agents/skills/ulthon-permission-cli/SKILL.md
Normal file
106
.agents/skills/ulthon-permission-cli/SKILL.md
Normal file
@@ -0,0 +1,106 @@
|
||||
---
|
||||
name: "ulthon-permission-cli"
|
||||
description: "解释并指导 RBAC 权限体系与相关 CLI 命令(admin:role:* / admin:user:role:* / admin:permission:*)。用于查看节点、管理角色权限、给用户分配角色、排查权限问题。"
|
||||
---
|
||||
|
||||
# 权限与角色管理(RBAC CLI)
|
||||
|
||||
## 何时调用
|
||||
|
||||
- 需要查看系统当前有哪些权限节点。
|
||||
- 需要创建/查看/删除角色,或查看角色详情。
|
||||
- 需要为角色分配/撤回权限节点。
|
||||
- 需要给指定用户分配/撤回角色。
|
||||
- 需要排查“有菜单但无权限 / 有权限但仍被拦截 / 节点名称不一致”等权限问题。
|
||||
|
||||
## 概念速览
|
||||
|
||||
- 权限节点:基于控制器/方法注解生成的权限标识(用于授权与鉴权)。
|
||||
- 角色:权限节点的集合(`SystemAuth`)。
|
||||
- 用户:后台用户(`SystemAdmin`),通过 `auth_ids`(逗号分隔)绑定角色 ID 列表。
|
||||
- 角色-节点:`SystemAuthNode` 记录 `auth_id + node` 的多对多关系。
|
||||
- 鉴权入口:后台请求进入后会根据“当前节点”进行权限检查(未授权则拦截)。
|
||||
- 输出说明:权限相关命令默认以文本输出为主;如命令涉及交互确认,可使用 `--force-force` 或 `-ff` 跳过确认。
|
||||
|
||||
## 常用命令
|
||||
|
||||
### 1) 查看权限节点
|
||||
|
||||
```bash
|
||||
php think admin:permission:nodes
|
||||
```
|
||||
|
||||
常用参数(如需):
|
||||
- `--module=<模块>`:按模块过滤
|
||||
- `--level=1|2`:按级别过滤(1=控制器,2=方法)
|
||||
|
||||
### 2) 角色管理
|
||||
|
||||
```bash
|
||||
php think admin:role:list
|
||||
php think admin:role:info --role-id=12
|
||||
php think admin:role:create --title="测试角色" --remark="测试用"
|
||||
php think admin:role:delete --role-id=12
|
||||
```
|
||||
|
||||
要点:
|
||||
- 删除角色会检查该角色是否仍被用户分配;若仍有用户绑定,则删除会失败。
|
||||
|
||||
### 3) 角色权限管理
|
||||
|
||||
```bash
|
||||
php think admin:role:permission:list --role-id=12
|
||||
php think admin:role:permission:assign --role-id=12 --nodes="system.admin/index,system.admin/add"
|
||||
php think admin:role:permission:revoke --role-id=12 --nodes="system.admin/add"
|
||||
```
|
||||
|
||||
要点:
|
||||
- `--nodes` 支持逗号分隔批量操作。
|
||||
- 建议先用 `admin:permission:nodes` 确认节点名称完全一致后再分配到角色。
|
||||
|
||||
### 4) 用户角色管理
|
||||
|
||||
```bash
|
||||
php think admin:user:role:list --user-id=1
|
||||
php think admin:user:role:assign --user-id=1 --role-ids="12,13"
|
||||
php think admin:user:role:revoke --user-id=1 --role-ids="13"
|
||||
```
|
||||
|
||||
### 5) 透视查询用户当前权限
|
||||
|
||||
```bash
|
||||
php think admin:permission:user --user-id=1
|
||||
```
|
||||
|
||||
## 典型工作流
|
||||
|
||||
### 工作流 A:新增/调整注解后,核对节点并授权
|
||||
|
||||
1. 在控制器/方法上新增或调整权限注解(节点名称、标题、模块等)。
|
||||
2. 执行 `admin:permission:nodes`,确认节点列表中已出现新节点且名称符合预期。
|
||||
3. 确定要使用的角色(可通过 `admin:role:list` / `admin:role:info` 查看;没有合适角色就用 `admin:role:create` 新建)。
|
||||
4. 执行 `admin:role:permission:assign` 将新节点分配给角色。
|
||||
5. 执行 `admin:user:role:assign` 将角色分配给用户。
|
||||
6. 执行 `admin:permission:user` 透视确认该用户已拥有节点。
|
||||
|
||||
### 工作流 B:排查“明明有权限但仍被拦截”
|
||||
|
||||
1. 执行 `admin:permission:user --user-id=<id>`,确认用户是否真的拥有当前节点。
|
||||
2. 执行 `admin:permission:nodes`,确认“当前被拦截节点名”是否存在、是否有大小写/分隔符差异。
|
||||
3. 如果用户通过角色获得权限,执行 `admin:role:permission:list --role-id=<roleId>` 核对角色是否包含该节点。
|
||||
4. 检查后台配置中是否存在免鉴权规则(例如 no_login/no_auth 的控制器/节点白名单)。
|
||||
|
||||
## 变更说明(重要)
|
||||
|
||||
- 旧命令 `admin:permission:assign` / `admin:permission:revoke` 已移除。
|
||||
- “按用户直接增删节点”的需求,应通过“角色”承接:
|
||||
- 只影响单个用户:创建专用角色 → 给该角色分配节点 → 将角色分配给该用户。
|
||||
- 影响一批用户:维护共享角色 → 给该角色增删节点 → 所有拥有该角色的用户一起生效。
|
||||
|
||||
## 常见坑位
|
||||
|
||||
- 节点名不一致:注解里写的节点名与实际鉴权使用的当前节点不一致,导致分配了权限但无法命中。
|
||||
- 只改了菜单没改权限:菜单能看到不代表有权限访问,权限检查以节点为准。
|
||||
- 缓存/环境差异:在不同环境中节点生成来源不一致时,先以 `admin:permission:nodes` 的输出为准核对。
|
||||
- 修改共享角色影响面过大:撤回/新增角色节点会影响所有拥有该角色的用户。
|
||||
- 删除角色失败:仍有用户绑定该角色,先用 `admin:user:role:revoke` 撤回后再删除。
|
||||
97
.agents/skills/ulthon-scheme-curd-workflow/SKILL.md
Normal file
97
.agents/skills/ulthon-scheme-curd-workflow/SKILL.md
Normal file
@@ -0,0 +1,97 @@
|
||||
---
|
||||
name: "ulthon-scheme-curd-workflow"
|
||||
description: "指导使用 Scheme 与 CURD 的标准开发流程。需要新增/调整表结构并生成模块基础代码时调用。"
|
||||
---
|
||||
|
||||
# Scheme + CURD 标准工作流
|
||||
|
||||
## 何时调用
|
||||
|
||||
- 新增业务表、调整字段、补充索引/注释,并希望保持“代码 <-> 数据库”一致。
|
||||
- 准备生成控制器/模型/视图等基础 CRUD 代码。
|
||||
|
||||
## 关键原则
|
||||
|
||||
- CURD 生成前,Scheme 与数据库表结构必须完全一致,否则会被拒绝。
|
||||
- 业务 Scheme 代码统一放在 `app/admin/scheme/`。
|
||||
- 表结构设计遵循项目数据库规范:表名小写下划线、字段注释完整、避免 ENUM。
|
||||
- CURD 命令中的 `{table}` 参数应为**不含前缀的下划线**格式(例如:数据库表 `ul_user_profile` 对应的参数为 `user_profile`)。
|
||||
- CURD 生成的页面脚本(`index.js` / `add.js` / `edit.js` / `read.js` / `_common.js`)默认与视图文件放在同一目录:`app/admin/view/<模块路径>/`,不提供“输出到其他 JS 目录”的配置项。
|
||||
- 一旦你开始在生成代码上做业务改造,就应默认“正式目录不可被覆盖”,后续结构变更需要走“临时生成 + 按需合并”。
|
||||
|
||||
## CURD 命令参数说明
|
||||
|
||||
| 参数 | 简写 | 说明 |
|
||||
|------|------|------|
|
||||
| `--table` | `-t` | 主表名(支持带前缀或不带前缀) |
|
||||
| `--force` | `-f` | 强制覆盖模式(**谨慎使用**) |
|
||||
| `--delete` | `-d` | 删除模式(**删除生成的文件,不是数据库操作**) |
|
||||
| `--runtime` | `-r` | 临时生成模式(**推荐用于预览**) |
|
||||
|
||||
### 参数使用建议
|
||||
|
||||
1. **首次生成**:直接使用 `-t` 生成到项目目录
|
||||
2. **已有业务代码**:使用 `-r` 生成到临时目录,对比并手动合并新增字段/逻辑
|
||||
3. **删除文件**:`-d` 用于清理已生成的文件,不影响数据库
|
||||
|
||||
## 推荐流程
|
||||
|
||||
### A. 以代码为准(推荐)
|
||||
|
||||
1. 在 `app/admin/scheme/` 新建或修改对应表的 Scheme 类。
|
||||
2. 仅查看差异(不改库),确认当前 Scheme 与 DB 的不一致点:
|
||||
|
||||
```bash
|
||||
php think scheme:sync --dry-run
|
||||
```
|
||||
2. 执行同步,将代码结构同步到数据库:
|
||||
|
||||
```bash
|
||||
php think scheme:sync
|
||||
```
|
||||
|
||||
3. 生成 CURD(先生成到临时目录确认更稳妥,`{table}` 需使用下划线格式):
|
||||
|
||||
```bash
|
||||
php think curd -t {table} -r
|
||||
```
|
||||
|
||||
4. 初次接入(代码还未做业务改造)可选择正式生成或覆盖:
|
||||
|
||||
```bash
|
||||
php think curd -t {table}
|
||||
php think curd -t {table} -f
|
||||
```
|
||||
|
||||
### A2. 已经做过业务改造时的推荐做法(临时生成 + 按需合并)
|
||||
|
||||
适用场景:你已经修改过 CURD 生成的控制器/模型/视图/JS 等代码,此时再次 `-f` 覆盖会丢失业务改动。
|
||||
|
||||
1. 先完成结构同步(`scheme:sync` 或 `scheme:make`),确保与数据库一致。
|
||||
2. 始终生成到临时目录:
|
||||
|
||||
```bash
|
||||
php think curd -t {table} -r
|
||||
```
|
||||
|
||||
3. 对比临时目录与正式目录的差异,仅把“新增字段/新增校验/新增表单项/新增列表列”等结构性变更按需合并回正式代码。
|
||||
4. 合并后再做一次功能自测,重点验证新增字段的新增/编辑/列表/详情与校验链路。
|
||||
|
||||
### B. 以数据库为准
|
||||
|
||||
1. 在数据库中创建/修改表结构。
|
||||
2. 反向生成 Scheme 代码(`{table}` 需使用下划线格式):
|
||||
|
||||
```bash
|
||||
php think scheme:make -t {table}
|
||||
```
|
||||
|
||||
3. 再执行 CURD:
|
||||
|
||||
```bash
|
||||
php think curd -t {table} -r
|
||||
```
|
||||
|
||||
## 交互提示
|
||||
|
||||
- 命令行工具通常支持 `--force-force`(`-ff`)跳过交互确认。
|
||||
118
.agents/skills/ulthon-scheme-definition/SKILL.md
Normal file
118
.agents/skills/ulthon-scheme-definition/SKILL.md
Normal file
@@ -0,0 +1,118 @@
|
||||
---
|
||||
name: "ulthon-scheme-definition"
|
||||
description: "指导编写 Ulthon Admin 的 Scheme 架构定义文件。当需要新增表结构、修改字段定义或配置组件显示时调用。"
|
||||
---
|
||||
|
||||
# Ulthon Scheme 定义指南
|
||||
|
||||
本技能指导如何在 `app/admin/scheme/` 目录下编写 Scheme 文件,这些文件定义了数据库表结构以及后台管理界面的组件呈现方式。
|
||||
|
||||
参考文档:[表结构-ulthon_admin](https://doc.ulthon.com/read/augushong/ulthon_admin/619efc9d7af62/zh-cn/2.x.html)
|
||||
|
||||
## 基本结构
|
||||
|
||||
Scheme 文件是一个 PHP 类,继承自 `BaseScheme`,并使用 PHP 8 注解(Attribute)来描述元数据。
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
namespace app\admin\scheme;
|
||||
|
||||
use app\common\scheme\BaseScheme;
|
||||
use app\common\scheme\attribute\Table;
|
||||
use app\common\scheme\attribute\Field;
|
||||
use app\common\scheme\attribute\Component;
|
||||
use app\common\scheme\attribute\Index;
|
||||
|
||||
#[Table(name: 'ul_your_table_name', comment: '表注释')]
|
||||
#[Index(columns: ['field1'], name: 'idx_field1', type: 'NORMAL')]
|
||||
class YourClassName extends BaseScheme
|
||||
{
|
||||
#[Field(type: 'int', length: 11, nullable: false, unsigned: true, autoIncrement: true, primary: true)]
|
||||
public $id;
|
||||
|
||||
#[Field(type: 'char', length: 100, default: '', comment: '标题')]
|
||||
public $title;
|
||||
|
||||
#[Field(type: 'int', length: 11, default: '1', comment: '状态', unsigned: true)]
|
||||
#[Component(type: 'radio', options: ['禁用', '启用'])]
|
||||
public $status;
|
||||
|
||||
#[Field(type: 'int', length: 11, default: '0', comment: '创建时间', unsigned: true)]
|
||||
public $create_time;
|
||||
|
||||
#[Field(type: 'int', length: 11, default: '0', unsigned: true)]
|
||||
public $update_time;
|
||||
|
||||
#[Field(type: 'int', length: 11, default: '0', unsigned: true)]
|
||||
public $delete_time;
|
||||
}
|
||||
```
|
||||
|
||||
## 注解详解
|
||||
|
||||
### 1. #[Table] (类注解)
|
||||
- `name`: 数据库表名(建议以 `ul_` 开头)。
|
||||
- `comment`: 表注释。
|
||||
- `engine`: 存储引擎,默认 `InnoDB`。
|
||||
- `charset`: 字符集,默认 `utf8mb4`。
|
||||
|
||||
### 2. #[Index] (类注解,可重复)
|
||||
- `columns`: 索引列,字符串或数组(如 `['cate_id', 'status']`)。
|
||||
- `name`: 索引名称。
|
||||
- `type`: 索引类型:`NORMAL`, `UNIQUE`, `FULLTEXT`。
|
||||
|
||||
### 3. #[Field] (属性注解)
|
||||
- `type`: 字段类型 (e.g., `int`, `bigint`, `char`, `varchar`, `text`, `decimal`, `tinyint`)。
|
||||
- `length`: 长度 (对于 char/varchar/int)。
|
||||
- `precision`: 精度 (对于 decimal)。
|
||||
- `scale`: 小数位数 (对于 decimal)。
|
||||
- `nullable`: 是否允许为空 (bool)。
|
||||
- `default`: 默认值 (mixed)。
|
||||
- `comment`: 字段注释。
|
||||
- `unsigned`: 是否无符号 (bool)。
|
||||
- `autoIncrement`: 是否自增 (bool)。
|
||||
- `primary`: 是否为主键 (bool)。
|
||||
|
||||
### 4. #[Component] (属性注解,可选)
|
||||
定义在后台管理页面中该字段使用的 UI 组件。
|
||||
- `type`: 组件类型。常用值:
|
||||
- `text`: 普通文本框(默认)。
|
||||
- `image`: 单图片上传。
|
||||
- `images`: 多图片上传(默认分隔符为 `|`)。
|
||||
- `file`: 单文件上传。
|
||||
- `files`: 多文件上传(默认分隔符为 `|`)。
|
||||
- `date`: 时间/日期组件。需配合 `options` 指定格式,如 `datetime` 或 `date`。
|
||||
- `editor`: 富文本编辑器。
|
||||
- `textarea`: 文本域。
|
||||
- `select`: 下拉选择框(需配合 `options`)。
|
||||
- `switch`: 开关组件(需配合 `options`,如 `['0' => '关闭', '1' => '开启']`)。
|
||||
- `checkbox`: 复选框(需配合 `options`)。
|
||||
- `radio`: 单选框(需配合 `options`)。
|
||||
- `relation`: 关联表下拉选择。`options` 需包含:
|
||||
- `table`: 关联表名。
|
||||
- `relationBindSelect`: 显示的字段名。
|
||||
- `primaryKey`: 关联表主键(可选)。
|
||||
- `onlyFields`: 列表页显示的字段(可选,用 `|` 分隔)。
|
||||
- `table`: 表格选择器。`options` 需包含:
|
||||
- `table`: 关联表名。
|
||||
- `type`: 选择模式 (`checkbox`/`radio`)。
|
||||
- `valueField`: 值字段名。
|
||||
- `fieldName`: 显示字段名。
|
||||
- `city`: 城市选择器。`options` 需包含:
|
||||
- `level`: 层级 (`province`/`city`/`area`)。
|
||||
- `options`: 选项数据。支持索引数组 `['禁用', '启用']` 或关联数组 `['1' => '男', '2' => '女']`,对于 `relation`/`table`/`city` 类型,则是配置参数数组。
|
||||
|
||||
## 编写建议
|
||||
|
||||
1. **命名规范**: 文件名采用大驼峰(PascalCase),且必须与类名一致。
|
||||
2. **基础字段**: 建议所有业务表都包含 `id`, `create_time`, `update_time` 字段。如果需要软删除,增加 `delete_time`。
|
||||
- `create_time`, `update_time`, `delete_time` 建议设置为 `int` 类型,默认 `0`,非空。
|
||||
3. **状态表达**: 避免使用 MySQL ENUM 类型。优先使用 `int` 或 `tinyint` 配合 `#[Component(type: 'radio')]` 或 `#[Component(type: 'switch')]`。
|
||||
4. **注释约定**: `Field` 的 `comment` 会直接同步到数据库字段注释,同时也作为后台表单的 Label。
|
||||
5. **字段后缀约定**: 框架会根据字段名后缀自动推断部分组件类型(若未显式指定 `#[Component]`):
|
||||
- `image`, `logo`, `photo`, `icon`: 默认为单图片。
|
||||
- `images`, `photos`, `icons`: 默认为多图片。
|
||||
- `file`: 默认为单文件。
|
||||
- `files`: 默认为多文件。
|
||||
|
||||
140
.agents/skills/ulthon-timer/SKILL.md
Normal file
140
.agents/skills/ulthon-timer/SKILL.md
Normal file
@@ -0,0 +1,140 @@
|
||||
---
|
||||
name: "ulthon-timer"
|
||||
description: "内置秒级定时器(php think timer)的使用与扩展规范;用于新增/调整定时任务(site/call、并发分片、TimerController 防刷、timer.mode normal/parallel)。"
|
||||
---
|
||||
|
||||
# timer(内置秒级定时器)
|
||||
|
||||
## 核心机制(你要记住的 3 件事)
|
||||
|
||||
1) 任务配置统一从 `app_file_path('common/command/timer/config.php')` 读取
|
||||
2) 每个配置会按 `concurrency` 自动展开成多份任务实例,并自动注入 `concurrency_id` / `concurrency_count`
|
||||
3) “是否该执行”主要由定时器侧的 Cache 节流控制(可选叠加控制器侧的防刷保护)
|
||||
|
||||
相关实现入口:
|
||||
|
||||
- 系统入口(优先从 app 层理解):
|
||||
- 定时器命令入口:`app/common/command/Timer.php`(实现继承自 `extend/base/common/command/TimerBase.php`)
|
||||
- 任务实例服务入口:`app/common/service/TimerService.php`(实现继承自 `extend/base/common/service/TimerServiceBase.php`)
|
||||
- site 任务控制器基类入口:`app/common/controller/TimerController.php`(实现继承自 `extend/base/common/controller/TimerControllerBase.php`)
|
||||
- 实现文件(需要深入机制时再看 Base):
|
||||
- [Timer.php](../../../app/common/command/Timer.php) / [TimerBase.php](../../../extend/base/common/command/TimerBase.php)
|
||||
- [TimerService.php](../../../app/common/service/TimerService.php) / [TimerServiceBase.php](../../../extend/base/common/service/TimerServiceBase.php)
|
||||
- [TimerController.php](../../../app/common/controller/TimerController.php) / [TimerControllerBase.php](../../../extend/base/common/controller/TimerControllerBase.php)
|
||||
- 运行模式配置:[timer.php](../../../config/timer.php)
|
||||
|
||||
## 新增定时任务(默认规则)
|
||||
|
||||
无特殊情况下,新增定时任务应当通过本机制实现:在 `timer/config.php` 注册任务 + 以 `site` 或 `call` 的方式实现目标逻辑。
|
||||
|
||||
### 1) 选择任务类型
|
||||
|
||||
- `site`:通过 HTTP 访问一个控制器地址(默认优先使用)。即使任务需要“长时间运行”,也尽量设计成 `site` 模式(分片/分批/可重入),以复用框架的页面/接口同体、鉴权、日志、事务、限流等能力。
|
||||
- `call`:直接执行一个 PHP callable(不推荐;除非万不得已)。仅在确实不适合走 HTTP 上下文、且不希望暴露为控制器入口时使用。
|
||||
|
||||
长时间运行任务的推荐写法(仍用 `site`):
|
||||
|
||||
- 设计为“可重入”的短任务:每次 `do()` 只处理一小批数据,处理进度写入缓存/表,下次继续
|
||||
- 结合 `concurrency` 做分片:按 `$this->concurrencyId` 划分数据范围,多个实例并行推进
|
||||
- 结合 `frequency` 控制节奏:用调度频率限制整体吞吐,避免单次占用过久
|
||||
|
||||
### 2) 编写任务目标(target)
|
||||
|
||||
#### A. site 类型(HTTP 任务)
|
||||
|
||||
实现方式建议:
|
||||
|
||||
- 框架使用者(做业务):仅在 `app/tools/controller/timer/` 新增控制器 `*.php` 即可;不需要、也不应该在 `extend/base/` 增加 `*Base.php`
|
||||
- 框架作者(维护内核):在 `extend/base/tools/controller/timer/` 新增 `*Base.php` 作为默认实现,同时在 `app/tools/controller/timer/` 增加同名入口类 `*.php` 继承 Base(系统唯一调用入口)
|
||||
- 控制器建议继承 `app\common\controller\TimerController`(以获得并发参数校验与可选的 `$frequency` 防刷);执行入口一般提供 `do()`
|
||||
|
||||
示例(已有实现可参考):[ClearLog.php](../../../app/tools/controller/timer/ClearLog.php)、[ClearLogBase.php](../../../extend/base/tools/controller/timer/ClearLogBase.php)
|
||||
|
||||
并发与防刷建议:
|
||||
|
||||
- 如需并发分片处理,在控制器中设置:
|
||||
- `protected $concurrency = N;`
|
||||
- 使用 `$this->concurrencyId` 做分片编号(0 ~ N-1)
|
||||
- 如希望防止外部重复请求(不仅是定时器自身节流),在控制器中设置:
|
||||
- `protected $frequency = 秒数;`
|
||||
- 这会启用 `TimerControllerBase::protectVisit()` 基于 URL 的防刷限制
|
||||
|
||||
#### B. call 类型(函数任务)
|
||||
|
||||
目标形态:
|
||||
|
||||
- `target` 为 `call_user_func` 可执行的 callable,例如:`[SomeService::class, 'method']`、闭包等
|
||||
- 由于 Base/App 双层机制的入口要求,类引用应指向 `app/` 下的入口类(由入口类继承 Base 实现)
|
||||
- 长时间/重任务不建议用 `call`:它缺少 HTTP 上下文与控制器层通用能力,排错与复用成本更高
|
||||
|
||||
### 3) 注册到任务配置(timer/config.php)
|
||||
|
||||
默认配置文件位置(支持分层覆盖):
|
||||
|
||||
- 优先覆盖:`app/common/command/timer/config.php`(一旦存在,`app_file_path(...)` 将优先读取此文件)
|
||||
- 框架默认:`extend/base/common/command/timer/config.php`(当 app 未提供时回落到该文件)
|
||||
|
||||
字段说明(兜底默认值由 Base 层的 `initConfigItem()` 提供):
|
||||
|
||||
- `name`:任务唯一名称(用于 Cache key),不可重复
|
||||
- `type`:`site` 或 `call`
|
||||
- `target`:
|
||||
- `site`:以 `/` 开头的相对路径(建议指向 `tools/timer.*` 控制器的 `do` 方法)
|
||||
- `call`:callable
|
||||
- `frequency`:执行频率(秒),小于 0 会被修正为 0
|
||||
- `concurrency`:并发数量(默认 1)。`site` 类型会自动把并发参数写入 query
|
||||
- `run_type`:保留字段(当前未参与调度逻辑)
|
||||
|
||||
示例(site):
|
||||
|
||||
```php
|
||||
return [
|
||||
[
|
||||
'name' => 'clear_log',
|
||||
'type' => 'site',
|
||||
'target' => '/tools/timer.ClearLog/do',
|
||||
'frequency' => 600,
|
||||
'concurrency' => 1,
|
||||
],
|
||||
];
|
||||
```
|
||||
|
||||
示例(call):
|
||||
|
||||
```php
|
||||
return [
|
||||
[
|
||||
'name' => 'system_host_register',
|
||||
'type' => 'call',
|
||||
'target' => [\app\common\service\HostService::class, 'heartbeat'],
|
||||
'frequency' => 30,
|
||||
],
|
||||
];
|
||||
```
|
||||
|
||||
## 运行与验证
|
||||
|
||||
### 运行命令
|
||||
|
||||
- 常规运行:`php think timer`
|
||||
- 只跑一轮(便于验证):`php think timer --temp`
|
||||
- 无任务时不输出“no request”:`php think timer --quit`
|
||||
|
||||
### 本地调试(指定请求 Host)
|
||||
|
||||
site 任务会按站点域名发起请求,默认从 `sysconfig('site','site_domain')` 读取。
|
||||
|
||||
- 本地调试:`php think timer --local --local-host=http://localhost --local-port=8000`
|
||||
|
||||
### 运行模式
|
||||
|
||||
配置在 [timer.php](../../../config/timer.php):
|
||||
|
||||
- `normal`:单进程循环 + Guzzle async(默认)
|
||||
- `parallel`:Workerman 多进程模式(并发更高,相关连接参数在 `timer.php` 中)
|
||||
|
||||
## 常见坑位(快速自检)
|
||||
|
||||
- `name` 重复:会导致 Cache key 冲突,表现为任务“莫名其妙不跑/跑得不对”
|
||||
- `concurrency` 与控制器侧 `$concurrency` 不一致:会触发 `concurrency id/count error`
|
||||
- 只依赖控制器侧 `$frequency`:它只是防刷,不是调度;调度频率以定时器侧 Cache 节流为准
|
||||
60
.agents/skills/ulthon-tools-http-call/SKILL.md
Normal file
60
.agents/skills/ulthon-tools-http-call/SKILL.md
Normal file
@@ -0,0 +1,60 @@
|
||||
---
|
||||
name: "ulthon-tools-http-call"
|
||||
description: "命令行调用后台控制器/URL 进行联调与功能验证(含默认 super token 模拟登录)。"
|
||||
---
|
||||
|
||||
# tools:http:call(命令行 HTTP 调用工具)
|
||||
|
||||
## 何时使用
|
||||
|
||||
- 需要在命令行快速验证某个后台页面/接口是否正常返回。
|
||||
- 需要绕过浏览器环境,在 CLI 中模拟已登录管理员请求。
|
||||
- 需要用 `--app/--controller/--action` 直接拼控制器路径调用。
|
||||
|
||||
## 基本用法
|
||||
|
||||
### 1) 直接按 URL 调用
|
||||
|
||||
```bash
|
||||
php think tools:http:call --url="/admin/system.admin/index" --method=GET
|
||||
```
|
||||
|
||||
### 2) 按控制器参数调用
|
||||
|
||||
```bash
|
||||
php think tools:http:call --app=admin --controller=system.admin --action=index --method=GET
|
||||
```
|
||||
|
||||
## 请求参数
|
||||
|
||||
- `--url`:请求路径(支持以 `/` 开头的相对路径)。
|
||||
- `--method`:GET/POST/PUT/PATCH/DELETE。
|
||||
- `--data`:JSON 字符串,请求会自动带 `Content-Type: application/json`。
|
||||
- `--body`:原始请求体字符串。
|
||||
- `--headers`:JSON 字符串的请求头对象(例如 `{ "Accept":"application/json" }`)。
|
||||
- `--app --controller --action`:框架特性参数,用于拼控制器路径。
|
||||
|
||||
## super token(默认模拟登录)
|
||||
|
||||
### 机制说明
|
||||
|
||||
- `tools:http:call` 默认会为每次请求生成一个新的 token,并写入 `Cache::store('login')`。
|
||||
- 请求会自动携带 `Authorization: Bearer <token>`。
|
||||
- 服务端会按既有 Bearer token 机制从 `Cache::store('login')` 读取登录态,因此只要命令行与服务端使用同一套缓存即可生效。
|
||||
|
||||
### 指定模拟账号
|
||||
|
||||
```bash
|
||||
php think tools:http:call --url="/admin/system.admin/index" --user-id=2
|
||||
```
|
||||
|
||||
### 关闭 super token(回到未登录行为)
|
||||
|
||||
```bash
|
||||
php think tools:http:call --url="/admin/system.admin/index" --super-token=false
|
||||
```
|
||||
|
||||
## 常见现象与排查
|
||||
|
||||
- 仍提示“请先登录后台”:通常是命令行与服务端的缓存不共享,或服务端未运行/未走到同一环境配置。
|
||||
- 返回“无权限访问”:说明已经是登录态,但该账号对当前节点没有权限;可以换 `--user-id` 或调整权限节点。
|
||||
Reference in New Issue
Block a user