feat: 接入PostgreSQL/MariaDB + 首次安装向导 + 登录页独立 + 设置重构 + 文件夹识别兜底
- 数据库层 lib/Db.php:统一 PDO 支持 pgsql/mysql/sqlite,连接参数存 data/db.json (git-ignored),migrate 建 ny_settings/ny_roster 表(三方言兼容 upsert) - 配置/名单读写:bootstrap ny_load_config/ny_save_config 与 Roster 均改为 '数据库可用则走 DB、否则回退 data/config.json/roster.json' 的文件降级模式 - 首次安装向导 install.php:选择存储后端(文件/PostgreSQL/MariaDB),测试连接+ 建表+写入卷王连接信息与默认满分;支持 ?force=1 重新配置 - 登录门分离:新增 login.php 独立登录页(仅需密码,账号预填)+logout.php+ 会话(ny_session_start/ny_is_auth/ny_login/ny_logout);index/dashboard 未安装 跳 install、未登录跳 login;api.php 加会话保护与 auth_check - 设置重构:删除卷王系统地址/接口前缀/登录账号/登录密码(连接信息由安装向导 配置);新增布局配置(默认/成绩明细与缺考名单同行)与各试卷独立满分列表(默认 分数作用于全部);工具栏布局下拉移除 - 文件夹识别兜底:app.js/dashboard.php 双策略 — mode 含 folder 优先,缺省时用 parent_id 引用反推(应对部分版本无 mode 字段);空文件夹自动隐藏 验证:php -l 全部通过、node --check app.js 通过;SQLite 等价实测 Db 层 (migrate/config upsert/Roster 读写/ny_load_config)与会话辅助函数全部PASS; e2e(内置服务器)验证路由:未装→install、装完→login、index/dashboard 未登录 跳转、api 401 保护、?force=1 重配、logout 302 均正确。本机无真实 pgsql/mysql 服务器,DB 连接按部署环境实测。
This commit is contained in:
+22
-2
@@ -13,9 +13,18 @@ class Roster
|
||||
return NY_DATA . '/roster.json';
|
||||
}
|
||||
|
||||
/** 数据库是否可作为名单后端 */
|
||||
private static function useDb(): bool
|
||||
{
|
||||
return class_exists('Db') && Db::pdo() !== null;
|
||||
}
|
||||
|
||||
/** @return array<int,array{sid:string,name:string,cls:string}> */
|
||||
public static function all(): array
|
||||
{
|
||||
if (self::useDb()) {
|
||||
return Db::rosterAll();
|
||||
}
|
||||
$d = ny_read_json(self::file(), null);
|
||||
if (!is_array($d) || !isset($d['students']) || !is_array($d['students'])) {
|
||||
return [];
|
||||
@@ -39,8 +48,8 @@ class Roster
|
||||
{
|
||||
$d = ny_read_json(self::file(), null);
|
||||
return [
|
||||
'count' => count(self::all()),
|
||||
'updated_at' => is_array($d) ? (string)($d['updated_at'] ?? '') : '',
|
||||
'count' => self::count(),
|
||||
'updated_at' => self::useDb() ? date('Y-m-d H:i:s') : (is_array($d) ? (string)($d['updated_at'] ?? '') : ''),
|
||||
];
|
||||
}
|
||||
|
||||
@@ -60,6 +69,10 @@ class Roster
|
||||
'grp' => trim((string)($s['grp'] ?? '')),
|
||||
];
|
||||
}
|
||||
if (self::useDb()) {
|
||||
Db::rosterReplace($clean);
|
||||
return true;
|
||||
}
|
||||
return ny_write_json(self::file(), [
|
||||
'students' => $clean,
|
||||
'updated_at' => date('Y-m-d H:i:s'),
|
||||
@@ -68,11 +81,18 @@ class Roster
|
||||
|
||||
public static function clear(): bool
|
||||
{
|
||||
if (self::useDb()) {
|
||||
Db::rosterReplace([]);
|
||||
return true;
|
||||
}
|
||||
return ny_write_json(self::file(), ['students' => [], 'updated_at' => date('Y-m-d H:i:s')]);
|
||||
}
|
||||
|
||||
public static function count(): int
|
||||
{
|
||||
if (self::useDb()) {
|
||||
return Db::rosterCount();
|
||||
}
|
||||
return count(self::all());
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user