享 享耍主站开发文档

享耍主站开发文档

覆盖主站前端应用、管理后台、PHP MVC API、鉴权会话、插件体系、数据表、安全基线、部署运维与提示词模板。插件包的独立规范请查看插件仓库文档。

公开可读 12 节 PHP 8.1 · 无 Composer 附 5 段提示词模板

01产品与架构

享耍是一套轻量工作台:主站负责介绍与入口,/app/ 是会员应用,/admin/ 是管理后台,/api/ 是统一 JSON 接口。插件主代码放在插件仓库分发,安装后形成 /app/{slug}/ 独立页面。

  • 前端:原生 JS 单页应用,无构建步骤,直接部署静态文件。
  • 后端:PHP 8.1 自研 MVC 内核,PSR-4 自动加载,无 Composer 依赖。
  • 数据:MySQL 5.7 / utf8mb4,PDO 关闭模拟预处理,统一预处理绑定。
  • 插件:仓库上传 zip,业务站按会员安装、启停与卸载。
前后端完全分离:页面只通过 /api/index.php?r=... 取数据,接口统一返回 {ok, data} 或 {ok:false, message}。

02目录结构

wwwroot/
├── index.html               主站介绍页
├── docs/                    主站开发文档(本页)
├── admin/                   管理后台 SPA(独立 tokenKey)
├── app/                     会员应用
│   ├── index.html           应用入口
│   ├── js/                  app.js、api.js、config.js、module-*.js
│   ├── css/                  module.css
│   ├── styles.css           主应用样式
│   ├── wangzhi/             网址插件独立页
│   ├── biji/                记事本插件独立页
│   └── wangpan/             网盘插件独立页
└── api/
    ├── index.php            唯一入口
    ├── bootstrap.php        自动加载与内核启动
    ├── routes.php           路由表
    ├── config.php           数据库与站点配置
    ├── schema.sql           基础表结构
    ├── src/                 内核、控制器、模型、服务
    └── plugins/             插件目录(manifest.json + src + web)

规则:每个模块独立文件夹、独立链路;新增能力优先做成插件,避免主应用继续膨胀。

03文档结构

源码包内的文档与在线文档保持同一口径,避免「页面一套、文件一套」。

docs/
├── index.html               在线文档(公开可读)
├── ARCHITECTURE.md          架构、目录与请求链路
├── API.md                   接口清单与返回约定
├── PLUGINS.md               主站插件体系与仓库接入
└── PROMPTS.md               提示词模板
  • 在线地址:/docs/,无需登录。
  • 插件规范:以 https://xiangshua.com/docs 为准(插件包结构、manifest、提示词)。
  • 更新顺序:先改代码与接口,再同步在线文档,最后更新源码包。
  • 版本记录:破坏性接口变更在文档顶部标注日期与迁移方式。

04前端应用

/app/index.html 加载 config.js、api.js、app.js,通过 hash 与 ?view= 切换视图。接口封装在 window.OOOApi。

方法说明
OOOApi.request(r, options)JSON 请求,自动带 Bearer 与错误提示。
OOOApi.upload(r, file)上传文件,返回进度回调。
OOOApi.getToken()本窗口 sessionStorage 优先,回填共享 localStorage。
OOOApi.setToken(t)同时写入本窗口与共享键。

多窗口登录隔离

  • 会员端使用 ooo_token,后台使用 ooo_admin_token,互不覆盖。
  • 每个窗口优先读自己的 sessionStorage,新窗口才回退到共享 localStorage。
  • 同一浏览器可同时登录管理员与会员,多窗口可登录不同账号。

样式约定

  • 图标卡片:透明背景、62px 炫彩圆角图标、标题居中、最多两行。
  • 窄屏侧栏隐藏,改用顶部栏与底部 Tab 栏,模块页保持一行两个图标。
  • 深色模式通过 data-theme 切换,颜色一律用 CSS 变量。

05管理后台

/admin/ 是独立 SPA,使用 ooo_admin_token,普通入口禁止管理员登录,管理员必须从后台入口进入。

  • 面板:概览、用户、卸载反馈、存储维护、会员运营、设置、管理日志。
  • 登录:用户名 + 密码 + 图形验证码;验证码一次性、限时、限次数。
  • 敏感操作写审计日志;创建/停用用户、清理文件等操作带 audit 中间件。
  • 存储维护可扫描缺失文件记录与孤立文件,确认后再清理。

