调查问卷插件(navgcn_survey)
插件简介
调查问卷系统插件,支持多种题型、游客填写、数据导出、审核流程与统计分析。
版本:1.0.1
适用版本:Xiuno BBS X 1.1+
作者:段先生
许可证:MIT
功能特性
题型支持
单选题(radio)
多选题(checkbox)
单行文本(text)
多行文本(textarea)
下拉选择(select)
评分题(rating,1-10 星)
日期题(date)
手机号题(tel)
邮箱题(email)
问卷生命周期
草稿(status=0):仅创建者可见,可编辑题目
待审核(status=3):提交后等待管理员审核
已发布(status=1):审核通过后公开填写,题目不可编辑
已关闭(status=2):停止填写,可查看统计
用户功能
登录用户可创建、编辑、复制、删除自己的问卷
问卷编辑器支持拖拽排序题型、拖拽排序题目
支持设置开始时间、截止时间、允许游客填写、接收提交通知
我的问卷页面分为"我创建的"和"我的填写记录"两个标签页
问卷统计数据可视化:选项分布进度条、评分平均值
游客支持
游客可填写允许游客填写的问卷
游客填写时可选填昵称
后台可开启游客验证码(使用 CaptchaService 自定义场景)
游客标识通过 Cookie 持久化,防止重复填写
管理员功能
后台问卷管理:查看所有问卷、按状态/关键词筛选
审核流程:通过或驳回待审核问卷,驳回需填写原因并通知作者
填写记录管理:查看所有填写记录、单条详情、批量删除
数据导出:CSV(含 BOM 支持)和 Excel(HTML 表格格式)
后台设置:允许创建问卷的用户组、最大创建数量、游客验证码、结果通知、导出格式、导航栏/发现页显示开关
导航入口
顶部导航栏"问卷"入口(受后台开关控制)
发现页宫格"问卷"入口(受后台开关控制)
个人中心侧边栏"我的问卷"入口
NavService 注册导航项(top/side/mobile 三端)
安装与卸载
安装
将
navgcn_survey目录上传至plugin/目录在后台"插件管理"中点击"安装"
安装完成后自动创建数据表、写入默认配置
导航栏自动显示"问卷"入口
卸载
在后台"插件管理"中点击"卸载"
卸载时将删除所有数据表及配置(请提前备份)
文件结构
navgcn_survey/
├── conf.json # 插件配置
├── icon.png # 插件图标
├── install.php # 安装脚本(建表+默认配置)
├── uninstall.php # 卸载脚本(删表+删配置)
├── upgrade.php # 升级脚本(幂等迁移)
├── setting.php # 后台设置页
├── nav_register.php # NavService 导航注册
├── readme.md # 本文件
├── hook/
│ ├── model_inc_file.php # Service 注册
│ ├── model_route_table_end.php # 前台+后台路由注册
│ ├── index_route_case_end.php # 前台路由分发
│ ├── admin_index_route_case_end.php # 后台路由分发
│ ├── lang_zh_cn_bbs.php # 中文语言包
│ ├── my_sidebar_nav_item_after.htm # 个人中心侧边栏入口
│ ├── header_nav_custom_after.htm # 顶部导航栏入口
│ └── more_discover_items_after.htm # 发现页入口
├── model/
│ └── NavgcnSurveyService.php # 核心服务类
├── route/
│ ├── navgcn_survey.php # 问卷列表页
│ ├── navgcn_survey_create.php # 创建问卷
│ ├── navgcn_survey_edit.php # 编辑问卷
│ ├── navgcn_survey_detail.php # 问卷详情/填写页
│ ├── navgcn_survey_my.php # 我的问卷
│ ├── navgcn_survey_api.php # AJAX API(提交/验证码/状态变更/统计)
│ ├── navgcn_survey_admin.php # 后台问卷管理
│ ├── navgcn_survey_admin_records.php# 后台填写记录
│ └── navgcn_survey_admin_record_detail.php # 后台记录详情
├── view/htm/
│ ├── navgcn_survey_list.htm # 问卷列表模板
│ ├── navgcn_survey_create.htm # 创建问卷模板
│ ├── navgcn_survey_edit.htm # 编辑问卷模板
│ ├── navgcn_survey_detail.htm # 问卷详情/填写模板
│ ├── navgcn_survey_my.htm # 我的问卷模板
│ ├── navgcn_survey_admin.htm # 后台问卷管理模板
│ ├── navgcn_survey_admin_records.htm# 后台记录列表模板
│ ├── navgcn_survey_admin_record_detail.htm # 后台记录详情模板
│ └── navgcn_survey_admin_settings.htm# 后台设置模板
├── static/
│ ├── js/navgcn_survey.js # 题目编辑器辅助 JS
│ └── css/navgcn_survey.css # 插件样式前台入口
页面 | URL |
|---|---|
问卷列表 |
|
创建问卷 |
|
编辑问卷 |
|
问卷详情 |
|
我的问卷 |
|
API 接口 |
|
后台入口
页面 | URL |
|---|---|
问卷管理 |
|
填写记录 |
|
记录详情 |
|
问卷设置 |
|
自检报告
以下为按照 Xiuno BBS X 插件开发技能规则与项目工程规范进行的自检结果。
一、conf.json 配置
包含必填字段:
name、brief、version、bbs_version、type不含已废弃字段:
id、installed、enablehooks_rank键名与 hook 文件名(含扩展名)完全一致version采用三位制(1.0.1)bbs_version与当前 XIUNOX_VERSION 前两段一致(1.1)插件目录名
navgcn_survey符合作者_功能标识两段格式
二、安装/卸载/升级脚本
install.php使用CREATE TABLE IF NOT EXISTS幂等创建install.php使用!defined('DEBUG') AND exit('Access Denied');头部保护install.php数据库表使用DEFAULT CHARSET=utf8mb4install.php使用$db->tablepre获取表前缀install.php使用setting_set()写入默认配置uninstall.php使用标准拼写(非unstall.php)uninstall.php使用DROP TABLE IF EXISTS删表uninstall.php使用setting_delete()删配置upgrade.php使用SHOW COLUMNS+ALTER TABLE幂等迁移upgrade.php使用!defined('DEBUG') AND exit('Forbidden');头部保护
三、Hook 文件
所有 PHP hook 以
<?php开头(非<?php exit;)所有
.htmhook 以<?php开头(非<?php exit;)hook 文件无
return;语句hook 文件名与
conf.json.hooks_rank键名完全匹配model_inc_file.php正确注册 Service 类model_route_table_end.php正确注册前台和后台路由hook 内局部变量使用插件前缀(
$_navgcn_survey_*),不污染宿主作用域
四、路由文件
所有路由文件以
!defined('DEBUG') AND exit('Access Denied');开头前台路由文件 include
APP_PATH.'view/htm/header.inc.htm'和footer.inc.htm后台路由文件 include
ADMIN_PATH.'view/htm/header.inc.htm'和footer.inc.htm后台路由文件开头有
$gid != 1 && $gid != 2权限检查需要登录的页面有
empty($uid)检查并重定向到登录页路由分发使用
param(1)子动作模式(兼容xn_url_parse连字符切分)
五、CSRF 防护
所有 POST 表单包含
<?php echo CsrfService::input();?>所有 POST 处理以
CsrfService::check()开头所有含表单的页面在渲染前调用
CsrfService::generate()模板中
CsrfService::input()调用包含echo关键字
六、输出转义
所有用户内容输出使用
esc_html()/esc_attr()无裸
htmlspecialchars()函数调用无
esc_textarea()调用(不存在的函数)JavaScript 中动态内容使用
escHtml()/escAttr()客户端转义函数escAttr()函数包含 null/undefined 安全检查
七、数据库操作
db_find()参数顺序正确:table, conditions, orderby, page(1-based), pagesizedb_*函数$table参数不含表前缀(传navgcn_survey非bbs_navgcn_survey)user_find_by_uids()使用implode(',', $uids)传入逗号分隔字符串用户信息显示使用
user_find_by_uids()/user_read(),模板取display_name统计字段使用
db_count()直接查询条件,不使用 A-B 相减
八、静态资源
JS 文件位于
static/js/目录CSS 文件位于
static/css/目录静态 JS 文件中无
<?php代码静态资源引用使用
$conf['view_url'].'../plugin/...'格式CSS 引用 URL 格式正确,无错误的
static_version拼接
九、命名规范
数据库表名使用
navgcn_survey前缀语言键使用
navgcn_survey_前缀模板变量使用
$_navgcn_survey_前缀(避免被其他插件覆盖)CSS class 使用
survey-前缀Cookie 名使用
navgcn_survey_guest前缀setting 键使用
navgcn_survey前缀
十、前端框架与交互
UI 框架使用 Bootstrap 5.3
图标使用 Tabler Icons(
<i class="ti ti-xxx"></i>)Card 组件使用
x-cardclass无 jQuery(
$()、.on()、.ajax()、$.fn.*)无 Alpine.js(
x-data/x-show/x-bind/x-model)无 idiomorph / alpine-morph 扩展
使用原生 JS(
fetch/querySelectorAll/addEventListener)后台页面无 htmx,使用原生 JS + Bootstrap
十一、Service 调用
Service 调用前有
include_once守卫CaptchaService 调用前有
class_exists检查NavgcnSurveyService 通过
hook/model_inc_file.php注册到 model 加载列表Service 类使用静态方法模式
十二、URL 生成
所有 URL 使用
url()函数生成无硬编码
.htm/.html后缀前台路由 URL 使用 kebab-case 格式(
navgcn_survey-create)
十三、验证码集成
使用
CaptchaService::register_scene()注册自定义验证码场景验证码生成使用
CaptchaService::generate('survey')验证码验证使用
CaptchaService::verify('survey', $code, $gid)前端通过 AJAX 获取 base64 验证码图片,非直接
<img src>
十四、导航与入口
顶部导航栏入口受后台开关控制
发现页入口受后台开关控制
个人中心侧边栏入口仅登录用户可见
NavService 注册导航项(top/side/mobile 三端)
十五、审核流程
普通用户发布问卷需提交审核(status=3)
管理员可审核通过(status=1)或驳回(status=2)
驳回需填写原因,并通过站内通知告知作者
审核通过后通过站内通知告知作者
十六、Grep 审计结果
htmlspecialchars审计:无实际函数调用(仅注释中出现)jQuery/$.ajax/$.fn审计:无结果Alpine/x-data/x-show审计:无结果return;在hook/目录审计:无结果<?php在static/*.js审计:无结果esc_textarea审计:无结果
十七、安全与权限
后台设置页
setting.php开头有$gid != 1 && $gid != 2权限检查后台管理路由有管理员权限检查
问卷编辑/删除有所有权检查(
$survey['uid'] != $uid)API 接口有登录状态检查
游客填写受
allow_guest开关控制游客验证码受后台
guest_captcha开关控制防重复提交检查(登录用户按 UID、游客按 Cookie 标识)
十八、模板规范
前台模板 include
APP_PATH的 header/footer后台模板 include
ADMIN_PATH的 header/footer模板中使用
x-cardclass 的 Card 组件表格使用
table-responsive包裹分页使用 Bootstrap
pagination组件Tab 导航使用
nav nav-tabs表单使用 Bootstrap 5 表单组件(
form-control、form-check、form-switch)
十九、数据导出
CSV 导出包含 UTF-8 BOM 头
Excel 导出使用 HTML 表格格式 +
esc_html()转义导出文件名包含问卷 ID 和日期
二十、通知系统
问卷被填写时通过
notice_send()通知创建者审核结果通过
notice_send()通知问卷作者通知前检查
function_exists('notice_send')
更新日志
v1.0.0:初始版本,支持基础问卷功能
v1.0.1:新增审核流程、游客验证码、数据导出、统计可视化、拖拽排序


版本:v1.0.1
适用版本:1.1
开发者:cywxmz

