vr-shopxo-plugin/docs/07_SHOPXO_PLUGIN_MECHANISM.md

13 KiB
Raw Blame History

ShopXO 插件开发文档

来源doc.shopxo.net 官方文档 + PluginsService.php 源码 + CSDN/搜索补充 版本ShopXO v2.2.0+(基于 ThinkPHP 8 整理:西莉雅


一、目录结构

系统结构v2.2.0+

www/                          # WEB部署目录或子目录
├─ app/                        # 应用目录
│   ├─ plugins/                # 插件目录
│   │   ├─ {plugins_name}/     # 插件目录(目录名 = config.json 的 plugins 字段)
│   │   │   ├─ config.json     # ★ 插件配置(核心文件)
│   │   │   ├─ admin/          # 后台管理
│   │   │   │   ├─ controller/ # 控制器
│   │   │   │   └─ view/       # Blade 视图app/plugins/{name}/view/admin/
│   │   │   ├─ index/          # 前台用户端
│   │   │   │   ├─ controller/
│   │   │   │   └─ view/
│   │   │   ├─ api/            # API接口端
│   │   │   │   └─ controller/
│   │   │   ├─ service/
│   │   │   │   └─ BaseService.php   # ★ 基础服务类(配置处理、菜单等)
│   │   │   ├─ Event.php            # ★ 生命周期事件类
│   │   │   ├─ common.php           # 公共函数
│   │   │   └─ hook/                # 钩子类目录(可选)
│   │   └─ ...
│   ├─ admin/                  # 后台管理模块
│   ├─ index/                  # 前台模块
│   ├─ api/                    # API接口模块
│   ├─ common.php              # 公共函数文件
│   └─ event.php               # 事件定义文件
├─ config/                     # 全局配置
├─ public/                     # WEB目录对外访问
│   ├─ index.php              # 前端入口
│   ├─ admin.php              # 后台入口
│   └─ api.php                # API入口
└─ vendor/                     # Composer依赖

插件静态资源路径

public/static/plugins/{plugins_name}/   # JS/CSS/图片
  ├─ index/   # 前台静态资源
  └─ admin/   # 后台静态资源

二、config.json — 插件配置文件(核心)

标准结构

{
  "base": {
    "name": "插件显示名称",
    "version": "1.0.0",
    "author": "作者名",
    "desc": "插件描述",
    "plugins": "vr_ticket",       // ★ 必须与目录名一致(唯一标识)
    "is_apps_ten_pay": 0
  },
  "element": [
    {
      "element": "input",
      "type": "text",
      "name": "api_key",
      "title": "API密钥",
      "value": "",
      "message": "请输入API密钥"
    }
  ],
  "hook": {
    "app_init": ["\\app\\plugins\\vr_ticket\\hook\\AppInit"]
  },
  "backend_hook": {
    "admin_user_view_right": ["\\app\\plugins\\vr_ticket\\hook\\AdminUserViewRight"]
  }
}

element 支持的表单类型

element 说明 关键参数
input 单行文本 type: text/password/number
textarea 多行文本
radio 单选 data: [{name, value}]
checkbox 多选 data: 同上
select 下拉选择 同上
upload 文件上传

hook vs backend_hook

  • hook:前端/全局钩子,在用户端触发
  • backend_hook:后台管理钩子,在 admin 模块触发

三、钩子系统Hook

ShopXO 基于 ThinkPHP 6 的 Event/Facade 机制实现插件钩子。

已知系统钩子(从源码/文档整理)

钩子名称 触发时机 常见用途
app_init 应用初始化(最早) 全局预处理
app_begin 应用开始 初始化扩展
module_init 模块初始化 模块级别扩展
action_begin 操作开始执行前 权限校验、前置处理
view_filter 视图内容过滤 输出内容处理
log_write 日志写入 自定义日志
app_end 应用结束 收尾处理
admin_user_view_right 管理员查看用户详情右侧 扩展用户信息面板
plugins_view_welcome 插件欢迎页 自定义插件首页

重要:开启开发者模式后,后台应用管理页面会显示所有可用钩子的提示名称。 路径:config/shopxo.phpis_develop: true

前端钩子注册方式

config.json 中:

"hook": {
  "钩子名称": ["\\app\\plugins\\{name}\\hook\\HookClass"]
}

后台钩子注册方式

"backend_hook": {
  "钩子名称": ["\\app\\plugins\\{name}\\hook\\HookClass"]
}

钩子类示例

<?php
// app/plugins/vr_ticket/hook/AppInit.php
namespace app\plugins\vr_ticket\hook;

class AppInit
{
    public function handle($params = [])
    {
        // 处理逻辑
        return ['code' => 0, 'msg' => 'success'];
    }
}

四、插件生命周期事件Event

插件可以通过 Event.php 响应系统生命周期回调。

生命周期事件列表

事件方法 触发时机 返回值意义
Upload 上传插件包时
BeginInstall 安装前(验证) 非0 → 阻止安装
Install 执行安装
Uninstall 卸载插件
Download 下载插件
BeginUpgrade 更新前(验证) 非0 → 阻止更新
Upgrade 执行更新
Delete 删除插件

Event.php 示例

<?php
// app/plugins/vr_ticket/Event.php
namespace app\plugins\vr_ticket;

class Event
{
    // 安装前验证
    public function BeginInstall($params = [])
    {
        // 检查依赖等
        return DataReturn('可以安装', 0);
    }

    // 执行安装
    public function Install($params = [])
    {
        // 创建数据库表等
        return DataReturn('安装成功', 0);
    }

    // 卸载
    public function Uninstall($params = [])
    {
        // 清理数据等
        return DataReturn('卸载成功', 0);
    }

    // 支付回调事件(需配合支付插件使用)
    public function PaySuccess($params = [])
    {
        // $params 包含 order_id, pay_price, payment 等
        return DataReturn('处理成功', 0);
    }
}

五、控制器与路由

URL 路由格式

/plugins/{group}?pluginsname={plugins}&pluginscontrol={control}&pluginsaction={action}

示例:

/plugins/index?pluginsname=vr_ticket&pluginscontrol=index&pluginsaction=index
/plugins/admin?pluginsname=vr_ticket&pluginscontrol=admin&pluginsaction=index
/plugins/api?pluginsname=vr_ticket&pluginscontrol=api&pluginsaction=notify

控制器命名规范

app/plugins/{name}/{group}/controller/{Control}.php
  • group: index(前台)| admin(后台)| apiAPI
  • Control: 首字母大写,如 Index, Admin, Order

控制器基类结构

<?php
// app/plugins/vr_ticket/index/controller/Index.php
namespace app\plugins\vr_ticket\index\controller;

class Index
{
    // 前台首页
    public function index($params = [])
    {
        return MyView('', ['data' => $data]);
    }

    // JSON API
    public function detail($params = [])
    {
        return DataReturn('success', 0, $data);
    }
}
<?php
// app/plugins/vr_ticket/admin/controller/Index.php
namespace app\plugins\vr_ticket\admin\controller;

class Index
{
    public function index($params = [])
    {
        IsLogin();  // 后台需登录校验
        return MyView('', []);
    }
}

六、BaseService — 基础服务类

<?php
// app/plugins/vr_ticket/service/BaseService.php
namespace app\plugins\vr_ticket\service;

use think\facade\Db;

class BaseService
{
    // 附件字段(配置中涉及文件上传的字段名)
    public static $base_config_attachment_field = [];

    // 私有字段(不返回给前端的敏感字段)
    public static $base_config_private_field = ['secret_key'];

    // 后台权限菜单(可选)
    public static function AdminPowerMenu()
    {
        return [
            ['name' => '场次管理', 'url' => MyUrl('plugins/admin', ['pluginsname' => 'vr_ticket', 'pluginscontrol' => 'event', 'pluginsaction' => 'index'])],
            ['name' => '门票核销', 'url' => MyUrl('plugins/admin', ['pluginsname' => 'vr_ticket', 'pluginscontrol' => 'verify', 'pluginsaction' => 'index'])],
        ];
    }

    // 配置数据处理(可选)
    public static function BaseConfigHandle($config)
    {
        return $config;
    }
}

读取插件配置

use app\service\PluginsService;

$data = PluginsService::PluginsData('vr_ticket');
// 返回 ['code' => 0, 'msg' => 'success', 'data' => [...配置数据]]

保存插件配置

PluginsService::PluginsDataSave([
    'plugins' => 'vr_ticket',
    'data' => $params
], $attachment_field);

七、模板引擎Blade

ShopXO 使用 Blade 模板(.blade.php

前台视图路径

app/plugins/vr_ticket/view/index/index.blade.php   # 前台
app/plugins/vr_ticket/view/admin/index.blade.php   # 后台

视图中引用静态资源

<img src="{{ \app\common.phpStaticAttachmentUrl('logo.png', 'images', 'vr_ticket') }}" />

<!-- 或直接写死路径 -->
<link href="/static/plugins/vr_ticket/index/css/style.css" rel="stylesheet">
<script src="/static/plugins/vr_ticket/index/js/app.js"></script>

视图渲染

// 渲染插件视图自动读取插件view目录
return MyView('index', ['data' => $data]);
// 路径app/plugins/vr_ticket/view/index/index.blade.php

// 渲染后台视图
return MyView('admin/index', ['data' => $data]);

公共模板变量

app/plugins/vr_ticket/common.php 中定义函数,可供所有视图调用。


八、调试与开发模式

开启开发者模式

路径:config/shopxo.php

'is_develop' => true,  // 从 false 改为 true

开启后后台应用管理页面会显示钩子名称提示。

日志文件

runtime/log/{年份}/{月份}.log
例runtime/log/2025/09.log

调试模式

.env 中设置:

APP_DEBUG=true

九、支付插件extend/ 方式)

ShopXO 的支付插件放在 extend/payment/ 目录,与通用插件不同。

extend/
└─ payment/
    ├─ Alipay.php     # 支付宝支付
    └─ Weixin.php     # 微信支付

支付插件实现支付接口集成,订单支付成功后会触发事件通知。


十、与 vr-shopxo-plugin 需求对应的关键点

VR 票务插件需要对接的核心功能

1. 票务场次管理(后台)

  • 路由/plugins/admin?pluginsname=vr_ticket&pluginscontrol=event&pluginsaction=index
  • 数据库:需创建 vr_events(场次)、vr_sessions(场次时间/库存)、vr_tickets(电子票)
  • 后台菜单:通过 BaseService::AdminPowerMenu() 注册

2. 支付回调处理API

  • 路由/plugins/api?pluginsname=vr_ticket&pluginscontrol=api&pluginsaction=notify
  • 触发方式:支付插件在支付成功后调用此接口
  • 关键逻辑
    1. 验证支付签名
    2. 创建 vr_tickets 记录AES_Encrypt 防伪造 QR
    3. 更新 vr_sessions 库存

3. 观演人信息收集

  • 触发时机:订单 pendingpaid 过渡阶段
  • 实现方式:可在订单扩展字段或 OrderService 中 hook
  • 字段:姓名、手机号、身份证(可选)

4. QR 电子票展示(前台)

  • 路由/plugins/index?pluginsname=vr_ticket&pluginscontrol=ticket&pluginsaction=detail
  • 数据源vr_tickets
  • 展示:票面信息 + QR 码图片

5. B 端扫码核销(后台)

  • 路由/plugins/admin?pluginsname=vr_ticket&pluginscontrol=verify&pluginsaction=index
  • 方式:微信扫码枪或管理员扫码页面
  • 逻辑vr_tickets.status = 'used' + 核销时间戳

关键开发顺序

Phase 1: 插件骨架config.json + BaseService + Event
    ↓
Phase 2: 数据库迁移vr_events, vr_sessions, vr_tickets
    ↓
Phase 3: 后台场次管理 CRUDadmin/controller
    ↓
Phase 4: 前台购票流程 + 支付回调api/controller + notify
    ↓
Phase 5: QR 票生成 + 观演人信息
    ↓
Phase 6: B 端核销页面

十一、参考资源

资源 URL
官方文档站 https://doc.shopxo.net/
插件开发索引 https://doc.shopxo.net/article/3.html
目录结构 https://doc.shopxo.net/article/4/265292898306621440.html
应用商店 https://store.shopxo.net/
GitHub 源码 https://github.com/gongfuxiang/shopxo
Gitee 源码 https://gitee.com/zongzhige/shopxo
ThinkPHP 8 文档 https://www.kancloud.cn/manual/thinkphp6_0/