diff --git a/README.md b/README.md index a8da4c1..27abbeb 100644 --- a/README.md +++ b/README.md @@ -23,13 +23,14 @@ |------|------| | **[docs/VR_GOODS_CONFIG_SPEC.md](docs/VR_GOODS_CONFIG_SPEC.md)** | ⚠️ **vr_goods_config JSON 格式 v3.0 完整规格**(商品配置核心) | | **[docs/PHASE2_PLAN.md](docs/PHASE2_PLAN.md)** | Phase 2 当前状态 + 下一步工作计划 | -| **[docs/EXPERIENCES.md](docs/EXPERIENCES.md)** | ⚠️ **踩坑经验(必读)** — 16条核心教训 | +| **[docs/EXPERIENCES.md](docs/EXPERIENCES.md)** | ⚠️ **踩坑经验(必读)** — 18条核心教训 | | **[docs/DEVELOPMENT_LOG.md](docs/DEVELOPMENT_LOG.md)** | 开发日志(完整变更记录) | ### 🔧 实现参考 | 文档 | 说明 | |------|------| +| [docs/DEVELOPMENT_GUIDELINES.md](docs/DEVELOPMENT_GUIDELINES.md) | ⚠️ **插件开发规范**(静态文件引用、$public_host、铁律、pre-commit 自检) | | [docs/GOODS_PHP_MODIFICATION.md](docs/GOODS_PHP_MODIFICATION.md) | Goods.php 1行改动说明 | | [docs/09_SHOPXO_HOOKS_REFERENCE.md](docs/09_SHOPXO_HOOKS_REFERENCE.md) | ShopXO 全部钩子清单(从源码提取) | | [docs/07_SHOPXO_PLUGIN_MECHANISM.md](docs/07_SHOPXO_PLUGIN_MECHANISM.md) | 插件开发机制 | diff --git a/docs/DEVELOPMENT_GUIDELINES.md b/docs/DEVELOPMENT_GUIDELINES.md index 044c6c2..d3b38f5 100644 --- a/docs/DEVELOPMENT_GUIDELINES.md +++ b/docs/DEVELOPMENT_GUIDELINES.md @@ -85,6 +85,56 @@ Council agents 和 Claude Code subagents 的 commit 行为**必须约束在 feat - 所有敏感配置(数据库密码、API Key、frp token 等)必须写入 `docs/PRIVATE_CONFIG.md`(不 commit)或 `.env`(已 gitignore) - 禁止将真实密码写入代码或 commit message +### 8. 插件模板静态文件引用规范 + +ShopXO 插件模板引用 JS/CSS 时,必须遵循以下规范: + +**背景**:ShopXO 官方模板用 `{{$public_host}}` 引用静态文件,但插件控制器不继承 `index/Common.php`,`$public_host` 不会自动赋值给插件视图。 + +**正确写法**: + +```php +// 控制器:显式传递 public_host +class Index +{ + public function wallet() + { + $user = UserService::LoginUserInfo(); + return MyView('../../../plugins/vr_ticket/view/goods/ticket_wallet', [ + 'user' => $user, + // 关键:插件不继承 Common 基类,必须显式传递 + 'public_host' => \think\facade\Config::get('shopxo.host_url'), + ]); + } +} +``` + +```html + + + + + + + + + +``` + +**静态文件来源优先级**: +1. **ShopXO 自带**:`{{$public_host}}static/common/lib/` 下已有 JsBarcode、jQuery、AmazeUI 等 +2. **国内 CDN**:`cdn.staticfile.net`(ShopXO 无自带时) +3. **禁止**:国际 CDN(`unpkg.com`、`jsdelivr.net`、`cdnjs.cloudflare.com`)— 大陆阻断 + +**验证方法**:容器内文件是否存在: +```bash +# ShopXO 自带 JsBarcode +docker exec shopxo-php ls /var/www/html/public/static/common/lib/JsBarcode/ +# 应输出:JsBarcode.all.min.js +``` + +**双目录陷阱**:插件 JS/CSS 文件在 `app/plugins/`(PHP runtime)和 `public/plugins/`(Nginx webroot)各有一份副本。修改后必须同步两边。详见 [docs/DEBUG_STATIC_FILE_SYNC.md](docs/DEBUG_STATIC_FILE_SYNC.md)。 + --- ## 三、已知特殊情况记录 diff --git a/docs/EXPERIENCES.md b/docs/EXPERIENCES.md index 266473c..46fdbbd 100644 --- a/docs/EXPERIENCES.md +++ b/docs/EXPERIENCES.md @@ -123,6 +123,8 @@ return [ **教训**:国内项目 CDN 必须用 `cdn.staticfile.net` 或 `cdn.bootcdn.net`,禁止 `unpkg.com`/`cdnjs.cloudflare.com`。 +**更优方案**:优先使用 ShopXO 源码自带的本地文件(见第 18 条)。 + --- ### 7. PHP 注释块污染:未闭合 `/*` 导致语法错误 @@ -289,13 +291,65 @@ const zone = zones.find(z => z.char === seatChar); --- +## 🟢 P2 — 重要经验 + +### 18. 插件模板静态文件引用:`$public_host` 最佳实践 + +**背景**:`ticket_wallet.html` 的 JsBarcode 条形码不显示,原因是 `cdn.jsdelivr.net` 在大陆阻断。 + +**案例**:票夹页面用 `