06API 与路由

入口 /api/index.php?r={route},路由表在 api/routes.php,每项为 [METHOD, pattern, 'Controller@action', middleware[]]。

array('GET',  'notes',       'NoteController@index',  array('auth')),
array('POST', 'notes',       'NoteController@create', array('auth')),
array('PUT',  'notes/{id}',  'NoteController@update', array('auth')),
array('DELETE','notes/{id}', 'NoteController@delete', array('auth')),
  • {id} 编译为正整数;控制器按顺序接收参数。
  • 中间件:auth 校验 Bearer 会话,admin 校验角色,audit 写审计日志。
  • 成功返回 {ok:true,data:...},失败返回 {ok:false,message} 与 HTTP 状态码。
  • 插件路由由内核自动追加 plugin:{slug},未安装/停用返回 403。

核心接口分组

分组路径说明
认证auth/captcha auth/login auth/me auth/logout验证码、登录、当前用户、退出。
快捷访问shortcuts列表、新增、修改、删除。
笔记notes列表、新增、修改、删除。
网盘files folders上传、下载、移动、删除、文件夹。
插件plugins plugins/nav plugins/{slug}/update plugins/{slug}/backups索引、导航、安装(自动最新版)、更新、备份与恢复、卸载、启停。
后台admin/*用户、会员、设置、日志、存储与反馈。

07鉴权与会话

  • 登录成功后签发 64 位 token,写入 sessions 表,前端以 Authorization: Bearer 携带。
  • 会话有效期:会员 2 小时、管理员 1 小时,可在「设置 · 站点设置」调整;插件仓库同一套配置。
  • 每次登录新建会话,不删除旧会话,因此多设备、多窗口可同时在线。
  • 管理员登录必须走 entry=admin;从普通入口登录管理员会返回 403 admin_use_admin_entry。
  • 脚本登录必须先取验证码;自动化场景使用 oauth_tickets + /oauth/exchange 换取 token。
前端令牌按窗口隔离:sessionStorage 保存本窗口令牌,localStorage 仅作新窗口回填;后台与会员端使用不同键名。

08插件体系

主站本身只保留「会员」「消息」等基础能力,其它功能全部插件化。插件由仓库分发,会员在会员中心安装、启停、卸载。

自营网店(shop)买家前台使用框架内置路由 store/*(仅需会员登录,不依赖插件中间件):完整说明见 网店 README,接口清单见 网店 API。

层级路径 / 表说明
清单api/plugins/{slug}/manifest.jsonslug、名称、版本、表前缀、导航、权限。
路由api/plugins/{slug}/routes.php自动追加 plugin:{slug} 中间件。
后端src/命名空间 OOO\Plugins\{Studly}。
前端web/index.html安装后复制到 /app/{slug}/。
安装状态user_pluginsuser_id + slug 唯一,含启用开关。
全局包plugin_packages版本、大小、SHA-256、下载统计。

与仓库的对接

  • 业务站通过 HMAC-SHA256 签名请求仓库索引、下载包、回报下载 / 安装 / 更新 / 卸载事件。
  • 下载后校验 X-Package-Sha256,再解包并执行 migrations;安装一律选择仓库最新版本。
  • 仓库地址与接入账号在 api/config.php 的 plugin_hub 配置。

更新与数据备份

  • 仓库有新版本时,会员中心卡片在版本号后显示「有更新 vX」,操作区最前出现「更新到最新版」按钮。
  • 升级前按插件 table_prefix 全量快照到 api/data/plugin-backups/{slug}/*.json.gz,默认保留最近 5 份,可随时恢复。
  • 升级失败自动恢复数据并尝试回拉旧版代码;恢复入口在卡片的「数据备份」弹窗。

更新包示例(shop 1.1.1 → 1.2.0)

更新包是版本号更高的完整包:slug 与 table_prefix 不变,只递增 version;结构变更时新增迁移文件,全部迁移会在安装 / 更新时重跑,必须幂等。

// manifest.json(只改版本与简介)
{
  "slug": "shop",
  "name": "自营网店",
  "version": "1.2.0",
  "table_prefix": "p_shop_",
  "intro": "1.2.0:新增订单备注,支持详情编辑与列表检索。"
}

-- migrations/003_order_remarks.sql
CREATE TABLE IF NOT EXISTS p_shop_order_remarks (
  id INT UNSIGNED NOT NULL AUTO_INCREMENT,
  user_id INT UNSIGNED NOT NULL DEFAULT 0,
  order_id INT UNSIGNED NOT NULL DEFAULT 0,
  remark VARCHAR(200) NOT NULL DEFAULT '',
  created_at DATETIME NOT NULL,
  updated_at DATETIME NOT NULL,
  PRIMARY KEY (id),
  KEY idx_user_order (user_id, order_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

# 打包(不要带最外层目录)
cd /path/to/shop-1.2.0
zip -r ../shop-1.2.0.zip . -x "node_modules/*" ".git/*" "tests/*" "*.log"
unzip -l ../shop-1.2.0.zip | head -20     # 根目录必须直接是 manifest.json

完整示例(目录变化、MySQL 5.7 加列守卫、更新说明、上架与验证步骤)见 仓库文档 · 09A 更新包制作与发布。

插件包结构、manifest 字段、路由写法与提示词,详见 插件仓库开发文档。

09数据表

表用途关键字段
users会员与管理员username role status display_name
sessions登录会话token user_id expires_at ip ua
shortcuts快捷访问user_id title url icon
notes笔记user_id title content created_at
files / folders网盘user_id name size path
plugin_packages插件包索引slug version sha256
user_plugins会员安装状态user_id slug enabled
plugin_backups插件升级 / 手动备份slug trigger_type version_from file
settings站点设置group key value
admin_logs管理审计admin_id action detail
插件表一律使用自己的前缀(如 p_notes_),禁止读写公共表;卸载默认不删表。

10安全基线

  • SQL:所有查询经 SqlGuard 与 PDO 预处理;关闭模拟预处理;LIMIT 参数转整数后再拼接。
  • SqlGuard:先抹掉字符串字面量,再拒绝多语句与 --、/* */、# 注释截断;动态表名/列名走白名单。
  • 认证:登录强制图形验证码;密码 password_hash;会话 token 64 位随机。
  • 越权:每个接口按 user_id 校验数据归属;后台接口额外要求 admin 中间件。
  • 上传:限制类型与大小,文件名重命名,禁止路径穿越;上传目录不允许执行脚本。
  • 输出:前端统一转义,富文本白名单过滤;错误不返回堆栈与敏感配置。
  • 审计:敏感管理操作写 admin_logs,保留操作人、动作与详情。

