精华 干货 XIUNOX 应用市场上架指南 [复制链接]

管理员组

开发者入驻 · 应用发布 · 审核规范 · 版本更新

版本2.1适用xnx_appcenter 1.15.0+ / XIUNOX 1.1更新2026-08-05

目录

  1. 开发者入驻流程

  2. 应用发布字段规范

  3. 应用状态机与审核流程

  4. 版本更新与自动发帖

  5. 外站应用(download_type=2)

  6. 价格、抽成与下载权限

  7. 代码规范与踩坑速查

  8. 上架前自检清单

1开发者入驻流程

访问 /appcenter-developer-edit.htm 提交资料,管理员审核通过后才能发布应用。校验入口 AppCenterService::checkPublishPrerequisite()

1.1 必填字段

字段

校验规则

说明

intro

必填,≤1000 字

开发者简介

contact_qq

必填

主联系方式

contact_email / contact_wechat / contact_phone

3 选 1 必填

备用联系方式

brand_prefix

正则 ^[a-zA-Z]{5,}_[a-zA-Z]*$

5+ 字母开头 + 下划线;禁用 xn/xnx/xiuno/xiunox

official_domain

URL,自动补 https://

开发者主页

portfolio_url_1/2/3

必须 github.comgitee.com 域名

3 个作品 URL

agreement_agree

必须为 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 字段全表

字段

必填

校验规则

name

≤9 字符

slug

3–50 字符,必须以 brand_prefix 开头,全局唯一,发布后不可改

brief

≤50 字

category

后台预设分类(plugin/template/extension)

tag_keys[]

1–2 个功能标签

description

AIEditor 富文本,纯文本 ≥100 字

icon_tmp_key

应用图标

screenshot_tmp_keys[]

至少 1 张截图

applicable_version

1.0 或 1.1

price_type

0=免费 / 1=付费

price_credits_type

付费时必填

credits/golds/rmbs,受 allowed_credits_types 限制

price_amount

付费时必填

max_price 上限限制

download_type

1=官方应用市场 / 2=自托管外站

external_url

dt=2 时必填

≤255 字符,站外下载地址

version

首版本号

version_download_tmp_key

首版本下载包(dt=1 时必填)

guide_read / confirm_ack / scan_passed

三个声明,必须为 1

2.2 上架前自检

  • 插件包扫描PluginScanner):扫描 conf.json/install/uninstall/upgrade/hook 结构问题

  • 上架前必看:本文档 iframe 嵌入发布页 Modal,必须点击"已阅读"

  • 自检声明:发布页底部按钮,需点击确认

3应用状态机与审核流程

应用 status 字段共 4 个状态。

3.1 状态定义

含义

可见性

0

待审核

仅作者 + 管理员

1

已发布

所有人可见可下载

2

审核未通过

仅作者,reject_reason 必填

3

已下架

仅作者,reject_reason 必填

3.2 状态转换

当前

可转到

触发入口

0 待审

1 通过 / 2 拒绝

后台 audit_app

1 已发布

3 下架

后台 audit_app(reason 必填)

3 已下架

1 重新上架 / 0 退回审核

后台 republish_app / return_audit

任意

0 待审

编辑提交(need_audit=true 或上传新版本强制回审)

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 入口对比

入口

必填字段

回审

发帖

编辑页"上传新版本"

上传包后:version_new + version_changelog

审核通过后发更新帖

详情页"添加新版本"

version + changelog + 下载包

审核通过后发更新帖

编辑页"单纯编辑(不上传包)"

无新版本字段

取决于 need_audit

不发帖

审核驳回修改

无新版本字段

取决于 need_audit 或 status=3

不发帖

4.2 数据存储

  • bbs_xnx_appcenter_version:每版本一条,含 version / download_aid / changelog / thread_tid(v1.15.0 新增) / create_time

  • app.version:addVersion 时同步更新为最新版本号

  • app.thread_tid:仅记录首帖 tid,更新帖 tid 在 version 表

设计原则:触发"上传新版本"流程的唯一标志是 version_download_tmp_key 非空(上传了安装包),不是 version_new 非空。只填版本号不上传包,会走"单纯编辑"分支被静默忽略。

5外站应用(download_type=2)

外站应用由开发者提供 external_url,下载时直接 302 跳转,不走站内下载和购买流程。

5.1 约束

  • 免费应用强制 dt=1price_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.mdbugfix_rules.md

7.1 插件结构

  • conf.json:必含 name/brief/version(X.Y.Z 三位制)/bbs_version(1.0 或 1.1,禁止 4.5);禁止包含 installed/enable

  • install.phpCREATE TABLE IF NOT EXISTS + DEFAULT CHARSET=utf8mb4

  • uninstall.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.php

  • Service 类内部含 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.htmtmp/plugin_xnx_verify_view_htm_xxx.htm

  • 语言包 lang/zh-cn/bbs.phptmp/lang_zh-cn_bbs.php(连字符不是下划线)

  • 批量清理:rm -f tmp/plugin_xnx_{插件名}_* tmp/lang_*.php

  • 新增缓存用 CacheHelper::remember(),清理用 CacheHelper::pluginDeletePrefix()

  • CacheHelper::set() 写版本号/裸值必须用 array('__v'=>$value) 哨兵格式

  • 禁止 cache_truncateflushdb,改用 deleteByPrefix

  • 缓存键 bbs_cache.kvarchar(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_userstatus:封禁用 ban_type(0=正常 / 1=禁言 / 2=禁止访问 / 3=锁定)

  • bbs_useravatar_url:动态计算字段,SQL 中 SELECT 会触发 Unknown column

  • db_* 函数 $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:requesthtmx:after:swaphtmx: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-card class,按钮用 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/ 规则文件整理

管理员标记为「干货」,奖励 +10 积分
最新回复

请先登录后再回复 登录