Skip to content

Agent 上下文 · 插件与主题开发手册 ​

用途:给 Cursor / 其他 Agent 的单一入口上下文。开发「插件」或「主题」前先读本文,再按需深入分册。
代码真相源:kede-finance/(若本文与源码冲突,以源码为准)
配套分册:04 / 04a 插件 · 04b 对接 API · 05 市场 · 10 / 10a 主题 · 11 钩子 · 06–08 支付/实名/通知
文档版本:对齐产品 1.0.4(Build 131+)


0. Agent 必读指令(先执行) ​

任务类型判断:
  - 改业务能力 / 钩子 / 后台菜单 / 驱动 → 插件(public/plugins)
  - 改官网/会员中心/购物车外观 → 主题(frontend/themes → public/themes)
  - 改开通对接(云主机等)→ 开通模块(extend/modules),不是插件

硬约束:
  1. 插件目录类型用单数 addon(禁止 public/plugins/addons)
  2. install()/uninstall() 必须 return true(严格 false 才失败;Magfang 短信可 return array)
  3. 配置只走 config.php + getConfig()/setConfig()/configFields(),勿自建密钥存储绕过系统
  4. 勿绕过授权中间件;勿在文档/示例写入授权站内部协议或密钥
  5. 生产安装用「压缩包 → 本地插件 Tab」;市场一键安装仅开发环境(需 MARKETPLACE_SERVER)

完成定义(Definition of Done):
  - 插件:可扫描 → 安装 → 启用 → 配置保存 → 钩子/驱动可验证 → 可卸载
  - 主题:构建到 public/themes → 后台扫描 → 激活 → 前台强刷可见

最短路径

目标做这些
写功能插件§2 结构 → §4 → §6.1 测试清单 → 对照 hello_world
写支付/短信/邮件/实名§4.4 类型契约 → wiki 06/07/08
写 SPA 主题§5 → §6.2 → 对照 frontend/themes/starter
打包给客户§6.3 / §6.4

1. 项目上下文 ​

1.1 系统是什么 ​

项说明
产品可得财务(KeDe Finance)—— 财务/销售/会员/工单/开通
后端ThinkPHP 8(多应用:admin / home / api)
前台Vue3 SPA(frontend/home)
后台Vue3(frontend/admin)
表前缀默认 kd_(以 .env / 安装配置为准)
仓库根kede-finance/(本手册相对路径均相对此根,除非写明 wiki/)

1.2 四类扩展(勿混用) ​

扩展磁盘位置注册表后台入口用途
插件 Pluginpublic/plugins/{type}/{name}/kd_addons插件管理功能/支付/短信/邮件/实名等
主题 Themepublic/themes/{web|clientarea|cart}/{name}/kd_themes + configs.theme.*主题模板外观 / SSR
开通模块 Moduleextend/modules/{Name}/产品模块配置产品/服务器开通云资源等
魔方兼容层插件命名空间别名 + 主题 mf_compat / .tpl——兼容 ZJMF/Magfang 资产

插件内部的 template/ 不是站点主题。

1.3 运行时关键路径(插件) ​

AppInit
  → app\listener\PluginBoot
  → PluginService::boot()
       · 注册自动加载:{type}\{name}\Class → public/plugins/{type}/{name}/
       · status=1 的插件:校验 integrity_hash → include hooks.php → include route.php
       · server/reserver 类型始终尝试加载 hooks/route
  → NotifyService 等核心钩子

1.4 关键文件(Agent 优先打开) ​

角色路径
插件基类app/common/lib/Plugin.php
生命周期app/common/service/PluginService.php
钩子app/common/service/HookService.php + app/common.php(add_hook)
后台菜单/页app/common/service/PluginMenuService.php
后台 APIapp/admin/controller/Addon.php / Marketplace.php
主题服务app/common/service/ThemeService.php
主题后台app/admin/controller/Theme.php
前台应用主题frontend/home/src/utils/theme.ts
主题构建frontend/theme-sdk/scripts/build-themes.mjs
打包市场scripts/build-marketplace.php
诊断scripts/test-siyun-plugin.php · scripts/diagnose-theme.php

2. 目录与命名结构(清晰标注) ​

2.1 插件目录树 ​

