ping(); } catch (Throwable $e) { // 卷王 token 已失效或配置错误 → 清会话 + 强制显示登录页(避免 login.php 把人踢回 index.php 形成死循环) // 把失败原因带出来,避免用户只看到登录框却不知道为什么被踢回来 $notice = '已退出之前的登录(' . $e->getMessage() . ')'; $_SESSION = []; @session_destroy(); } if (ny_is_auth()) { header('Location: index.php'); exit; } } $err = ''; $ok = false; if ($_SERVER['REQUEST_METHOD'] === 'POST') { $user = trim((string)($_POST['username'] ?? $cfg['username'])); $pwd = (string)($_POST['password'] ?? ''); // 允许用户在本页调整账号;密码必须输入 if ($user === '' || $pwd === '') { $err = '请输入账号与密码。'; } else { // 用当前配置的连接信息 + 本页输入的账密做一次卷王登录 $test = $cfg; $test['username'] = $user; $test['password'] = $pwd; try { $client = new SurveyKingClient($test); $client->getToken(true); // 登录成功:把账号与密码写回配置(本地单用户工具,持久化密码以便 token // 失效时平台能自动重新登录卷王,避免后台刷新陷入"未配置账号"的死状态) $cfg['username'] = $user; $cfg['password'] = $pwd; $saved = ny_save_config($cfg); // 关键:必须回读确认真的存住了。以前这里不看返回值,data 目录不可写时 // 会显示"登录成功",但下一个请求读到的账号仍是空的 → 无限跳回登录页。 $back = ny_load_config(); $persistOk = $saved && trim((string)($back['username'] ?? '')) === $user && (string)($back['password'] ?? '') === $pwd; if (!$persistOk) { $d = ny_config_diag(); $err = "登录卷王成功,但凭据没能保存到本机配置,继续进入会立刻又提示“未配置账号”。\n" . "请检查 data 目录写权限后重试:\n" . "· 配置来源:" . $d['storage'] . "(可写=" . ($d['cfg_writable'] ? '是' : '否') . ")\n" . "· 数据目录:" . $d['data_dir'] . "(可写=" . ($d['dir_writable'] ? '是' : '否') . ")\n" . "· 数据库:" . ($d['db_connected'] ? '已连接(可写=' . ($d['db_writable'] ? '是' : '否') . ')' : '未连接 ' . $d['db_error']) . "\n" . "· 保存错误:" . ($d['save_error'] !== '' ? $d['save_error'] : '(无)'); } elseif (!ny_session_usable($sessWhy)) { // 会话存不住时同样会"登录成功→立刻被踢回登录页",必须在这一步拦住 $err = "凭据已保存,但 PHP 会话不可用,登录状态无法保持:\n" . $sessWhy . "\n请在 php.ini 中把 session.save_path 指向一个可写目录后重试。"; } else { ny_login(); $ok = true; } } catch (Throwable $e) { $err = '登录失败:' . $e->getMessage(); } } } ?> 登录 · <?= htmlspecialchars(NY_APP_NAME) ?>
⚠️ 本机尚未保存卷王账号(配置来源:)。 如果每次登录成功都回到本页,多半是 data 目录不可写导致账号没存住—— 请让 data/ 目录()对 PHP 进程可写后重试。