开发者入驻 · 应用发布 · 审核规范 · 版本更新
版本2.1适用xnx_appcenter 1.15.0+ / XIUNOX 1.1更新2026-08-05
目录
1开发者入驻流程
访问 /appcenter-developer-edit.htm 提交资料,管理员审核通过后才能发布应用。校验入口 AppCenterService::checkPublishPrerequisite()。
1.1 必填字段
字段 | 校验规则 | 说明 |
|---|---|---|
| 必填,≤1000 字 | 开发者简介 |
| 必填 | 主联系方式 |
| 3 选 1 必填 | 备用联系方式 |
| 正则 | 5+ 字母开头 + 下划线;禁用 |
| URL,自动补 | 开发者主页 |
| 必须 | 3 个作品 URL |
| 必须为 1 | 协议需滚动到底 + 10 秒倒计时后才能勾选 |
1.2 审核流程
提交后
audit_status=0,管理员通过后置audit_status=1审核通过后自动发介绍帖到
forum_fid配置版块(createDeveloperThread()),存developer.thread_tid避免重复发帖未通过审核无法发布应用
2应用发布字段规范
发布入口 /appcenter-publish.htm,POST 到 route/appcenter.php publish action。
2.1 字段全表
字段 | 必填 | 校验规则 |
|---|---|---|
| 是 | ≤9 字符 |
| 是 | 3–50 字符,必须以 |
| 是 | ≤50 字 |
| 是 | 后台预设分类(plugin/template/extension) |
| 是 | 1–2 个功能标签 |
| 是 | AIEditor 富文本,纯文本 ≥100 字 |
| 是 | 应用图标 |
| 是 | 至少 1 张截图 |
| 是 | 1.0 或 1.1 |
| 是 | 0=免费 / 1=付费 |
| 付费时必填 | credits/golds/rmbs,受 |
| 付费时必填 | 受 |
| 是 | 1=官方应用市场 / 2=自托管外站 |
| dt=2 时必填 | ≤255 字符,站外下载地址 |
| 是 | 首版本号 |
| 是 | 首版本下载包(dt=1 时必填) |
| 是 | 三个声明,必须为 1 |
2.2 上架前自检
插件包扫描(
PluginScanner):扫描 conf.json/install/uninstall/upgrade/hook 结构问题上架前必看:本文档 iframe 嵌入发布页 Modal,必须点击"已阅读"
自检声明:发布页底部按钮,需点击确认
3应用状态机与审核流程
应用 status 字段共 4 个状态。
3.1 状态定义
值 | 含义 | 可见性 |
|---|---|---|
| 待审核 | 仅作者 + 管理员 |
| 已发布 | 所有人可见可下载 |
| 审核未通过 | 仅作者, |
| 已下架 | 仅作者, |
3.2 状态转换
当前 | 可转到 | 触发入口 |
|---|---|---|
0 待审 | 1 通过 / 2 拒绝 | 后台 |
1 已发布 | 3 下架 | 后台 |
3 已下架 | 1 重新上架 / 0 退回审核 | 后台 |
任意 | 0 待审 | 编辑提交( |
3.3 审核通过自动发帖
forum_fid > 0 且 status 变为 1 时,updateAppStatus() 自动发帖:
首帖(
createForumThread):app.thread_tid为空时触发,标题【XIUNOX{分类名}】{应用名} v{版本号},内容含描述+截图+下载链接(xnx_hidden 启用时回复可见)更新帖(
createUpdateThread,v1.15.0):app.thread_tid非空且最新 version 的thread_tid为空时触发,标题加"更新"后缀
发帖人固定为应用作者 $app['uid'],走 thread_create() 并传 skip_attach_assoc=true。
4版本更新与自动发帖
v1.15.0 起两个入口逻辑统一:上传新版本安装包后版本号和更新日志必填,提交后强制回审,审核通过后自动发"更新帖"。
4.1 入口对比
入口 | 必填字段 | 回审 | 发帖 |
|---|---|---|---|
编辑页"上传新版本" | 上传包后: | 是 | 审核通过后发更新帖 |
详情页"添加新版本" |
| 是 | 审核通过后发更新帖 |
编辑页"单纯编辑(不上传包)" | 无新版本字段 | 取决于 | 不发帖 |
审核驳回修改 | 无新版本字段 | 取决于 | 不发帖 |
4.2 数据存储
bbs_xnx_appcenter_version:每版本一条,含version/download_aid/changelog/thread_tid(v1.15.0 新增) /create_timeapp.version:addVersion 时同步更新为最新版本号app.thread_tid:仅记录首帖 tid,更新帖 tid 在 version 表
设计原则:触发"上传新版本"流程的唯一标志是 version_download_tmp_key 非空(上传了安装包),不是 version_new 非空。只填版本号不上传包,会走"单纯编辑"分支被静默忽略。
5外站应用(download_type=2)
外站应用由开发者提供 external_url,下载时直接 302 跳转,不走站内下载和购买流程。
5.1 约束
免费应用强制 dt=1:
price_type=0 && download_type=2时后端自动改为 1详情页价格徽章仅显示"付费",不显示金额
详情页不渲染购买按钮,满足下载条件显示"前往下载"按钮,不满足显示"无法下载"按钮并弹窗提示
5.2 下载按钮确认弹窗
场景 | 弹窗颜色 | 标题 | 关键条款 |
|---|---|---|---|
免费应用下载 | 蓝色 | ⛑️ 安装前友情提示 | 个人维护、无深度安全检测、引导反馈 |
金币付费购买 | 黄色 | 💰 虚拟商品购买确认 | 支付即得、概不退费、3 秒倒计时锁定按钮 |
跳转外站下载 | 红色 | 🚨 即将离开本站 | 官方免责、风险自担 |
6价格、抽成与下载权限
6.1 价格字段
price_type:0=免费 / 1=付费price_credits_type:credits / golds / rmbs,受后台allowed_credits_types限制price_amount:受max_price上限限制(checkPriceLimit())
6.2 后台配置
commission_rate:系统抽成百分比,默认 10%max_price:全局最大价格default_rmbs_price:一键批量设置付费应用为 RMB 付费
6.3 收益流水
bbs_xnx_appcenter_earnings 表记录每笔购买:order_amount / developer_income / system_fee / commission_rate。
6.4 下载权限
download_allow_groups:允许下载的用户组(空=不限制)download_require_medals:需拥有任意一个勋章才能下载(数组)作者和管理员(gid=1,2)豁免
付费应用必须先
PurchaseService::isPurchased()通过
7代码规范与踩坑速查
所有上架插件必须遵守。详细规则见 .trae/rules/project_rules.md 与 bugfix_rules.md。
7.1 插件结构
conf.json:必含name/brief/version(X.Y.Z 三位制)/bbs_version(1.0 或 1.1,禁止 4.5);禁止包含installed/enableinstall.php:CREATE TABLE IF NOT EXISTS+DEFAULT CHARSET=utf8mb4uninstall.php:标准拼写(非unstall.php),DROP TABLE所有插件表 +setting_delete('插件名')upgrade.php:幂等(SHOW COLUMNS+ALTER TABLE),结构变更必走此机制覆盖核心模板放
plugin/<dir>/overwrite/,禁止改view/htm/lib/下的类不会自动加载,路由层必须显式include
7.2 Hook 规范(高频踩坑)
禁止在 hook 文件中使用 return;:会从宿主函数/路由/模板返回,跳过后续逻辑。违规 5 次导致严重 bug。终止性 exit 需用 if 包裹并加 ponytail: 注释。闭包内 return 合法。
hook 注释禁止 // hook xxx 格式:编译器正则误匹配为 hook 占位符,多趟编译重复拼接导致 ParseError。改用 // hook: xxx 或 // xxx。违规 2 次。
PHP hook 以
<?php开头(防直接访问)插件语言键写入
hook/lang_*_bbs.php,修改后清tmp/lang_*_bbs.phpService 类内部含 hook 注释的必须通过
hook/model_inc_file.php注册,禁止直接include_once
7.3 安全 API
所有 POST 表单含
CsrfService::input()输出用
esc_html()/esc_attr()/esc_js(),禁止innerHTML拼接用户输入param()默认转义,密码等敏感字段传第 3 参FALSE关闭转义密码存储
md5(md5(明文)+salt),登录用user_login_verify()验证码每次提交后刷新
7.4 缓存与编译
修改 _include() 文件后必须清 tmp/ 编译缓存:route/model/view/htm/lang 都通过 _include() 加载,编译缓存命名规则为完整路径的 / 替换为 _。_include() 只检查 tmpfile 是否存在,不比较源文件修改时间。违规 3 次。
插件模板
plugin/xnx_verify/view/htm/xxx.htm→tmp/plugin_xnx_verify_view_htm_xxx.htm语言包
lang/zh-cn/bbs.php→tmp/lang_zh-cn_bbs.php(连字符不是下划线)批量清理:
rm -f tmp/plugin_xnx_{插件名}_* tmp/lang_*.php
新增缓存用
CacheHelper::remember(),清理用CacheHelper::pluginDeletePrefix()CacheHelper::set()写版本号/裸值必须用array('__v'=>$value)哨兵格式禁止
cache_truncate用flushdb,改用deleteByPrefix缓存键
bbs_cache.k为varchar(255),长键正常容纳,无需哈希
PHP 8+ 中 @ 错误抑制符不捕获 Error:被 disable_functions 禁用的内置函数(chmod/mkdir/touch 等)调用会抛 Error 终止脚本,nginx 返回 502。必须用 function_exists('xxx') 守卫包裹。
7.5 数据与 SQL
display_name禁止 SELECT:是user_format()派生的虚拟字段,SQL 中不存在。用user_find_by_uids()批量取bbs_user无status:封禁用ban_type(0=正常 / 1=禁言 / 2=禁止访问 / 3=锁定)bbs_user无avatar_url:动态计算字段,SQL 中 SELECT 会触发Unknown columndb_*函数$table禁止含前缀:内部自动拼接,原生 SQL 需手动拼$db->tablepre分页过滤条件必须下沉 SQL,计数器递减用
user_dec/forum_dec/thread_dec(含GREATEST保护)checkbox 必须
value="1":未声明 value 时默认提交 "on",intval("on")===0导致后端校验失败
7.6 前端与 htmx
禁用 jQuery、Alpine.js、idiomorph。DOM 操作改用原生 JS 或 htmx
htmx 事件名必须用冒号格式:
htmx:config:request、htmx:after:swap、htmx:response:error。旧版驼峰格式(htmx:configRequest/htmx:afterSettle等)已移除,静默失效后端 htmx 请求返回纯 HTML 片段,不返回完整页面、重定向或 JSON
hx-swap="none"时通过HX-Trigger响应头触发前端事件每个局部刷新元素必须明确
hx-target/hx-swap/hx-select异步加载大体积 JS 必须监听
script.onload+script.onerror,setTimeout 仅作兜底UI 改版时必须同步修改 JS 中的 DOM 选择器,grep 所有引用该选择器的 JS 文件
PC/移动端双模板避免相同 id,移动端加
-mobile后缀卡片用
x-cardclass,按钮用px-*控制宽度,禁止w-100表单提交回调中禁止
jform.reset()(会清空用户输入)JS/CSS 修改后递增
conf.json.version强制刷新浏览器缓存
7.7 其他常见陷阱
HTML 注释
<!-- -->不防 PHP 执行:被注释包裹的<?php ?>仍会被执行。需要屏蔽 PHP 代码必须用 PHP 注释//或/* */Tabler Icons 必须用
<i class="ti ti-xxx"></i>:项目不存在tabler_icon()函数URL 函数禁止双重包裹:
admin_plugin_setting_url()等已内置url(),模板中直接echo判断用户是否默认头像禁止用
avatar_url字符串比较:头像替换类插件会改写avatar_url。正确做法:检查user['avatar']字段 + 物理文件存在性
8上架前自检清单
提交应用前逐项核对,"必检"项不通过直接拒绝上架。
8.1 文件结构
conf.json 含 name/brief/version(X.Y.Z)/bbs_version(1.0 或 1.1),无 installed/enable
install.php 用 CREATE TABLE IF NOT EXISTS + DEFAULT CHARSET=utf8mb4
uninstall.php 标准拼写,DROP TABLE 所有插件表 + setting_delete
upgrade.php 幂等(SHOW COLUMNS + ALTER TABLE)
覆盖模板放 overwrite/,禁止改 view/htm/
lib/ 下的类必须显式 include
8.2 安全
所有 POST 表单含 CsrfService::input()
输出用 esc_html() / esc_attr(),禁止 innerHTML 拼接用户输入
param() 敏感字段(密码)传第 3 参 FALSE 关闭转义
密码存储 md5(md5(明文)+salt),登录用 user_login_verify()
8.3 Hook
hook 文件禁止 return;
hook 注释禁止 // hook xxx 格式
终止性 exit 必须 if 包裹 + ponytail: 注释
插件语言键写入 hook/lang_*_bbs.php
8.4 缓存与编译
CacheHelper::set() 用 array('__v'=>$value) 哨兵格式
cache_truncate 用 deleteByPrefix,禁止 flushdb
修改 _include() 加载的文件后清 tmp/ 编译缓存
PHP 8+ 不依赖 @ 抑制 Error,用 function_exists 守卫
8.5 前端
禁用 jQuery、Alpine.js、idiomorph
htmx 事件名用冒号格式
后端 htmx 请求返回纯 HTML 片段
表单提交回调禁止 jform.reset()
按钮用 px-* 控制宽度,禁止 w-100
JS/CSS 修改后递增 conf.json.version
8.6 数据
SQL 中禁止 SELECT display_name / avatar_url / status(bbs_user 无此字段)
db_* 函数 $table 参数禁止包含表前缀
checkbox 必须声明 value="1"
分页过滤条件下沉 SQL,计数器递减用辅助函数
XIUNOX 应用市场上架指南 · 版本 2.1 · 更新于 2026-08-05
基于 xnx_appcenter 1.15.0 源码 + .trae/rules/ 规则文件整理