public/plugins/
├── addon/                 ← 功能扩展(最常见)
│   └── {snake_name}/
│       ├── {CamelName}.php      【必须】主类;或 {CamelName}Plugin.php
│       ├── hooks.php            【可选】add_hook(...)
│       ├── config.php           【可选】默认配置 array
│       ├── route.php            【可选】启用后加载;server/reserver 始终尝试
│       ├── admin_menu.php       【可选】后台侧栏
│       ├── admin/page.php       【可选】后台宿主页 HTML
│       ├── template/            【可选】插件自有视图(非站点主题)
│       └── vendor/autoload.php  【可选】
├── gateway/               ← 支付
├── sms/                   ← 短信
├── mail/                  ← 邮件
├── certification/         ← 实名
├── server/ | reserver/ | oauth/ | captcha/   ← 兼容目录(可空)

命名铁律

项规则示例
目录名snake_casehello_world
主类文件PascalCase.phpHelloWorld.php
命名空间{type}\{snake_name}addon\hello_world
$info['name']PascalCase,与类名一致HelloWorld
自建表{prefix}addon_{plugin}_*kd_addon_hello_world

2.2 主题目录树 ​

源码(长期维护)

frontend/themes/{name}/
├── theme.json                 【推荐】元数据 + config 变量
├── screenshot.svg             【可选】
├── home/theme.css             → 构建到 public/themes/web/{name}/
├── clientarea/theme.css       → public/themes/clientarea/{name}/
└── cart/theme.config          → public/themes/cart/{name}/

运行时(站点实际加载)

public/themes/
├── web/{name}/                ← 内部 type = home(官网)
├── clientarea/{name}/         ← 会员中心
└── cart/{name}/               ← 购物车
内部 type磁盘目录用途
homepublic/themes/web/官网
clientareapublic/themes/clientarea/会员中心
cartpublic/themes/cart/购物车

2.3 参考实现索引 ​

