文档部署到 /ny-exam-platform 子路径 + 移除快照/趋势/异常 + 打印与 UI 全面完善

文档站(#88)
- base 默认改为 /ny-exam-platform/,可用 DOCS_BASE=/ 覆盖本地预览
- 新增 DOCS_OUT 环境变量,避免构建时清空输出目录失败导致产物半截
- 新增 tools/docs-preview.js:按子路径重写路由的本地预览服务
- 删除 docs/guide/snapshot.md,同步清理全部相关文档

移除存快照 / 趋势 / 异常(#89)
- 后端:删除 api.php 的 snapshot_save/list/delete/trend 四个 action 与
  $WRITE_ACTIONS 中的同名条目;删除 lib/Snapshot.php 与自动加载注册;
  DataService 移除 detectAnomalies() 及其调用
- 前端:移除三个按钮与三个弹窗、相关 JS 处理与 state 字段
- 测试:移除对应用例,补充 5 条名单导入列识别断言(17+9+18+32+29+11 全过)

打印完善(#90)
- 改用隐藏 iframe 输出,规避弹窗拦截;@page A4 支持纵向/横向
- 表头每页重复、行内不跨页断开、全表连续名次、可选「是否合格」列
- 分组小计(人数/平均/最高/最低/合格人数与合格率)、可附缺考名单另起一页
- 末尾签字栏;缺考名单打印改为同一套输出

UI / 交互 / Bug 修复(#91)
- dashboard.php:补「← 主系统 / 退出」入口(此前全屏后无法离开);
  修复成员下钻 onclick 里 JSON.stringify 双引号提前闭合属性导致点击报错,
  改为 data-sid 事件委托;补 Esc 关弹窗;后台标签页暂停轮询、切回自动补拉;
  刷新中断原因写入 title;数值字段统一兜底,避免 NaN / undefined%
- draw.php / draw.js:结果表新增「登陆账号」列(导出前可核对,缺失显示 学号 ⚠);
  弹窗只关最上层且支持 Esc;「全部」改为跟随候选池,手工改人数即解除;
  候选池不足时给出明确提示;自定义比例框隐藏时清空,避免旧权重被误读
- app.js / dashboard.php:成绩着色改为按「占本卷满分的百分比」判断,
  修复满分不是 100 时整列误标红
- style.css:数值列右对齐;新增 subbar、draw-stage-sub;
  看板顶栏窄屏下拉与按钮换行,消除横向滚动
This commit is contained in:
2026-09-11 16:23:08 +08:00
parent f271066266
commit 25a2e8a42c
30 changed files with 700 additions and 883 deletions
+3 -4
View File
@@ -1,8 +1,8 @@
import { defineConfig } from 'vitepress'
// 部署到子路径时,构建前设置环境变量即可:
// DOCS_BASE=/ny-exam-docs/ npm run docs:build
const base = process.env.DOCS_BASE || '/'
// 站点部署在域名的 /ny-exam-platform 子路径下,故 base 默认为该路径。
// 本地预览时用 DOCS_BASE=/ 覆盖:DOCS_BASE=/ npm run docs:build
const base = process.env.DOCS_BASE || '/ny-exam-platform/'
// 输出目录。默认 .vitepress/dist;若需要保留旧产物(或环境禁止删除目录),
// 可用 DOCS_OUT=.vitepress/dist2 npm run docs:build 输出到新目录。
const outDir = process.env.DOCS_OUT || '.vitepress/dist'
@@ -72,7 +72,6 @@ export default defineConfig({
{ text: '名单管理', link: '/guide/roster' },
{ text: '成绩明细与统计口径', link: '/guide/scores' },
{ text: '试卷设置(满分/合格率/免考)', link: '/guide/project-config' },
{ text: '快照、趋势与异常检测', link: '/guide/snapshot' },
{ text: '导出与打印', link: '/guide/export-print' }
]
},
+2 -12
View File
@@ -16,7 +16,7 @@
## 写操作白名单
`config_save`、`roster_save`、`roster_import`、`roster_clear`、
`snapshot_save`、`snapshot_delete`、`unmatched_map`、`project_config_save`
`unmatched_map`、`project_config_save`
## 接口清单
@@ -38,7 +38,7 @@
| Action | 方法 | 参数 | 说明 |
| --- | --- | --- | --- |
| `projects` | GET | — | 卷王项目(问卷 / 考试)列表 |
| `data` | GET | `projectId`、`nameQid`、`force` | 主系统数据:统计、成绩行、名单、缺考、未匹配、异常 |
| `data` | GET | `projectId`、`nameQid`、`force` | 主系统数据:统计、成绩行、名单、缺考、未匹配 |
| `dashboard` | GET | `projectId`、`nameQid`、`force` | 按班级 / 组别聚合的看板数据 |
`data` 响应关键字段:
@@ -50,7 +50,6 @@ rows[] { sid, name, cls, grp, score, best_score, attempts, attempts_list[]
roster[] { sid, name, cls, grp, login }
absent[] 缺考名单
unmatched[] 未匹配答卷
anomalies { fast_high[], frequent[], identical[] }
project_cfg 本卷配置
_cache { cached, at }
```
@@ -72,15 +71,6 @@ _cache { cached, at }
| `project_config` | GET | `projectId` | 返回 `cfg`、`effective`(生效值)、`global`(全局默认) |
| `project_config_save` | POST | JSON `{ full_score, pass_rate, exempt[] }` | 留空/0 = 清除该项,回落全局 |
### 快照
| Action | 方法 | 参数 | 说明 |
| --- | --- | --- | --- |
| `snapshot_save` | POST | `projectId`、JSON `{ label }` | 保存当前成绩快照 |
| `snapshot_list` | GET | `projectId` | 列表 |
| `snapshot_delete` | POST | `projectId`、JSON `{ file }` | 删除 |
| `snapshot_trend` | GET | `projectId`(可逗号分隔多个,跨卷对比) | 趋势 |
### 导出
| Action | 方法 | 参数 | 说明 |
+3 -5
View File
@@ -19,11 +19,10 @@ ny-exam-platform/
├─ bootstrap.php 常量、自动加载、配置读写、CSRF、限流、公共函数
├─ lib/
│ ├─ SurveyKingClient.php 卷王 API 客户端(登录 / 令牌 / 项目 / 答卷)
│ ├─ DataService.php 数据组装:姓名→学号匹配、统计、去重、异常检测
│ ├─ DataService.php 数据组装:姓名→学号匹配、统计、去重
│ ├─ Roster.php 名单管理(xlsx/csv 导入、列识别、持久化)
│ ├─ Db.php SQLite 封装(三方言兼容的 DDL 与 upsert)
│ ├─ DataCache.php 结果缓存(TTL + flock 防惊群)
│ ├─ Snapshot.php 成绩快照与趋势
│ ├─ XlsxReader.php 零依赖 XLSX 读取
│ └─ XlsxWriter.php 零依赖 XLSX 写入(支持多工作表)
├─ assets/ style.css / app.js / draw.js
@@ -33,8 +32,7 @@ ny-exam-platform/
│ ├─ roster.json 名单(文件备份)
│ ├─ project_config.json 每卷配置(文件备份)
│ ├─ cache/ 卷王令牌 + 结果缓存
│ ├─ uploads/ 导入临时目录(解析后即删)
│ └─ snapshots/ 成绩快照
│ └─ uploads/ 导入临时目录(解析后即删)
├─ tests/ PHP 自测 + 一键运行脚本
├─ tools/ mock 服务与 Node e2e
└─ docs/ 本文档站(VitePress)
@@ -53,7 +51,7 @@ ny-exam-platform/
│ ├─► Roster::all() 读名单
│ ├─► 姓名 → 学号匹配
│ ├─► dedupe(决定代表成绩)
│ └─► 统计 / 异常检测
│ └─► 统计
└─► ny_resolve_score_cfg() 解析本卷满分与合格率
└─► ny_ok(JSON)
```
-1
View File
@@ -80,7 +80,6 @@ PRAGMA foreign_keys = ON;
| 配置 | `ny_settings['config']` | `data/config.json` |
| 名单 | `ny_roster` | `data/roster.json` |
| 每卷配置 | `ny_project_config` | `data/project_config.json` |
| 成绩快照 | 文件系统 `data/snapshots/` | — |
| 结果缓存 | 文件系统 `data/cache/` | — |
| 卷王令牌 | 文件系统 `data/cache/token.json` | — |
+1 -1
View File
@@ -13,7 +13,7 @@ bash tests/run-all.sh
| 文件 | 类型 | 覆盖 |
| --- | --- | --- |
| `tests/test-aggregate.php` | PHP | 聚合、去重、考试次数、排序 |
| `tests/test-new-features.php` | PHP | 异常检测、快照、趋势、XLSX 多表 |
| `tests/test-new-features.php` | PHP | 再次提交置顶排序、XLSX 多表、名单导入列识别 |
| `tools/test-xlsxwriter.php` | PHP | XLSX 写入与 ZIP 打包 |
| `tools/test-config-save.js` | Node e2e | 配置保存、连接变化检测、每卷配置隔离、CSRF |
| `tools/test-draw-alloc.js` | Node e2e | 随机抽取名额分配(加权 / 自定义 / 守恒 fuzz) |
+10 -1
View File
@@ -13,6 +13,14 @@
| 自动刷新开关 + 间隔 | 与主页面一致的 5 / 10 / 15 / 30 / 60 / 120 秒 |
| 刷新 | 立即拉取一次(跳过缓存) |
| ⛶ 全屏 | 进入 / 退出全屏,布局自动铺满 |
| ← 主系统 | 返回主页面(成绩明细 / 名单 / 抽取);全屏状态下也可直接返回 |
| 退出 | 退出登录 |
::: tip 后台标签页会自动暂停
切换到其他标签页后看板会**停止轮询**,切回来时立即补拉一次数据并重新开始计时——
投屏时长开也不会在无人观看时反复请求卷王。自动刷新失败时,「最后更新」会显示
**刷新中断(仍显示上次数据)**,鼠标悬停可看到具体原因。
:::
## 汇总卡片
@@ -25,7 +33,8 @@
看板主体按**班级**分块,每块内再按**组别**对比,指标与统计口径完全相同:
总人数、已提交、缺考、提交率、平均分、合格率、最高分、最低分、平均用时。
点击班级内任意成员可查看其**每一次提交**(时间、成绩、时长),最高分有标记。
点击考过多次的成员(带「刷 N 次」标签)可查看其**每一次提交**(时间、成绩、时长),最佳成绩有标记。
按 `Esc` 或点击弹窗外部可关闭。
> 未分班的人归入「(未分班)」,未分组的人归入「(未分组)」,不会丢失。
+11 -3
View File
@@ -44,7 +44,15 @@
顶部卡片:`候选人数 / 本次抽取 / 累计已抽取 / 已排除 / 抽取来源`。
结果表格:`序号 / 学号 / 姓名 / 班级 / 组别 / 操作`。
结果表格:`序号 / 学号 / 姓名 / 班级 / 组别 / 登陆账号 / 操作`。
「登陆账号」列让你在导出前就能核对:显示为 `学号 ⚠` 表示名单里没填这一列,
导出时会自动回退用学号——**这会导致学生登不进考试**,请先回主系统「名单管理」补全。
::: tip 「全部」按钮会跟随候选池
点 **全部** 后抽取人数进入跟随模式:切换班级 / 组别 / 来源时人数自动更新为当前
候选池大小。手工改动人数输入框即解除该模式。
:::
| 按钮 | 说明 |
| --- | --- |
@@ -57,8 +65,8 @@
## 登陆账号说明
名单中的**登陆账号**列只在这里用于导出白名单,主系统界面任何位置都不展示。
若名单里没有这一列,导出的白名单该字段为空。
名单中的**登陆账号**列在这里既用于导出白名单,也会直接显示在结果表格中(便于导出前核对)。
若名单里没有这一列,抽取结果里会用 `学号 ⚠` 标出,导出时回退用学号。
::: warning 模板文件名
卷王模板中该列表头为「登陆账号」(不是"登录账号"),导出时已按此命名。
+24 -6
View File
@@ -2,7 +2,8 @@
## 导出成绩明细
工具栏 **导出成绩**,生成 `.xlsx`(零依赖,仓库内自行实现 XLSX 写入,不需要 `zip` 扩展也能用)。
工具栏下方「导出」条里的 **导出成绩**,生成 `.xlsx`(零依赖,仓库内自行实现 XLSX 写入,不需要 `zip` 扩展也能用)。
导出控件单独成行,与筛选、刷新分开,不会挤在一起。
### 三种可选模式
@@ -41,13 +42,30 @@
## 打印成绩明细
成绩明细面板右上角 **打印**:
成绩明细面板右上角 **打印**,弹窗里可设置:
- 默认按**成绩降序**;
- 可选「按班级 / 组别分组对比」,每组段首给出小计;
- 走浏览器打印通道,可直接另存为 PDF。
| 选项 | 说明 |
| --- | --- |
| 打印标题 | 默认「试卷名 + 成绩明细」,可改成学校/考试正式名称 |
| 排序方式 | 成绩降序(默认)/ 升序 / 学号 / 提交时间 |
| 分组对比 | 按班级或组别分段,段首给出小计(人数/平均/最高/最低/合格人数与合格率) |
| 纸张方向 | A4 纵向(列少清晰)或横向(列多不折行) |
| 显示名次 | 全表连续编号,不分组也不会因为分段重新从 1 开始 |
| 显示「是否合格」列 | 低于合格线的成绩与「不合格」标红,一眼定位 |
| 显示考试次数 | 便于发现反复重考的人 |
| 附缺考名单 | 成绩表后**另起一页**附缺考名单,带空白备注列供手写 |
缺考名单面板右上角 **打印** 同理。
其它细节:
- 表头在**每一页自动重复**,行不会被切断到两页;
- 页眉含范围(班级/组别)、打印时间、人数、平均分、最高/最低、合格人数与合格线;
- 页脚含**教师 / 教研组长签字栏与日期**,可直接签字归档;
- 打印走隐藏 iframe 调起,**不会被浏览器的弹窗拦截挡掉**,也不会多开标签页。
## 打印缺考名单
缺考名单面板右上角 **打印**:按班级分组、班内按学号排序,同样带页眉与签字栏,
备注列留空供手写说明(请假、缓考等)。
## 直接调用导出接口
+1 -1
View File
@@ -86,7 +86,7 @@
**Q:可以把平台搬到另一台服务器吗?**
可以。整个目录复制过去,并把 `data/` 一起带上(里面有配置、名单、快照),确保 `data/` 可写。
可以。整个目录复制过去,并把 `data/` 一起带上(里面有配置、名单、每卷配置),确保 `data/` 可写。
## 安全
+1 -2
View File
@@ -97,11 +97,10 @@ Apache 下 `data/` 默认即被保护。仍需确认:
| 路径 | 需要 | 说明 |
| --- | --- | --- |
| `data/` | 可写 | 配置、名单、令牌、快照的根目录 |
| `data/` | 可写 | 配置、名单、令牌的根目录 |
| `data/ny.db` | 可写 | SQLite 主库(启用 `pdo_sqlite` 时) |
| `data/uploads/` | 可写 | 导入名单时的临时落盘,解析后立即删除 |
| `data/cache/` | 可写 | 卷王令牌缓存、结果缓存 |
| `data/snapshots/` | 可写 | 成绩快照 |
```bash
chown -R www:www data
+3 -5
View File
@@ -26,12 +26,10 @@ NY 问卷考试系统数据平台是一个**零第三方运行依赖**的 PHP 8
| 试卷切换 | 下拉选择卷王中的问卷 / 考试,自动拉取该卷全部答卷 |
| 姓名关联 | 自动识别答卷中的「姓名」题,也可手动指定字段;未匹配答卷单独面板 + 一键补入名单 |
| 统计卡片 | 名单总人数、已提交、缺考、平均分、最高分、最低分、合格率、平均用时;选择班级后全部联动 |
| 成绩明细 | 虚拟滚动(无分页)、点击表头排序、搜索、考试次数、新提交绿色高亮(30 秒自动清除) |
| 缺考名单 | 名单中有但未提交的人,支持复制学号 / 姓名、打印 |
| 成绩明细 | 虚拟滚动(无分页)、点击表头排序、搜索(提示同步显示命中数)、考试次数、新提交绿色高亮(30 秒自动清除) |
| 缺考名单 | 名单中有但未提交的人,支持复制学号 / 姓名、打印(按班级分组) |
| 试卷设置 | 为当前选中的试卷单独设置满分 / 合格率 / 免考名单,试卷间互相隔离 |
| 快照 / 趋势 | 保存带标签的时间点快照,横向对比每名学生成绩变化 |
| 异常检测 | 短时长高分、高频重考、雷同成绩三类线索 |
| 导出 / 打印 | 成绩明细、缺考名单 `.xlsx`;成绩明细按成绩降序打印,可选分组对比 |
| 导出 / 打印 | 成绩明细、缺考名单 `.xlsx`;成绩明细按成绩降序打印,支持分组小计、合格标记、附缺考名单、签字栏 |
### 数据看板 `dashboard.php`
+15 -1
View File
@@ -9,6 +9,7 @@
| 名单总人数 | 名单条目数;被当前试卷设为**免考**的人不计入 |
| 已提交 | 匹配到名单、且提交了答卷的人数(去重后的代表成绩行数) |
| 缺考 | `max(0, 名单总人数 − 已提交)` |
| 提交率 | `已提交 ÷ 名单总人数 × 100%`——考试进行中最该盯的指标 |
| 提交率 | `已提交 ÷ 名单总人数 × 100%` |
| 平均分 | 所有**有成绩**的答卷成绩平均值;无成绩者不计入分母 |
| 最高分 / 最低分 | 同上,取自所有有成绩的答卷 |
@@ -40,7 +41,20 @@
| 提交时间 | **最近一次**提交时间(重考低分也会让这行按最新时间排序到最上面) |
| 考试时长 | 最近一次答卷的时长;后台手动录入等没有起止时间的答卷为 `-` |
点击任意一行可查看该学生的**每一次提交**(时间、成绩、时长),最高分有标记。
点击任意一行可查看该学生的**每一次提交**(时间、成绩、时长),最佳成绩有标记。
### 成绩颜色
成绩按**占本卷满分的百分比**着色,而不是写死的 90 / 60 分:
| 颜色 | 条件 |
| --- | --- |
| 绿色 | ≥ 满分的 90% |
| 橙色 | ≥ 合格率线(默认满分的 60%,可在[每卷配置](./project-config.md)里改) |
| 红色 | 低于合格率线 |
这样把满分改成 50 分或 20 分制时,不会因为绝对分数偏低而整列误标红。
数据看板的成员榜使用同一套规则。
## 排序与搜索
+2 -2
View File
@@ -6,8 +6,8 @@
| 配置项 | 默认值 | 说明 |
| --- | --- | --- |
| 卷王系统地址 | `https://exam.nxxy335.top` | 结尾不带 `/` |
| 接口前缀 | `/api` | 社区版 `/api`;企业版可能用 `/admin-api` |
| 卷王系统地址 | `https://exam.nxxy335.top` | 结尾不带 `/`,可直接在设置里修改 |
| 接口前缀 | `/api` | 社区版 `/api`;企业版可能用 `/admin-api`;可直接在设置里修改 |
| 登录账号 | `admin` | 卷王后台管理员账号 |
| 登录密码 | `123456` | 不回显;留空表示不修改 |
| 校验 HTTPS 证书 | 勾选 | 自签名证书取消勾选 |
-72
View File
@@ -1,72 +0,0 @@
# 快照、趋势与异常检测
这一组功能用于**跨时间**看成绩,而不是只看当前这一刻。
## 快照
工具栏 **存快照** 打开快照面板,填写标签(留空自动用「快照 MM-DD HH:II」)后保存。
一份快照包含:
- 保存时间与标签;
- 试卷 ID 与名称;
- 当时的整体统计(总人数、已提交、平均分、合格率……);
- 每名学生的 `学号 / 姓名 / 班级 / 组别 / 成绩 / 最高分 / 考试次数 / 最近提交时间`(按学号排序)。
存储位置:`data/snapshots/<projectId>/<unix秒>_<md5(标签)>.json`。
快照**按试卷分目录**,所以不同试卷的快照互不干扰。
| 操作 | 位置 |
| --- | --- |
| 保存当前快照 | 快照弹窗 → 保存当前快照 |
| 刷新列表 | 快照弹窗 → 刷新列表 |
| 删除某份 | 列表每行的删除按钮 |
## 趋势
**趋势** 面板把同一试卷的多份快照横向铺开,按学号对齐,可以直接看出每名学生
在几个时间点上的分数变化(上升 / 下降 / 缺考)。
典型用法:
1. 月考卷 A 考完 → 存快照「10月月考」;
2. 期中卷 B 考完 → 存快照「期中」;
3. 打开趋势,逐人对比两次成绩。
## 异常检测
工具栏 **异常** 打开异常线索面板。它**不是判定作弊**,只是把值得人工复核的对象挑出来,
避免在上千行数据里肉眼找。
### 短时长高分
命中条件:
```
有时长记录
且 时长 < max(60秒, 平均时长 × 40%)
且 成绩 ≥ 满分提示值 × 85%
```
> 「满分提示值」取当前数据中的最高分(`max_score`),至少为 1。
### 高频重考
命中条件:`考试次数 ≥ max(4, ceil(平均考试次数 + 3))`
即:至少 4 次才算高频,且要明显高于整体平均水平。
### 雷同成绩
同一分数出现 **≥ 3 人** 时列为疑似,按人数降序排列并列出成员。
::: warning 请人工复核
异常检测基于统计特征,误报很正常(例如题目全是选择题时同分很常见)。
请把它当作"值得看一眼"的线索,不要直接作为处理依据。
:::
## 相关
- [成绩明细与统计口径](./scores.md)
- [导出与打印](./export-print.md)
+1 -4
View File
@@ -32,9 +32,6 @@ features:
- icon: ⚙️
title: 每卷独立配置
details: 满分、合格率、免考名单按试卷隔离设置,互不干扰;未设置时回落到全局默认值。
- icon: 📈
title: 快照与趋势
details: 随时保存成绩快照,横向对比每名学生在多个时间点的成绩变化,并给出异常线索。
- icon: 🎲
title: 随机抽取
details: 按班级 / 组别均衡或加权抽取,累计去重、排除管理、历史批次与白名单导出。
@@ -52,7 +49,7 @@ features:
| 页面 | 入口 | 用途 |
| --- | --- | --- |
| 主系统 | `index.php` | 成绩明细、统计卡片、名单管理、快照 / 趋势 / 异常、导出与打印 |
| 主系统 | `index.php` | 成绩明细、统计卡片、名单管理、试卷设置、导出与打印 |
| 数据看板 | `dashboard.php` | 大屏展示,适合投屏实时监控提交进度 |
| 随机抽取 | `draw.php` | 从名单或某试卷已提交人员中随机抽取,支持白名单导出 |
+1 -2
View File
@@ -5,7 +5,7 @@
## P0:屏蔽数据目录(必做)
`data/` 位于 Web 根目录内,里面有 `ny.db`(配置 / 名单 / 卷王账号密码)、
`config.json`、`roster.json`、令牌缓存与快照。**必须禁止直接访问。**
`config.json`、`roster.json`、令牌缓存。**必须禁止直接访问。**
### nginx(生产环境默认,必做)
@@ -132,7 +132,6 @@ deny all;
| `data/ny.db` | 配置、名单、每卷配置(SQLite) |
| `data/config.json` | 配置(文件备份) |
| `data/roster.json` | 名单(文件备份) |
| `data/snapshots/` | 成绩快照 |
## P2:改掉卷王默认口令
+3 -3
View File
@@ -24,7 +24,7 @@
`X-CSRF-Token` 头中自动携带;
- 后端对写操作维护**白名单** `$WRITE_ACTIONS`,命中白名单的请求一律校验:
`config_save` / `roster_save` / `roster_import` / `roster_clear` /
`snapshot_save` / `snapshot_delete` / `unmatched_map` / `project_config_save`。
`unmatched_map` / `project_config_save`。
## 文件上传
@@ -58,7 +58,7 @@
## 目录保护
程序启动时会在 `data/`、`data/cache/`、`data/uploads/`、`data/snapshots/`
程序启动时会在 `data/`、`data/cache/`、`data/uploads/`
自动生成 `.htaccess`(`Deny from all`)与 `index.html` 占位。
> **nginx 不读取 `.htaccess`**,必须显式配置。见 [部署加固清单](./hardening.md)。
@@ -70,7 +70,7 @@
| 全站 HTTPS | 登录密码经 RSA 加密,但仍建议全站 TLS |
| IP 白名单 | 内网使用时在 nginx 层限制来源 IP |
| 隐藏版本号 | 关闭 `expose_php`、隐藏 nginx 版本号 |
| 定期备份 | 备份 `data/`(配置、名单、快照、SQLite 库) |
| 定期备份 | 备份 `data/`(配置、名单、每卷配置、SQLite 库) |
| 最小权限 | PHP-FPM 进程只对 `data/` 可写,其它目录只读 |
| 改默认密码 | 卷王后台默认 `admin/123456` 务必修改 |