PDO 预处理 SqlGuard 拦截 验证码 角色中间件 审计日志

11部署与运维

  1. 上传 wwwroot 内容到站点根目录,保留 .htaccess 静态化规则。
  2. 配置 api/config.php 的数据库、站点地址、插件仓库与短信/支付参数。
  3. 首次访问执行安装:写入基础表与管理员账号;升级用 install/upgrade。
  4. 目录权限:上传目录可写,api/config.php 与源码目录不可写。
  5. 启用 HTTPS;后台建议限制来源 IP 或加独立域名。
  6. 定时任务:清理过期会话与临时文件,备份数据库与上传目录。

发布检查

  • 静态资源版本号已更新,避免浏览器命中旧缓存。
  • 接口返回结构与文档一致,错误码可读。
  • 桌面与窄屏均无横向滚动,深色模式可读。
  • 登录、退出、多窗口会话与验证码回归通过。
  • 数据库变更已写入 schema.sql 或迁移脚本。

12提示词模板

替换花括号后直接交给 AI;一次只做一件事,先约束范围再提要求。

A. 新增一个接口 / 模块

你是享耍主站后端开发者。请只新增下面这个接口,不要改动无关路由。

需求:{一句话描述}
路由:{METHOD} {path}
入参:{字段与类型}
返回:{结构}
权限:{登录 / 管理员 / 公开}
数据表:{表名与字段;若需新建请给出幂等 SQL}

