# hkcms-addon-dev **Repository Path**: mo3408/hkcms-addon-dev ## Basic Information - **Project Name**: hkcms-addon-dev - **Description**: HKCMS 插件开发技能包 —— 让 AI 助手按官方手册规范**一次写对** HKCMS 插件。 - **Primary Language**: HTML - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-09-20 - **Last Updated**: 2026-09-21 ## Categories & Tags **Categories**: Uncategorized **Tags**: hkcms, skill, 插件开发 ## README # hkcms-addon-dev HKCMS 插件开发技能包 —— 让 AI 助手按官方手册规范**一次写对** HKCMS 插件。 HKCMS 是基于 ThinkPHP + Bootstrap + RequireJS 的免费开源 CMS,插件机制由 `think-addons` 驱动。 它的插件不是"写个 PHP 文件放进去"这么简单:控制器要复制到主项目、模板要落进主题目录、 静态 JS 靠缓存清单注入、安装时目录已存在会直接回滚 —— 这些隐式约定散落在手册和源码里, 踩一次代价通常是半天起步。 这个技能包把这些约定、以及实战中踩出来的坑,整理成 AI 可以直接执行的工作流 + 文档 + 工具。 --- ## 什么时候会用上它 在对话里提到以下任意内容,助手会自动加载本技能: - 开发 / 改造 HKCMS 插件,`addons/xxx` 相关的工作 - 写 HKCMS 后台控制器、后台模板、插件菜单 - 处理插件安装(`install/` 目录)、`install.sql`、插件打包 - 排查"插件装完按钮没反应""弹窗关不掉""地图白屏"这类怪问题 ## 它覆盖什么 | 主题 | 要点 | |---|---| | **目录结构** | `info.ini`、名称类、`config.php`、`common.php`、`route.php`、`data/` 语言包 | | **install 复制机制** | `install/{app,public,template,static}` 四类目录的去向;首次安装的 `%s existed` 回滚规则 | | **后台开发** | `BaseController` + `Crud` trait 的 index/add/edit/del/batches/recycle;三个模板的完整写法 | | **后台模板细节** | `{block:script}` 抽取机制、nice-validator 校验、laydate、`build_radios`、图片上传 `fileGroup` | | **前台开发** | `think\addons\Controller`、视图路径、`__addons__`、`getConfig()` 扁平结构 | | **数据库** | `@prefix@` 占位、空语句块坑、模型 `$name`/时间戳/strict 模式 | | **菜单与权限** | `$menu` 定义、`create_menu()` 同步、`has_rule()` 节点推导、语言包加载 | | **打包与验证** | zip 根目录布局;PHP/JS 语法、模板渲染、SQL 切分、浏览器实测四层校验 | ### 记录在案的重大坑 这些是实际开发中踩过、且**排查成本很高**的问题,均已给出症状、根因和修法: 1. **`volist` 的 `key` 是循环计数器**,不是数组键 —— 关联数组循环必须换写法 2. **弹窗回调抛异常会阻断关闭** —— 表现为"点确定没反应" 3. **高德 JS API 2.0 动态加载**需要重试 + 超时 + `window.AMap` 自愈 4. **高德 loader 是 UMD,与后台 RequireJS 冲突** —— 脚本 200 但 `AMap` 永远 undefined 5. **插件 JS 靠 `adminjslist` 缓存加载**(TTL 86400)—— 装/卸/升级后不清缓存,按钮一天不响应 6. **`install/` 首次安装时目录已存在即回滚** —— `install/app` 不能覆盖系统文件 7. **后台控制器不属于插件路由** —— 插件 `common.php` 不会自动加载,必须手动引入 8. **TP ORM strict 模式过滤未定义字段** —— 新增字段要同步表结构与模型 --- ## 目录结构 ``` hkcms-addon-dev/ ├── SKILL.md 入口:开发流程 + 硬约束 + 踩坑速查表 ├── README.md 本文件 ├── references/ 详细文档,按需加载 │ ├── 01-structure.md 目录结构、名称类、install 机制、config、语言包 │ ├── 02-backend.md 后台控制器、模板、静态 JS、adminjslist 缓存 │ ├── 03-frontend.md 前台控制器/视图、volist、弹窗回调、高德地图 │ ├── 04-database-menu.md install.sql、模型、菜单与权限 │ └── 05-verification-packaging.md 校验手段、浏览器实测、打包 ├── scripts/ 可直接执行的工具(仅用 Python 标准库) │ ├── init_addon.py 生成插件骨架(还原文件名 + 替换占位符) │ ├── check_addon.py 静态自检 │ └── package_addon.py 打包 zip └── assets/scaffold/ 插件骨架模板(占位符 + `原名@扩展名.txt` 命名) ├── info@ini.txt __ADDON__@php.txt config@php.txt common@php.txt route@php.txt ├── install@sql.txt demodata@sql.txt data/zh-cn@php.txt ├── controller/Index@php.txt model/__STUDLY__@php.txt validate/__STUDLY__@php.txt ├── view/index/index@html.txt └── install/ ├── app/admin/controller/__STUDLY__@php.txt ├── template/admin/__ADDON__/{index,add,edit}@html.txt └── static/__ADDON__/__ADDON__@js.txt ``` > **为什么骨架文件名长这样:`__ADDON__@php.txt`?** > skill 分发渠道对文件类型有白名单,只接受 `.md` / `.py` / `.json` / `.txt` / `.yaml` 这类文本类型。 > 直接放 `__ADDON__.php` 会被拒("不允许的文件类型");只加一层 `.tpl` 后缀**同样会被拒**。 > 因此骨架统一命名为 `<原名>@<原扩展名>.txt`:后缀落在白名单内,且文件名里**不出现 `.php` 这类字面量**, > 由 `init_addon.py` 在生成时还原成真实文件名。 > 相关常量在 `init_addon.py` 顶部(`EXT_SUFFIX` / `EXT_SEP`),渠道规则变化时只改这两个即可。 `assets/scaffold/` 里的占位符: | 占位符 | 含义 | 示例(`footprint`) | |---|---|---| | `__ADDON__` | 插件目录名 / 菜单名 | `footprint` | | `__STUDLY__` | 大驼峰类名 | `Footprint` | | `__TITLE__` | 英文标题 | `Footprint` | | `__TITLE_CN__` | 中文名(语言包用) | `用户足迹` | | `__DESC__` / `__AUTHOR__` / `__VERSION__` | 描述 / 作者 / 版本 | — | --- ## 怎么用 ### 交给助手(推荐) 直接描述需求即可,例如: > 帮我做一个 HKCMS 的足迹插件:后台能增删改查,前台列表展示,带封面图和地图选点 助手会自动加载本技能,按流程生成骨架 → 填字段 → 自检 → 打包。 ### 自己动手用脚本 三个脚本都无第三方依赖,先看清楚再跑: ```bash # 1) 生成骨架(占位符替换 + 文件名重命名一步到位) python scripts/init_addon.py footprint -o /path/to/cms/addons \ --title-cn "用户足迹" --desc "用户足迹管理插件" --author yourname # 2) 静态自检:结构 / 命名 / install / SQL / 模板 / 缓存 / php -l / node --check python scripts/check_addon.py /path/to/cms/addons/footprint python scripts/check_addon.py /path/to/cms/addons/footprint --quiet # 只看问题 # 3) 打包(自动排除 *.log / __pycache__ / .DS_Store 等,并校验 info.ini 在根目录) python scripts/package_addon.py /path/to/cms/addons/footprint -o dist/ python scripts/package_addon.py /path/to/cms/addons/footprint --dry-run # 先看会打什么 ``` `check_addon.py` 的返回码:`0` 通过(可能带 WARN),`1` 有致命问题。 它会调用 `php -l` 与 `node --check`,环境里缺哪个就自动跳过对应项,不会失败。 **自检能抓到什么**(都经过负向测试验证): - 名称类类名 / 命名空间与目录名不一致 - 生命周期钩子没清 `adminjslist` 缓存(注释掉的代码也能识别出来) - 后台控制器没 `include_once` 插件 `common.php` - `install.sql` 用 `rtrim(';')`+`explode(';')` 后出现空语句块 - `install/static/` 目录名与插件名不一致 - `install/app` 下有覆盖系统文件风险的文件 - 后台模板 `{block:script}` 开闭不配对 - **前台插件视图里写了 `{block:script}`**(该机制对前台视图无效,会被原样输出) - 表单回填值没用 `htmlspecialchars` 转义 - PHP / JS 语法错误 --- ## 适用环境 - HKCMS:ThinkPHP 8 运行时(官方手册标称 TP6,代码按 TP8 写即可) - 手册: - 脚本:Python 3.8+,仅标准库 - 自检依赖(可选):`php`(做 `php -l`)、`node`(做 `node --check`) - 已验证:PHP 8.0.23 / Python 3.13 / Node 22 ## 维护约定 - `SKILL.md` 只放**流程、硬约束、踩坑索引**,保持精简;详细说明和完整代码模板一律进 `references/`。 - 新增一条踩坑时,同时更新三处:对应 `references/` 章节、`SKILL.md` 的踩坑速查表。 速查表格式固定为「症状 → 病因 → 去哪看」,症状要写用户/开发者能观察到的现象。 - `assets/scaffold/` 是**唯一**的代码模板来源,`references/` 里不再重复贴长模板; 改模板时同步跑一遍 `init_addon.py` + `check_addon.py` 确认自检仍为 0 错误。 - **往骨架里新增文件时,文件名必须写成 `<原名>@<扩展名>.txt`**(如 `__ADDON__.php` → `__ADDON__@php.txt`), 否则会再次触发"不允许的文件类型";且内容里用占位符而不是真实插件名。 - 提交 skill 前先自检一次文件类型,扩展名必须只落在 `md / py / json / txt / yaml` 内: ```bash find . -type f | sed 's/.*\.//' | sort -u ``` - 新增自检规则时,补一条负向测试(故意破坏 → 确认能报错),避免出现假阳/假阴。