角色路径
文档示例 addonpublic/plugins/addon/hello_world/
生产向生命周期public/plugins/addon/login_log/
后台侧栏 + 宿主页public/plugins/addon/sidebar_demo/
支付示例public/plugins/gateway/payjs/
魔方短信public/plugins/sms/siyun/
SPA 主题示例frontend/themes/starter/
魔方主题样例public/themes/*/mf_compat/

3. 开发规范(必须遵守) ​

3.1 通用 ​

  1. PHP 8.1+,新文件建议 declare(strict_types=1);
  2. 不提交 .env、私钥、授权站内部协议细节
  3. 用户输入写库前过滤;对外 HTTP 设超时
  4. 钩子内避免长时间阻塞;邮件用 NotifyService::sendMailQuiet() 一类静默发送
  5. 钩子异常会被捕获记日志,不要依赖抛异常中断主流程
  6. 改动范围只做任务需要的文件;勿顺手重构无关模块

3.2 插件规范 ​

规范要求
基类addon → app\common\lib\Plugin;类型插件用对应 *Plugin
生命周期install / uninstall / enable / disable 按需实现
返回值install/uninstall:true 成功;false 失败;短信 Magfang 模板数组视为成功
配置config.php 默认值 ∪ DB kd_addons.config;读 getConfig()
表单configFields(): array 或 Magfang 风格 config.php 字段定义
钩子仅在 hooks.php 注册;启用后才加载
菜单admin_menu.php 的 key 必须以 plugin: 开头
完整性启用时写 integrity_hash;篡改后钩子可能被跳过,需重启用/修复
驱动键支付/实名等常为 plugin:{name}(如 plugin:payjs)

3.3 主题规范 ​

规范要求
CSS 作用域必须带 .kd-theme-scope-{type}[data-kd-theme-{type}="{name}"],禁止裸全局污染
变量theme.json → config → CSS --kd-theme-{key}
维护路径改 frontend/themes/ 后执行构建;勿只改 public/ 后丢源码
SPA vs SSR默认 SPA;仅魔方旧主题需要 theme.ssr_mode=tpl
分发给客户的 zip 基于已构建的 public/themes/...

3.4 Git / 发布(与仓库规则一致) ​

  • 版本与 Build 以 app/common/Version.php 为准(产品发版时)
  • 插件/主题独立分发时,在自身 $info['version'] / theme.json.version 递增
  • 提交信息说明「为什么」;未经要求不要 git commit

4. 插件开发 ​

4.1 生命周期(状态机) ​

磁盘文件就绪
    │
    ▼
[安装] PluginService::install
    · 校验主类存在 → new Instance → install()
    · INSERT kd_addons(通常 status=1)
    · 立即 include hooks.php
    · trigger AfterAddonInstall
    │
    ▼
运行中(status=1):boot 加载 hooks / route
    │
├─[停用] setStatus(0) → disable() → 钩子不再加载
├─[启用] setStatus(1) → enable() → 刷新 integrity_hash
├─[配置] GET config / POST saveConfig → kd_addons.config
    │
    ▼
[卸载] uninstall() → DELETE kd_addons → AfterAddonUninstall
       (磁盘文件保留,可再次安装)

4.2 最小 addon 模板 ​

public/plugins/addon/my_addon/MyAddon.php

php
<?php
declare(strict_types=1);

namespace addon\my_addon;

use app\common\lib\Plugin;

class MyAddon extends Plugin
{
    public $info = [
        'name'        => 'MyAddon',
        'title'       => '我的插件',
        'description' => '说明',
        'author'      => 'YourName',
        'version'     => '1.0.0',
    ];

    public function install() { return true; }
    public function uninstall() { return true; }
}

hooks.php

php
<?php
add_hook('after_user_register', function ($param) {
    // ...
});

config.php

php
<?php
return ['enabled' => '1'];

完整建表 + configFields 示例:直接复制 public/plugins/addon/hello_world/。

4.3 钩子 ​

php
add_hook('hook_name', callable $fn, int $priority = 50); // 数字越小越先
run_hook('hook_name', $params); // 业务侧一般用 HookService::trigger
  • CamelCase 与 snake_case 互通(UserLogin ↔ user_login)
  • 常用钩子见 wiki 11-hooks.md(AfterUserRegister、AfterInvoicePaid、AdminMenu 等)
  • 魔方别名示例:AfterInvoicePaid → 另触发 order_paid

4.4 类型插件契约 ​

type基类必须实现(要点)后台选用
addonPlugin按需 hooks/建表插件管理
gatewayGatewayPlugin + GatewayInterfacename/title/configFields/pay/notify/notifySuccessResponse支付网关 plugin:{name}
smsSmsPlugin + SmsDriverInterfacesend(...);Magfang 可保留 sendCnSms 由桥接通知设置
mailMailPlugin + MailDriverInterfacesend(...)通知设置
certificationCertificationPlugin + RealnameProviderInterfaceinitVerify / queryStatus实名 plugin:{name}

接口源码:

  • app/common/gateway/GatewayInterface.php
  • app/common/notify/SmsDriverInterface.php
  • app/common/notify/MailDriverInterface.php
  • app/common/realname/RealnameProviderInterface.php

4.5 后台菜单与宿主页 ​

admin_menu.php:

php
return [[
    'key'        => 'plugin:my_addon',
    'title'      => '我的模块',
    'addon'      => 'my_addon',
    'icon'       => 'experiment',
    'sort'       => 85,
    'permission' => 'plugin',
]];

admin/page.php 返回 ['title' => '...', 'html' => '...'],由 PluginHost.vue 渲染。
对照:public/plugins/addon/sidebar_demo/。

4.6 配置字段形状 ​

php
public function configFields(): array
{
    return [
        ['name' => 'api_key', 'label' => '密钥', 'type' => 'text', 'default' => '', 'required' => true],
        // type: text | password | textarea | select | switch …(以后台渲染支持为准)
    ];
}

Magfang 插件常见 config.php 为带 type/value 的字段树;系统会 flatten 为键值再存库。


5. 主题开发 ​

5.1 模式选择 ​

模式何时用产物
SPA + CSS(推荐)绝大多数新主题theme.css + 可选 theme.json
SPA + Theme SDK 组件要改区块结构需改 frontend/home(升级冲突风险高)
.tpl SSR魔方旧主题 / 要服务端 HTMLindex.tpl + theme.ssr_mode=tpl

5.2 SPA 主题最小步骤 ​

  1. 复制 frontend/themes/starter → frontend/themes/{name}
  2. 改 theme.json 的 name/title/config(name = 目录名)
  3. 写带作用域的 CSS(见 §3.3)
  4. 构建:
bash
cd kede-finance
node frontend/theme-sdk/scripts/build-themes.mjs
  1. 后台 主题模板 → 扫描 → 按类型启用
  2. 前台 Ctrl+F5;或检查 GET /home/content/siteConfig 的 theme / theme_assets

5.3 CSS 作用域模板 ​

css
.kd-theme-scope-home[data-kd-theme-home="mytheme"] .hero-slide {
  background: linear-gradient(
    125deg,
    var(--kd-theme-hero-from, #0f766e),
    var(--kd-theme-hero-to, #14b8a6)
  );
}

5.4 SSR 摘要 ​

  • POST /admin/theme/ssrMode body: { "mode": "tpl" }
  • 访问 /tpl/home(开发 public/router.php、生产 nginx 需有 /tpl 规则)
  • 渲染器:ThemeTplRenderer(Smarty 子集)
  • SPA 主题未开 SSR 时,/tpl/* 可能 302 回 /,属正常

5.5 魔方主题安装 ​

  1. 解压到 public/themes/{web|clientarea|cart}/{name}/
  2. 确保有 theme.config 或 theme.json
  3. 后台扫描并启用
    详见 frontend/themes/README.md。

6. 安装与测试流程(一目了然) ​

6.1 插件:本地开发安装(最常用) ​

┌─────────────────────────────────────────────────────────┐
│  A. 放文件                                               │
│     public/plugins/{type}/{snake_name}/  写好主类等      │
├─────────────────────────────────────────────────────────┤
│  B. 后台安装                                             │
│     后台 → 插件管理 →「本地插件」Tab                      │
│     → 筛选 type → 找到插件 →【安装】→【启用】             │
├─────────────────────────────────────────────────────────┤
│  C. 配置(如有)                                         │
│     →【配置】→ 填写 → 保存                               │
├─────────────────────────────────────────────────────────┤
│  D. 功能验证(按下表)                                    │
└─────────────────────────────────────────────────────────┘

验收清单(addon)

#步骤期望
1本地插件列表可见标题/版本正确
2安装成功;kd_addons 有行;install() 建表存在
3启用status=1
4触发业务(如注册)钩子副作用出现(表记录/日志)
5改配置再触发新配置生效
6停用再触发钩子不再执行
7卸载kd_addons 无行;uninstall 清表(若实现)

验收清单(gateway)

#步骤期望
1安装启用支付设置可选 plugin:{name}
2发起支付返回跳转/二维码;失败抛可识别错误
3异步回调验签通过;账单变已支付

验收清单(sms / mail)

#步骤期望
1安装启用并选为驱动通知设置可见
2后台测试发送手机/邮箱收到或驱动返回明确错误

验收清单(certification)

#步骤期望
1安装启用,实名驱动选 plugin:{name}前台可发起
2完成或回调用户实名状态更新

CLI 冒烟(魔方短信)

bash
php scripts/test-siyun-plugin.php

6.2 插件:生产压缩包安装 ​

1. 制作 zip(推荐布局):
     my_addon/
       MyAddon.php
       hooks.php
       config.php
2. 解压到: public/plugins/addon/my_addon/
3. 后台 → 本地插件 → 安装 → 启用 → 配置

不要把 zip 解压成 public/plugins/addon/public/plugins/... 嵌套;系统虽有修复,但应避免。

6.3 插件:开发环境市场安装 ​

1. .env: MARKETPLACE_SERVER = https://你的市场地址
2. 后台 → 插件市场 Tab → 安装/升级
3. 生产/内网:不要依赖此方式;改用 §6.2

发布者打包(仅供市场服务器,非生产离线介质):

bash
php scripts/build-marketplace.php
# → resources/marketplace/packages/{type}/{name}.zip + catalog.json

6.4 主题:开发 → 启用 → 验收 ​

┌─────────────────────────────────────────────────────────┐
│  1. 改 frontend/themes/{name}/                           │
│  2. node frontend/theme-sdk/scripts/build-themes.mjs     │
│  3. 后台 → 主题模板 →【扫描】                             │
│  4. 分别启用 home / clientarea / cart(按需)             │
│  5. 前台强刷;检查配色/变量                               │
└─────────────────────────────────────────────────────────┘
#验证期望
1public/themes/web/{name}/theme.css 存在构建成功
2GET /home/content/siteConfigtheme.home 等为新名
3浏览器 Elementsdata-kd-theme-home="{name}";CSS 已加载
4(可选)php scripts/diagnose-theme.php无发现异常

主题 zip 给客户

解压到站点 public/themes/ 对应子目录后 → 扫描 → 启用

6.5 API 快速自测(curl) ​

bash
# 健康/站点(按你的域名或本地端口调整)
curl -sS 'http://127.0.0.1:8800/home/content/siteConfig' | head

# 后台需带管理员 Cookie / Token,以下仅示意路径:
# GET  /admin/addon/index?type=addon
# POST /admin/addon/install          body: type, name
# POST /admin/addon/enable
# GET  /admin/addon/config?type=&name=
# POST /admin/addon/saveConfig
# GET  /admin/theme/index
# POST /admin/theme/sync
# POST /admin/theme/activate         body: type, name
# POST /admin/theme/ssrMode          body: mode=spa|tpl

权限模块名:插件 UI 使用 plugin。


7. API 速查 ​

插件对接完整说明(参数 / 响应 / 驱动 / 魔方 / 自定义 REST):
04b 插件对接 API — Agent 写对接代码时优先打开。

7.1 插件 Addon(摘要) ​

方法路径说明
GET/admin/addon/index?type=扫描列表
POST/admin/addon/install安装
POST/admin/addon/uninstall卸载
POST/admin/addon/enable / disable启停
GET/admin/addon/config配置 + _fields
POST/admin/addon/saveConfig保存
GET/admin/addon/menus侧栏注入
GET/admin/addon/page宿主页

7.2 市场 Marketplace(摘要) ​

方法路径说明
GET/admin/marketplace/index目录
GET/admin/marketplace/detail详情
POST/admin/marketplace/fetch仅下载
POST/admin/marketplace/install下载+安装
POST/admin/marketplace/upgrade覆盖升级
POST/admin/marketplace/sync重扫本地

7.3 主题 Theme ​

方法路径说明
GET/admin/theme/index列表+当前
POST/admin/theme/sync扫描同步
POST/admin/theme/activate激活
POST/admin/theme/ssrModespa/tpl
GET/home/content/siteConfig前台主题资源

8. 排错矩阵 ​

现象优先排查
列表看不到插件路径是否 plugins/{type}/{snake};命名空间;主类文件名;PHP 语法(runtime/log)
安装失败install() 是否 return true;建表 SQL;目录写权限
钩子不跑是否启用;hooks.php 是否存在;钩子名;integrity 是否失败
配置不生效是否保存;是否 getConfig();字段名是否一致
配置页「无可编辑配置」缺 configFields() 且 config.php 无可识别字段;Magfang 字段需可 flatten
类找不到自动加载命名空间;是否误放 addons 复数目录
主题不生效是否构建到 public/themes;是否扫描/激活;浏览器缓存;CSS 作用域选择器
/tpl 302 到首页当前为 SPA 且未开 SSR,正常
市场无法安装生产应改压缩包;检查 MARKETPLACE_SERVER 与网络
魔方短信异常php scripts/test-siyun-plugin.php;桥接类 ZjmfSmsDriverBridge

9. Agent 任务模板(可直接套用) ​

9.1 新功能插件 ​

目标:实现 addon「{标题}」,目录名 {snake_name}
步骤:
  1. 创建 public/plugins/addon/{snake_name}/ 按 §2.1
  2. 实现 install/uninstall/hooks/configFields(按需求)
  3. 对照 hello_world 自测 §6.1
  4. 若需侧栏:admin_menu.php + admin/page.php(对照 sidebar_demo)
  5. 需要分发则打 zip(§6.2)
交付:路径列表 + 验收步骤结果说明

9.2 新 SPA 主题 ​

目标:主题「{title}」,name={name}
步骤:
  1. 复制 frontend/themes/starter → frontend/themes/{name}
  2. 改 theme.json 与 CSS 作用域
  3. node frontend/theme-sdk/scripts/build-themes.mjs
  4. 按 §6.4 验收
交付:源码路径 + public 产物路径 + 激活截图/siteConfig 片段

10. 深入文档索引 ​

文档何时打开
01 概览不熟悉产品
02 快速开始搭本地环境
03 目录结构找目录
04 插件系统插件概览
04a 插件教程手把手 addon
04b 插件对接 APIHTTP/驱动/魔方全量接口
05 插件市场打包/市场
06 支付gateway
07 实名certification
08 通知sms/mail
09 开通模块不是插件
10 主题与 SSR主题概览
10a 主题教程手把手 SPA
11 钩子钩子全表
13 部署宝塔/上线
29 安全加固检查
kede-finance/AGENTS.md仓库内 Agent 入口
kede-finance/README-DEV.md本地启动命令

11. 一页纸速记 ​

插件 = public/plugins/{type}/{snake}/ + kd_addons
主题 = frontend/themes → build → public/themes/{web|clientarea|cart}
模块 = extend/modules(开通,别写成插件)

安装插件:放文件 → 本地插件「安装+启用」→ 测钩子/驱动
装主题:build → 主题模板「扫描+启用」→ 强刷前台

必须 return true;必须 CSS 作用域;生产用 zip 本地装
参考:hello_world / sidebar_demo / starter / payjs / siyun

可得财务 © 2026