约束:
- 路由写进 api/routes.php,控制器放 api/src/Http/Controllers,模型放 api/src/Models。
- 所有 SQL 预处理绑定;分页参数转整数后再拼接 LIMIT。
- 按 user_id 校验数据归属;错误抛 HttpException 并给中文提示。
- 返回统一 $this->ok([...]) 结构。
- 完成后列出改动文件、SQL 变更与自测请求示例。

B. 改造前端页面

你是享耍前端开发者。只修改我指定的页面与样式,不要重构无关代码。

页面:{/app/index.html 或 /app/xxx/index.html}
要改的内容:{逐条描述}
保持不变:{结构、类名、接口、深链}

要求:
- 沿用现有 CSS 变量与组件类名,不引入框架。
- 桌面与 390px 窄屏都要正常,无横向滚动。
- 深色模式可读;按钮可键盘操作。
- 不破坏 ?view= 深链与多窗口登录隔离。
- 完成后说明改了哪些文件与自测步骤。

C. 审查与修复

你是享耍代码审查员。请审查我提供的文件,按严重程度排序输出问题,不要直接大改。

检查项:
1. SQL 是否全部预处理;SqlGuard 是否覆盖;分页是否整数拼接。
2. 接口是否校验 user_id 归属;后台接口是否有 admin 中间件。
3. 登录态是否可能出现跨窗口覆盖;后台与会员 token 是否分离。
4. 上传是否限制类型/大小/路径;输出是否转义。
5. 前端加载/空/错误态是否齐全;窄屏是否一行两个图标。
6. 敏感操作是否写审计日志。

输出格式:P0/P1/P2 分级,每条给出文件、行号、风险与最小修复方案;最后列出待确认问题。

D. 发布插件更新包

你是享耍插件维护者。我要发布 {slug} 的更新包,并确保升级不丢数据。

当前版本:{x.y.z}
目标版本:{x.y.w}
本次改动:{新增 / 修复 / 结构变更}

请完成:
1. 说明版本号该递增哪一段(修订 / 功能 / 不兼容)及理由。
2. 输出 manifest.json:slug 与 table_prefix 不变,version 递增,intro 写明更新内容。
3. 结构变更时新增 migrations/{序号}.sql,必须幂等;不得修改历史迁移文件。
4. 更新 docs/README.md 的更新说明(新增、变更、修复、注意事项)。
5. 打包完整插件包,zip 内不套外层目录,命名 {slug}-{version}.zip;
   排除 node_modules、.git、测试脚本与密钥。
6. 到仓库后台「插件包」→ {slug} 分组 → 「上传更新包」,确认新版本置顶并标记「最新」。
7. 说明验收:会员中心出现「有更新 vX」→ 一键更新 → 升级前自动备份 → 失败自动回滚。

E. 会员中心升级与备份改造

你是享耍业务站开发者。目标:会员中心支持「安装自动取最新版 + 有更新提示 + 一键更新 + 数据备份恢复」。

后端(OOO\Plugin\PluginManager):
1. catalog() 返回 latest_version 与 has_update(本地 version vs 仓库索引,version_compare 比较)。
2. install():缺包按仓库最新版下载;本机落后时自动走升级流程。
3. update():校验已安装、非内置、仓库确有更高版本后调用 runUpgrade()。
4. runUpgrade():先按 table_prefix 全量备份 → 下载校验 SHA-256 → 解包 → migrations;
   失败恢复备份并尽力回拉旧版本。
5. 备份文件放 api/data/plugin-backups/{slug}/*.json.gz,元数据入 plugin_backups,保留最近 5 份。
6. 路由:plugins/{slug}/update 与 plugins/{slug}/backups(增删查、restore),全部带 auth。

前端(会员中心):
- 版本号后显示「有更新 vX」;动作区顺序:更新到最新版 → 打开 → 启停 → 数据备份 → 删除。
- 备份弹窗展示类型/时间/版本/表数/行数/大小,支持立即备份、恢复、删除;
  恢复前提示「插件数据全站共享,会覆盖所有会员」。

输出:改动文件、接口返回示例与验证步骤(含失败回滚验证)。